@contrail/cli 2.0.19 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -25
- package/dist/api/types.d.ts +0 -2
- package/dist/api/types.js +1 -15
- package/dist/commands/app/create.js +2 -1
- package/dist/commands/app/getApiKey.js +3 -3
- package/dist/commands/app/publish.d.ts +2 -1
- package/dist/commands/app/publish.js +3 -2
- package/dist/commands/instance/import.js +0 -2
- package/dist/commands/types/getAll.d.ts +0 -4
- package/dist/commands/types/getAll.js +2 -77
- package/dist/commands/types/loadAll.js +0 -2
- package/dist/commands/types/mergeTypeProperties.js +0 -2
- package/dist/commands/types/uploadTypePropertyPolicies.js +8 -16
- package/dist/helpers/app/app-deployer.d.ts +3 -2
- package/dist/helpers/app/app-deployer.js +25 -5
- package/dist/templates/typescript/app.yml +0 -1
- package/dist/templates/typescript/package.json +5 -18
- package/dist/templates/typescript/src/actions/logItem.ts +20 -17
- package/dist/templates/typescript/src/main.ts +48 -0
- package/dist/templates/typescript/tsconfig.json +22 -13
- package/oclif.manifest.json +13 -28
- package/package.json +2 -2
- package/dist/commands/types/uploadTypePolicies.d.ts +0 -10
- package/dist/commands/types/uploadTypePolicies.js +0 -226
- package/dist/templates/typescript/Dockerfile +0 -15
- package/dist/templates/typescript/docker_deploy.bat +0 -1
- package/dist/templates/typescript/src/framework/action-dispatcher.ts +0 -93
- package/dist/templates/typescript/src/framework/app-config.ts +0 -24
- package/dist/templates/typescript/src/framework/handler.ts +0 -11
- package/dist/templates/typescript/src/framework/index.ts +0 -3
- package/dist/templates/typescript/src/framework/interfaces.ts +0 -32
- package/dist/templates/typescript/src/framework/logger.ts +0 -21
- package/dist/templates/typescript/src/framework/mock-server.ts +0 -31
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ $ npm install -g @contrail/cli
|
|
|
15
15
|
$ contrail COMMAND
|
|
16
16
|
running command...
|
|
17
17
|
$ contrail (--version)
|
|
18
|
-
@contrail/cli/2.
|
|
18
|
+
@contrail/cli/2.1.2 darwin-arm64 node-v18.13.0
|
|
19
19
|
$ contrail --help [COMMAND]
|
|
20
20
|
USAGE
|
|
21
21
|
$ contrail COMMAND
|
|
@@ -75,7 +75,6 @@ To get instructions on how to set up autocomplete for your shell, run `contrail
|
|
|
75
75
|
* [`contrail types uploadOptionSets`](#contrail-types-uploadoptionsets)
|
|
76
76
|
* [`contrail types uploadOptionSetsHierarchyLocalFile FILE NAME`](#contrail-types-uploadoptionsetshierarchylocalfile-file-name)
|
|
77
77
|
* [`contrail types uploadRuleSets`](#contrail-types-uploadrulesets)
|
|
78
|
-
* [`contrail types uploadTypePolicies`](#contrail-types-uploadtypepolicies)
|
|
79
78
|
* [`contrail types uploadTypePropertyPolicies`](#contrail-types-uploadtypepropertypolicies)
|
|
80
79
|
* [`contrail types uploadUsageInfo`](#contrail-types-uploadusageinfo)
|
|
81
80
|
* [`contrail users export`](#contrail-users-export)
|
|
@@ -122,10 +121,10 @@ Get an api key for an app
|
|
|
122
121
|
|
|
123
122
|
```
|
|
124
123
|
USAGE
|
|
125
|
-
$ contrail app getApiKey [
|
|
124
|
+
$ contrail app getApiKey [-a <value>]
|
|
126
125
|
|
|
127
126
|
FLAGS
|
|
128
|
-
--appIdentifier=<value> The app identifier
|
|
127
|
+
-a, --appIdentifier=<value> The app identifier
|
|
129
128
|
|
|
130
129
|
DESCRIPTION
|
|
131
130
|
Get an api key for an app
|
|
@@ -160,11 +159,12 @@ Publish the app
|
|
|
160
159
|
|
|
161
160
|
```
|
|
162
161
|
USAGE
|
|
163
|
-
$ contrail app publish [-u] [-d]
|
|
162
|
+
$ contrail app publish [-u] [-v] [-d]
|
|
164
163
|
|
|
165
164
|
FLAGS
|
|
166
|
-
-d, --
|
|
165
|
+
-d, --dryRun Dry run the upgrade without actually updating the app.
|
|
167
166
|
-u, --upgrade In addition to deploying, upgrade the installed version of the app in this org to the latest one.
|
|
167
|
+
-v, --verbose Debug the app deployment step and do not remove the intermediate build artifacts.
|
|
168
168
|
|
|
169
169
|
DESCRIPTION
|
|
170
170
|
Publish the app
|
|
@@ -1047,25 +1047,6 @@ EXAMPLES
|
|
|
1047
1047
|
$ contrail types uploadRuleSets
|
|
1048
1048
|
```
|
|
1049
1049
|
|
|
1050
|
-
## `contrail types uploadTypePolicies`
|
|
1051
|
-
|
|
1052
|
-
Upload type policies
|
|
1053
|
-
|
|
1054
|
-
```
|
|
1055
|
-
USAGE
|
|
1056
|
-
$ contrail types uploadTypePolicies [-d <value>]
|
|
1057
|
-
|
|
1058
|
-
FLAGS
|
|
1059
|
-
-d, --dir=<value> [default: .] The directory from which to export the type policy data. Defaults to the current
|
|
1060
|
-
directory. The type policy data will be loaded from $dir/type-policies/*.yml
|
|
1061
|
-
|
|
1062
|
-
DESCRIPTION
|
|
1063
|
-
Upload type policies
|
|
1064
|
-
|
|
1065
|
-
EXAMPLES
|
|
1066
|
-
$ contrail types UploadTypePolicies
|
|
1067
|
-
```
|
|
1068
|
-
|
|
1069
1050
|
## `contrail types uploadTypePropertyPolicies`
|
|
1070
1051
|
|
|
1071
1052
|
Upload type property policies
|
package/dist/api/types.d.ts
CHANGED
|
@@ -5,5 +5,3 @@ export declare function getRuleSetLinks(): Promise<any>;
|
|
|
5
5
|
export declare function getUsageInfo(): Promise<any>;
|
|
6
6
|
export declare function getTypePropertyPolicies(): Promise<any>;
|
|
7
7
|
export declare function getTypePropertyPolicyLinks(): Promise<any>;
|
|
8
|
-
export declare function getTypePolicies(): Promise<any>;
|
|
9
|
-
export declare function getTypePolicyLinks(): Promise<any>;
|
package/dist/api/types.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getTypePropertyPolicyLinks = exports.getTypePropertyPolicies = exports.getUsageInfo = exports.getRuleSetLinks = exports.getRuleSets = exports.getOptionSetHierarchies = exports.getOptionSets = void 0;
|
|
4
4
|
const sdk_1 = require("@contrail/sdk");
|
|
5
5
|
async function getOptionSets() {
|
|
6
6
|
return await new sdk_1.Entities().get({
|
|
@@ -50,17 +50,3 @@ async function getTypePropertyPolicyLinks() {
|
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
52
|
exports.getTypePropertyPolicyLinks = getTypePropertyPolicyLinks;
|
|
53
|
-
async function getTypePolicies() {
|
|
54
|
-
const entitiesClient = new sdk_1.Entities();
|
|
55
|
-
return await entitiesClient.get({
|
|
56
|
-
entityName: 'type-policy',
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
exports.getTypePolicies = getTypePolicies;
|
|
60
|
-
async function getTypePolicyLinks() {
|
|
61
|
-
const entitiesClient = new sdk_1.Entities();
|
|
62
|
-
return await entitiesClient.get({
|
|
63
|
-
entityName: 'type-policy-link',
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
exports.getTypePolicyLinks = getTypePolicyLinks;
|
|
@@ -49,7 +49,8 @@ class CreateApp extends core_1.Command {
|
|
|
49
49
|
publisher: answers.appPublisher,
|
|
50
50
|
public: false,
|
|
51
51
|
hidden: false,
|
|
52
|
-
description: answers.appDescription
|
|
52
|
+
description: answers.appDescription,
|
|
53
|
+
frameworkVersion: 2,
|
|
53
54
|
};
|
|
54
55
|
try {
|
|
55
56
|
await new sdk_1.Entities().create({ entityName: 'app', object: newApp });
|
|
@@ -22,7 +22,7 @@ class GetAPIKeyApp extends core_1.Command {
|
|
|
22
22
|
})
|
|
23
23
|
}];
|
|
24
24
|
const answers = await inquirer_1.default.prompt(questions);
|
|
25
|
-
console.log(`App API key:
|
|
25
|
+
console.log(`App API key: (app:${answers.appApiKey})`);
|
|
26
26
|
}
|
|
27
27
|
else {
|
|
28
28
|
const appFound = installedApps.find(x => x.app.identifier === flags.appIdentifier);
|
|
@@ -30,7 +30,7 @@ class GetAPIKeyApp extends core_1.Command {
|
|
|
30
30
|
console.log('You do not have such an app installed');
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
|
-
console.log(`App API key:
|
|
33
|
+
console.log(`App API key: (app:${appFound.apiKey.apiKey})`);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -41,5 +41,5 @@ GetAPIKeyApp.examples = [
|
|
|
41
41
|
`,
|
|
42
42
|
];
|
|
43
43
|
GetAPIKeyApp.flags = {
|
|
44
|
-
appIdentifier: core_1.Flags.string({ description: 'The app identifier', required: false })
|
|
44
|
+
appIdentifier: core_1.Flags.string({ char: 'a', description: 'The app identifier', required: false })
|
|
45
45
|
};
|
|
@@ -5,7 +5,8 @@ export default class PublishApp extends Command {
|
|
|
5
5
|
static strict: boolean;
|
|
6
6
|
static flags: {
|
|
7
7
|
upgrade: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
8
|
-
|
|
8
|
+
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
|
+
dryRun: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
10
|
};
|
|
10
11
|
run(): Promise<void>;
|
|
11
12
|
}
|
|
@@ -22,7 +22,7 @@ class PublishApp extends core_1.Command {
|
|
|
22
22
|
console.log(`%s Deploying Application. ${appDeclaration.appIdentifier}`, chalk_1.default.blue.bold('START'));
|
|
23
23
|
try {
|
|
24
24
|
await (0, login_1.authUser)();
|
|
25
|
-
const app = await new app_deployer_1.AppDeployer(flags.
|
|
25
|
+
const app = await new app_deployer_1.AppDeployer(flags.verbose, flags.dryRun).deploy(appDeclaration);
|
|
26
26
|
if (flags.upgrade) {
|
|
27
27
|
const installedApps = await (0, apps_1.getInstalledApps)();
|
|
28
28
|
const installedAppOrg = installedApps.find(x => x.appId === app.id);
|
|
@@ -51,5 +51,6 @@ PublishApp.examples = [
|
|
|
51
51
|
PublishApp.strict = true;
|
|
52
52
|
PublishApp.flags = {
|
|
53
53
|
upgrade: core_1.Flags.boolean({ char: 'u', description: 'In addition to deploying, upgrade the installed version of the app in this org to the latest one.', required: false }),
|
|
54
|
-
|
|
54
|
+
verbose: core_1.Flags.boolean({ char: 'v', description: 'Debug the app deployment step and do not remove the intermediate build artifacts.', required: false }),
|
|
55
|
+
dryRun: core_1.Flags.boolean({ char: 'd', description: 'Dry run the upgrade without actually updating the app.', required: false }),
|
|
55
56
|
};
|
|
@@ -7,7 +7,6 @@ const loadAll_1 = require("../types/loadAll");
|
|
|
7
7
|
const upload_1 = require("../users/upload");
|
|
8
8
|
const upload_2 = require("../groups/upload");
|
|
9
9
|
const uploadTypePropertyPolicies_1 = require("../types/uploadTypePropertyPolicies");
|
|
10
|
-
const uploadTypePolicies_1 = require("../types/uploadTypePolicies");
|
|
11
10
|
class ImportInstance extends core_1.Command {
|
|
12
11
|
async run() {
|
|
13
12
|
const { flags } = await this.parse(ImportInstance);
|
|
@@ -15,7 +14,6 @@ class ImportInstance extends core_1.Command {
|
|
|
15
14
|
await (0, upload_1.uploadUsers)(path.join(flags.dir, 'users.yml'));
|
|
16
15
|
await (0, upload_2.uploadGroups)(path.join(flags.dir, 'groups.yml'));
|
|
17
16
|
await (0, uploadTypePropertyPolicies_1.uploadTypePropertyPolicies)(flags.dir);
|
|
18
|
-
await (0, uploadTypePolicies_1.uploadTypePolicies)(flags.dir);
|
|
19
17
|
}
|
|
20
18
|
}
|
|
21
19
|
exports.default = ImportInstance;
|
|
@@ -8,8 +8,6 @@ export interface DataHolder {
|
|
|
8
8
|
usageInfo: any[];
|
|
9
9
|
typePropertyPolicies: any[];
|
|
10
10
|
typePropertyPolicyLinks: any[];
|
|
11
|
-
typePolicies: any[];
|
|
12
|
-
typePolicyLinks: any[];
|
|
13
11
|
}
|
|
14
12
|
export interface ReducedDataHolder {
|
|
15
13
|
reducedTypes: any[];
|
|
@@ -20,8 +18,6 @@ export interface ReducedDataHolder {
|
|
|
20
18
|
reducedUsageInfo: any[];
|
|
21
19
|
reducedTypePropertyPolicies: any[];
|
|
22
20
|
reducedTypePropertyPolicyLinks: any[];
|
|
23
|
-
reducedTypePolicies: any[];
|
|
24
|
-
reducedTypePolicyLinks: any[];
|
|
25
21
|
}
|
|
26
22
|
export default class GetAllTypes extends Command {
|
|
27
23
|
static description: string;
|
|
@@ -45,8 +45,6 @@ async function getAll(outDir, overwrite) {
|
|
|
45
45
|
usageInfo: await (0, types_1.getUsageInfo)(),
|
|
46
46
|
typePropertyPolicies: await (0, types_1.getTypePropertyPolicies)(),
|
|
47
47
|
typePropertyPolicyLinks: await (0, types_1.getTypePropertyPolicyLinks)(),
|
|
48
|
-
typePolicies: await (0, types_1.getTypePolicies)(),
|
|
49
|
-
typePolicyLinks: await (0, types_1.getTypePolicyLinks)(),
|
|
50
48
|
};
|
|
51
49
|
const reducedData = await reduceData(data);
|
|
52
50
|
await saveData(reducedData, outDir, overwrite);
|
|
@@ -103,80 +101,11 @@ async function reduceTypePropertyPolicies(data) {
|
|
|
103
101
|
function reduceTypePropertyPolicyLinks(data) {
|
|
104
102
|
var _a, _b;
|
|
105
103
|
const typeProperties = (_a = data === null || data === void 0 ? void 0 : data.types) === null || _a === void 0 ? void 0 : _a.map(x => x.typeProperties).reduce((x, y) => x.concat(y));
|
|
106
|
-
// make a map of all type properties to their type ids
|
|
107
|
-
const typePropertyIdToTypeSlugMap = data.types.reduce((map, obj) => {
|
|
108
|
-
for (const tp of obj.typeProperties) {
|
|
109
|
-
map[tp.id] = obj.slug;
|
|
110
|
-
}
|
|
111
|
-
return map;
|
|
112
|
-
}, {});
|
|
113
104
|
return (_b = data === null || data === void 0 ? void 0 : data.typePropertyPolicyLinks) === null || _b === void 0 ? void 0 : _b.map(x => {
|
|
114
|
-
var _a, _b;
|
|
115
|
-
const typeSlug = typePropertyIdToTypeSlugMap[x.typePropertyId];
|
|
116
|
-
const typePropertySlug = (_a = typeProperties.find(y => y.id === x.typePropertyId)) === null || _a === void 0 ? void 0 : _a.slug;
|
|
117
|
-
const typePropertyPolicyLabel = (_b = data.typePropertyPolicies.find(y => y.id === x.typePropertyPolicyId)) === null || _b === void 0 ? void 0 : _b.label;
|
|
118
|
-
if (!typeSlug ||
|
|
119
|
-
!typePropertySlug ||
|
|
120
|
-
!typePropertyPolicyLabel) {
|
|
121
|
-
console.warn('Could not reduce bad type property policy link... skipping', x);
|
|
122
|
-
return null;
|
|
123
|
-
}
|
|
124
|
-
return {
|
|
125
|
-
typeSlug,
|
|
126
|
-
typePropertySlug,
|
|
127
|
-
typePropertyPolicyLabel,
|
|
128
|
-
};
|
|
129
|
-
}).filter(x => !!x);
|
|
130
|
-
}
|
|
131
|
-
async function reduceTypePolicies(data) {
|
|
132
|
-
var _a;
|
|
133
|
-
const orgUsers = await (0, users_1.getUserOrgs)();
|
|
134
|
-
const groups = await (0, users_1.getGroups)();
|
|
135
|
-
function reducePrincipal(statement) {
|
|
136
|
-
var _a, _b;
|
|
137
|
-
if (!(statement === null || statement === void 0 ? void 0 : statement.principal)) {
|
|
138
|
-
return statement;
|
|
139
|
-
}
|
|
140
|
-
const [type, id] = statement.principal.split(':');
|
|
141
|
-
if (!type || !id) {
|
|
142
|
-
return statement;
|
|
143
|
-
}
|
|
144
|
-
if (type === 'group') {
|
|
145
|
-
const groupName = (_a = groups.find(x => x.id === id)) === null || _a === void 0 ? void 0 : _a.name;
|
|
146
|
-
if (!groupName) {
|
|
147
|
-
console.log(`Could not find group for statement. skipping invalid policy conversion ${id}`);
|
|
148
|
-
return statement;
|
|
149
|
-
}
|
|
150
|
-
statement.principal = `group:${groupName}`;
|
|
151
|
-
}
|
|
152
|
-
else if (type === 'user') {
|
|
153
|
-
const userEmail = (_b = orgUsers.find(x => x.user.id === id)) === null || _b === void 0 ? void 0 : _b.email;
|
|
154
|
-
if (!userEmail) {
|
|
155
|
-
console.log(`Could not find group for statement. skipping invalid policy conversion ${id}`);
|
|
156
|
-
return statement;
|
|
157
|
-
}
|
|
158
|
-
statement.principal = `user:${userEmail}`;
|
|
159
|
-
}
|
|
160
|
-
return statement;
|
|
161
|
-
}
|
|
162
|
-
return (_a = data === null || data === void 0 ? void 0 : data.typePolicies) === null || _a === void 0 ? void 0 : _a.map(x => {
|
|
163
|
-
return {
|
|
164
|
-
label: x.label,
|
|
165
|
-
policy: {
|
|
166
|
-
version: x.policy.version,
|
|
167
|
-
statements: x.policy.statements.map(x => reducePrincipal(x)),
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
function reduceTypePolicyLinks(data) {
|
|
173
|
-
var _a;
|
|
174
|
-
const types = data === null || data === void 0 ? void 0 : data.types;
|
|
175
|
-
return (_a = data === null || data === void 0 ? void 0 : data.typePolicyLinks) === null || _a === void 0 ? void 0 : _a.map(x => {
|
|
176
105
|
var _a, _b;
|
|
177
106
|
return {
|
|
178
|
-
|
|
179
|
-
|
|
107
|
+
typePropertySlug: (_a = typeProperties.find(y => y.id === x.typePropertyId)) === null || _a === void 0 ? void 0 : _a.slug,
|
|
108
|
+
typePropertyPolicyLabel: (_b = data.typePropertyPolicies.find(y => y.id === x.typePropertyPolicyId)) === null || _b === void 0 ? void 0 : _b.label,
|
|
180
109
|
};
|
|
181
110
|
});
|
|
182
111
|
}
|
|
@@ -306,8 +235,6 @@ async function reduceData(data) {
|
|
|
306
235
|
reducedUsageInfo: reduceUsageInfo(data),
|
|
307
236
|
reducedTypePropertyPolicies: await reduceTypePropertyPolicies(data),
|
|
308
237
|
reducedTypePropertyPolicyLinks: reduceTypePropertyPolicyLinks(data),
|
|
309
|
-
reducedTypePolicies: await reduceTypePolicies(data),
|
|
310
|
-
reducedTypePolicyLinks: reduceTypePolicyLinks(data),
|
|
311
238
|
};
|
|
312
239
|
}
|
|
313
240
|
exports.reduceData = reduceData;
|
|
@@ -354,8 +281,6 @@ async function saveData(reducedData, dir, overwrite) {
|
|
|
354
281
|
reducedUsageInfo: { filename: 'usage-info', split: false, fileLabel: '' },
|
|
355
282
|
reducedTypePropertyPolicies: { filename: 'type-property-policies', split: true, fileLabel: 'label' },
|
|
356
283
|
reducedTypePropertyPolicyLinks: { filename: 'type-property-policy-links', split: false, fileLabel: '' },
|
|
357
|
-
reducedTypePolicies: { filename: 'type-policies', split: true, fileLabel: 'label' },
|
|
358
|
-
reducedTypePolicyLinks: { filename: 'type-policy-links', split: false, fileLabel: '' },
|
|
359
284
|
};
|
|
360
285
|
for (const [key, folder] of Object.entries(propertyToFolderMap)) {
|
|
361
286
|
const CURRENT_DIR = process.cwd();
|
|
@@ -11,7 +11,6 @@ const uploadUsageInfo_1 = require("./uploadUsageInfo");
|
|
|
11
11
|
const uploadRuleSets_1 = require("./uploadRuleSets");
|
|
12
12
|
const uploadTypePropertyPolicies_1 = require("./uploadTypePropertyPolicies");
|
|
13
13
|
const type_uploader_1 = require("../../helpers/types/type-uploader");
|
|
14
|
-
const uploadTypePolicies_1 = require("./uploadTypePolicies");
|
|
15
14
|
class LoadAllTypes extends core_1.Command {
|
|
16
15
|
async run() {
|
|
17
16
|
const { flags } = await this.parse(LoadAllTypes);
|
|
@@ -37,7 +36,6 @@ async function loadAll(dir, skipPolicies = false) {
|
|
|
37
36
|
await (0, uploadRuleSets_1.uploadRuleSets)(dir);
|
|
38
37
|
if (!skipPolicies) {
|
|
39
38
|
await (0, uploadTypePropertyPolicies_1.uploadTypePropertyPolicies)(dir);
|
|
40
|
-
await (0, uploadTypePolicies_1.uploadTypePolicies)(dir);
|
|
41
39
|
}
|
|
42
40
|
}
|
|
43
41
|
catch (e) {
|
|
@@ -63,8 +63,6 @@ async function mergeTypeProperties(fileLocation, typePaths) {
|
|
|
63
63
|
usageInfo: [],
|
|
64
64
|
typePropertyPolicies: [],
|
|
65
65
|
typePropertyPolicyLinks: [],
|
|
66
|
-
typePolicies: [],
|
|
67
|
-
typePolicyLinks: [],
|
|
68
66
|
};
|
|
69
67
|
const reducedData = await (0, getAll_1.reduceData)(data);
|
|
70
68
|
for (const typePath of typePaths) {
|
|
@@ -37,8 +37,6 @@ async function uploadTypePropertyPolicies(dir) {
|
|
|
37
37
|
}
|
|
38
38
|
catch (e) {
|
|
39
39
|
console.log(`%s Type Property Policy Upload Failed. ${e}`, chalk_1.default.red.bold('FAIL'));
|
|
40
|
-
//TODO make this only print if a debug flag is set
|
|
41
|
-
console.trace(e);
|
|
42
40
|
return;
|
|
43
41
|
}
|
|
44
42
|
console.log('%s Type Property Policy Upload Complete.', chalk_1.default.green.bold('COMPLETE'));
|
|
@@ -149,16 +147,10 @@ async function uploadTPPolicyObjects(reducedTypePropertyPolicies) {
|
|
|
149
147
|
}
|
|
150
148
|
async function uploadTypePropertyPolicyLinks(reducedTypePropertyPolicyLinks) {
|
|
151
149
|
const typesWithProperties = await (0, type_extractor_1.getTypes)();
|
|
152
|
-
const typeProperties =
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
tp.typeId = type.id;
|
|
157
|
-
tp.typeSlug = type.slug;
|
|
158
|
-
typeProperties.push(tp);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
});
|
|
150
|
+
const typeProperties = typesWithProperties
|
|
151
|
+
.filter(t => !!t.typeProperties)
|
|
152
|
+
.map(t => t.typeProperties)
|
|
153
|
+
.reduce((a, b) => a.concat(b));
|
|
162
154
|
const currentTPPs = await new sdk_1.Entities().get({
|
|
163
155
|
entityName: 'type-property-policy',
|
|
164
156
|
});
|
|
@@ -172,17 +164,17 @@ async function uploadTypePropertyPolicyLinks(reducedTypePropertyPolicyLinks) {
|
|
|
172
164
|
if (!foundTypeProperty || !foundTPP) {
|
|
173
165
|
console.log('skipping unhashable, invalid policy link:', currentLink);
|
|
174
166
|
}
|
|
175
|
-
const hash = `${foundTypeProperty.
|
|
167
|
+
const hash = `${foundTypeProperty.slug}|${foundTPP.label}`;
|
|
176
168
|
currentLinksHashes[hash] = currentLink;
|
|
177
169
|
}
|
|
178
170
|
const reducedLinksByHashes = {};
|
|
179
171
|
for (const loadedLink of reducedTypePropertyPolicyLinks) {
|
|
180
|
-
const hash = `${loadedLink.
|
|
172
|
+
const hash = `${loadedLink.typePropertySlug}|${loadedLink.typePropertyPolicyLabel}`;
|
|
181
173
|
reducedLinksByHashes[hash] = loadedLink;
|
|
182
174
|
}
|
|
183
175
|
for (const loadedTPPLink of reducedTypePropertyPolicyLinks) {
|
|
184
176
|
try {
|
|
185
|
-
const found = currentLinksHashes[`${loadedTPPLink.
|
|
177
|
+
const found = currentLinksHashes[`${loadedTPPLink.typePropertySlug}|${loadedTPPLink.typePropertyPolicyLabel}`];
|
|
186
178
|
if (!found) {
|
|
187
179
|
if (!transformReducedLink(loadedTPPLink, typeProperties, currentTPPs)) {
|
|
188
180
|
continue;
|
|
@@ -222,7 +214,7 @@ async function uploadTypePropertyPolicyLinks(reducedTypePropertyPolicyLinks) {
|
|
|
222
214
|
}
|
|
223
215
|
}
|
|
224
216
|
function transformReducedLink(TPPLink, typeProperties, typePropertyPolicies) {
|
|
225
|
-
const foundTP = typeProperties.find(tp => tp.slug === TPPLink.typePropertySlug
|
|
217
|
+
const foundTP = typeProperties.find(tp => tp.slug === TPPLink.typePropertySlug);
|
|
226
218
|
if (!foundTP) {
|
|
227
219
|
console.error('Could not find type property with label', TPPLink.typePropertySlug);
|
|
228
220
|
return false;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { App, AppCodePackage, AppDeclaration } from '../../interfaces';
|
|
2
2
|
export declare class AppDeployer {
|
|
3
3
|
private debug;
|
|
4
|
-
|
|
4
|
+
private dryRun;
|
|
5
|
+
constructor(debug?: boolean, dryRun?: boolean);
|
|
5
6
|
deploy(appDeclaration: AppDeclaration): Promise<App>;
|
|
6
7
|
getExistingApp(appDeclaration: AppDeclaration): Promise<App>;
|
|
7
8
|
private createNewApp;
|
|
8
9
|
updateExistingApp(appDeclaration: AppDeclaration, existingApp: any): Promise<any>;
|
|
9
10
|
remove(appDeclaration: AppDeclaration): Promise<void>;
|
|
10
11
|
}
|
|
11
|
-
export declare function createNodePackage(appIdentifier: string, debug: boolean): Promise<AppCodePackage>;
|
|
12
|
+
export declare function createNodePackage(appIdentifier: string, debug: boolean, dryRun: boolean): Promise<AppCodePackage>;
|
|
@@ -14,8 +14,9 @@ const axios_1 = tslib_1.__importDefault(require("axios"));
|
|
|
14
14
|
const child_process = require('child_process');
|
|
15
15
|
const fs = require('fs');
|
|
16
16
|
class AppDeployer {
|
|
17
|
-
constructor(debug = false) {
|
|
17
|
+
constructor(debug = false, dryRun = false) {
|
|
18
18
|
this.debug = debug;
|
|
19
|
+
this.dryRun = dryRun;
|
|
19
20
|
//pass
|
|
20
21
|
}
|
|
21
22
|
async deploy(appDeclaration) {
|
|
@@ -28,6 +29,10 @@ class AppDeployer {
|
|
|
28
29
|
console.log('%s Updating existing app.', chalk_1.default.yellow.bold('APP'));
|
|
29
30
|
app = await this.updateExistingApp(appDeclaration, app);
|
|
30
31
|
}
|
|
32
|
+
if (this.dryRun) {
|
|
33
|
+
console.log('Dry run, skipping action and workflow template definition deployment.');
|
|
34
|
+
return {};
|
|
35
|
+
}
|
|
31
36
|
await new actions_deployer_1.ActionsDeployer().deployActions(appDeclaration, app);
|
|
32
37
|
await new workflow_template_definition_deployer_1.WorkflowTemplateDefinitionDeployer().deployWorkflowTemplateDefinitions(appDeclaration, app);
|
|
33
38
|
return app;
|
|
@@ -51,7 +56,7 @@ class AppDeployer {
|
|
|
51
56
|
const isDocker = Object.hasOwnProperty.call(appDeclaration, 'dockerImageRef');
|
|
52
57
|
let appCodePackageId;
|
|
53
58
|
if (!isDocker) { // this is the expected default behavior
|
|
54
|
-
const appCodePackage = await createNodePackage(appDeclaration.appIdentifier, this.debug);
|
|
59
|
+
const appCodePackage = await createNodePackage(appDeclaration.appIdentifier, this.debug, this.dryRun);
|
|
55
60
|
appCodePackageId = appCodePackage.id;
|
|
56
61
|
}
|
|
57
62
|
const newApp = {
|
|
@@ -68,7 +73,12 @@ class AppDeployer {
|
|
|
68
73
|
triggerKeyDefinitions,
|
|
69
74
|
dockerImageRef: (_a = appDeclaration.dockerImageRef) !== null && _a !== void 0 ? _a : null,
|
|
70
75
|
appCodePackageId: appCodePackageId !== null && appCodePackageId !== void 0 ? appCodePackageId : null,
|
|
76
|
+
frameworkVersion: 2,
|
|
71
77
|
};
|
|
78
|
+
if (this.dryRun) {
|
|
79
|
+
console.log('Dry run, not creating app');
|
|
80
|
+
return {};
|
|
81
|
+
}
|
|
72
82
|
const app = await new sdk_1.Entities().create({ entityName: 'app', object: newApp });
|
|
73
83
|
console.log(`%s Created new app: ${app.name}`, chalk_1.default.yellow.bold('APP'));
|
|
74
84
|
return app;
|
|
@@ -87,7 +97,7 @@ class AppDeployer {
|
|
|
87
97
|
const isDocker = Object.hasOwnProperty.call(appDeclaration, 'dockerImageRef');
|
|
88
98
|
let appCodePackageId;
|
|
89
99
|
if (!isDocker) { // this is the expected default behavior
|
|
90
|
-
const appCodePackage = await createNodePackage(appDeclaration.appIdentifier, this.debug);
|
|
100
|
+
const appCodePackage = await createNodePackage(appDeclaration.appIdentifier, this.debug, this.dryRun);
|
|
91
101
|
appCodePackageId = appCodePackage.id;
|
|
92
102
|
}
|
|
93
103
|
const updates = {
|
|
@@ -103,7 +113,12 @@ class AppDeployer {
|
|
|
103
113
|
triggerKeyDefinitions,
|
|
104
114
|
dockerImageRef: (_a = appDeclaration.dockerImageRef) !== null && _a !== void 0 ? _a : null,
|
|
105
115
|
appCodePackageId: appCodePackageId !== null && appCodePackageId !== void 0 ? appCodePackageId : null,
|
|
116
|
+
frameworkVersion: 2,
|
|
106
117
|
};
|
|
118
|
+
if (this.dryRun) {
|
|
119
|
+
console.log('Dry run, not creating app');
|
|
120
|
+
return {};
|
|
121
|
+
}
|
|
107
122
|
const app = await new sdk_1.Entities().update({ entityName: 'app', id: existingApp.id, object: updates });
|
|
108
123
|
console.log(`%s Updated app: ${app.name}`, chalk_1.default.yellow.bold('APP'));
|
|
109
124
|
return app;
|
|
@@ -125,7 +140,7 @@ class AppDeployer {
|
|
|
125
140
|
}
|
|
126
141
|
}
|
|
127
142
|
exports.AppDeployer = AppDeployer;
|
|
128
|
-
async function createNodePackage(appIdentifier, debug) {
|
|
143
|
+
async function createNodePackage(appIdentifier, debug, dryRun) {
|
|
129
144
|
// zip src code and package.json and package-lock.json files into a zip file
|
|
130
145
|
// and upload as a code package.
|
|
131
146
|
const entitiesClient = new sdk_1.Entities();
|
|
@@ -133,7 +148,6 @@ async function createNodePackage(appIdentifier, debug) {
|
|
|
133
148
|
// clear and make temp directory
|
|
134
149
|
fs.rmSync('tmp/', { recursive: true, force: true });
|
|
135
150
|
fs.cpSync('package.json', 'tmp/package.json');
|
|
136
|
-
fs.cpSync('app.yml', 'tmp/app.yml');
|
|
137
151
|
//copy package-lock.json if it exists
|
|
138
152
|
if (fs.existsSync('package-lock.json')) {
|
|
139
153
|
fs.cpSync('package-lock.json', 'tmp/package-lock.json');
|
|
@@ -145,9 +159,15 @@ async function createNodePackage(appIdentifier, debug) {
|
|
|
145
159
|
console.log('Building package...');
|
|
146
160
|
child_process.execSync('npx tsc --outDir tmp/dist');
|
|
147
161
|
console.log('Building package done.');
|
|
162
|
+
// including the app.yml file in the package at the dist level
|
|
163
|
+
fs.cpSync('app.yml', 'tmp/dist/app.yml');
|
|
148
164
|
console.log('Zipping package...');
|
|
149
165
|
await (0, zip_a_folder_1.zip)('tmp/', 'tmp.zip');
|
|
150
166
|
console.log('Zipping package done.');
|
|
167
|
+
if (dryRun) {
|
|
168
|
+
console.log('Dry run, skipping cloud updates');
|
|
169
|
+
return {};
|
|
170
|
+
}
|
|
151
171
|
console.log('Uploading package to S3...');
|
|
152
172
|
let apps = await entitiesClient.get({ entityName: 'app', criteria: { hidden: true } });
|
|
153
173
|
apps = apps.concat(await entitiesClient.get({ entityName: 'app', criteria: { private: true } }));
|
|
@@ -5,7 +5,6 @@ visibility: private # This should be private unless you want to develop an app
|
|
|
5
5
|
hidden: false # can be used with a public app to prevent it from showing on the marketplace, but still installable by other orgs
|
|
6
6
|
publisher: "Your company name" # Your company name, used for public apps
|
|
7
7
|
version: 1.0
|
|
8
|
-
# dockerImageRef: CHANGE_ME # Deprecated. For VibeIQ Deployment... for use by VibeIQ employees only
|
|
9
8
|
|
|
10
9
|
# Properties you can configure when you install the app.
|
|
11
10
|
# These property values will be available to all of your actions when they run
|
|
@@ -7,36 +7,22 @@
|
|
|
7
7
|
"@contrail/contrail-cli": "bin/init",
|
|
8
8
|
"contrail": "bin/init"
|
|
9
9
|
},
|
|
10
|
-
"config": {
|
|
11
|
-
"wf": "/workflow-actions-prod"
|
|
12
|
-
},
|
|
13
10
|
"publishConfig": {
|
|
14
11
|
"access": "public"
|
|
15
12
|
},
|
|
16
13
|
"scripts": {
|
|
17
14
|
"build": "tsc",
|
|
18
|
-
"start": "nodemon --watch \"src/**/*.ts\" --exec ts-node src/
|
|
19
|
-
"debug": "nodemon -r ts-node/register --inspect=127.0.0.1:60002 --watch 'actions/**/*.ts' --exec node src/
|
|
15
|
+
"start": "nodemon --watch \"src/**/*.ts\" --exec ts-node src/main.ts",
|
|
16
|
+
"debug": "nodemon -r ts-node/register --inspect=127.0.0.1:60002 --watch 'actions/**/*.ts' --exec node src/main.ts",
|
|
20
17
|
"lint": "eslint . --fix",
|
|
21
18
|
"test": "jest",
|
|
22
|
-
"test-watch": "jest --watch"
|
|
23
|
-
"docker-build": "docker build . -t \"${npm_package_name}:${npm_package_version}\" --platform=linux/amd64",
|
|
24
|
-
"docker-build:win": "docker build . -t \"%npm_package_name%:%npm_package_version%\" --platform=linux/amd64",
|
|
25
|
-
"docker-run-entry": "docker run -it --entrypoint=/bin/bash \"${npm_package_name}:${npm_package_version}\"",
|
|
26
|
-
"docker-run-entry:win": "docker run -it --entrypoint=/bin/bash \"%npm_package_name%:%npm_package_version%\"",
|
|
27
|
-
"docker-run": "docker run --env CONTRAIL_CLI_ENV=DEV -p 9000:8080 \"${npm_package_name}:${npm_package_version}\"",
|
|
28
|
-
"docker-run:win": "docker run --env CONTRAIL_CLI_ENV=DEV -p 9000:8080 \"%npm_package_name%:%npm_package_version%\"",
|
|
29
|
-
"docker-ecr-login": "aws ecr get-login-password | docker login --username AWS --password-stdin ${AWS_REGISTRY}",
|
|
30
|
-
"docker-ecr-login:win": "aws ecr get-login-password | docker login --username AWS --password-stdin %AWS_REGISTRY%",
|
|
31
|
-
"docker-tag": "docker tag ${npm_package_name}:${npm_package_version} \"${AWS_REGISTRY}${npm_package_config_wf}:${npm_package_name}.${npm_package_version}\"",
|
|
32
|
-
"docker-tag:win": "docker tag %npm_package_name%:%npm_package_version% %AWS_REGISTRY%%npm_package_config_wf%:%npm_package_name%.%npm_package_version%",
|
|
33
|
-
"docker-push": "docker push \"${AWS_REGISTRY}${npm_package_config_wf}:${npm_package_name}.${npm_package_version}\"",
|
|
34
|
-
"docker-push:win": "docker push \"%AWS_REGISTRY%%npm_package_config_wf%:%npm_package_name%.%npm_package_version%\""
|
|
19
|
+
"test-watch": "jest --watch"
|
|
35
20
|
},
|
|
36
21
|
"keywords": [],
|
|
37
22
|
"author": "",
|
|
38
23
|
"license": "ISC",
|
|
39
24
|
"dependencies": {
|
|
25
|
+
"@contrail/app-framework": "^1.0.9",
|
|
40
26
|
"@contrail/sdk": "^1.1.54",
|
|
41
27
|
"chalk": "^4.0.0",
|
|
42
28
|
"js-yaml": "^4.1.0"
|
|
@@ -44,6 +30,7 @@
|
|
|
44
30
|
"devDependencies": {
|
|
45
31
|
"@types/node": "^18.14.6",
|
|
46
32
|
"body-parser": "^1.20.2",
|
|
33
|
+
"copyfiles": "^2.4.1",
|
|
47
34
|
"express": "^4.18.2",
|
|
48
35
|
"jest": "^29.2.2",
|
|
49
36
|
"nodemon": "^1.19.4",
|
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
import { Entities } from
|
|
2
|
-
import { AppActionCallBack, AppActionCallbackStatus } from
|
|
3
|
-
import { Logger } from "../framework/logger";
|
|
1
|
+
import { Entities } from '@contrail/sdk';
|
|
2
|
+
import { Action, AppAction, AppActionCallBack, AppActionCallbackStatus, Logger } from '@contrail/app-framework';
|
|
4
3
|
|
|
5
|
-
export
|
|
6
|
-
logger.log('Starting Example Action');
|
|
7
|
-
logger.log('Getting item from SDK');
|
|
4
|
+
export class LogItemAction implements AppAction {
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
logger.log('Got item: ', item);
|
|
6
|
+
@Action('logItem')
|
|
7
|
+
public async execute(event, config: any, logger: Logger): Promise<AppActionCallBack> {
|
|
8
|
+
logger.log('Starting Example Action');
|
|
9
|
+
logger.log('Getting item from SDK');
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
const item = await new Entities().get({
|
|
12
|
+
entityName: 'item',
|
|
13
|
+
id: event.id,
|
|
14
|
+
});
|
|
15
|
+
logger.log('Got item: ', item);
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
output: {
|
|
19
|
+
item,
|
|
20
|
+
},
|
|
21
|
+
status: AppActionCallbackStatus.SUCCESS
|
|
22
|
+
};
|
|
23
|
+
}
|
|
21
24
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ContrailAppModule, loadAppConfig, registerAppInfo, runMockServer, AppActionRequest, AppActionResponse, ActionDispatcher, GLOBAL_ACTION_REGISTRY } from '@contrail/app-framework';
|
|
2
|
+
|
|
3
|
+
// we can't use static import here. Require only
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
const pJson = require('../package.json');
|
|
7
|
+
|
|
8
|
+
const APP_YML_LOCATION = path.resolve(path.join(__dirname, '..', 'app.yml'));
|
|
9
|
+
export class AppModule extends ContrailAppModule {
|
|
10
|
+
|
|
11
|
+
initModule() {
|
|
12
|
+
// register the app info
|
|
13
|
+
const appConfig = loadAppConfig(APP_YML_LOCATION);
|
|
14
|
+
registerAppInfo({
|
|
15
|
+
appName: appConfig.appIdentifier, //appName is required
|
|
16
|
+
packageVersion: pJson.version
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// register app's actions
|
|
20
|
+
for (const file of fs.readdirSync(path.join(__dirname, 'actions'))) {
|
|
21
|
+
// only parse js and ts file, avoid property files
|
|
22
|
+
if (
|
|
23
|
+
file.endsWith('.js') ||
|
|
24
|
+
(file.endsWith('.ts') && !file.endsWith('.d.ts'))
|
|
25
|
+
) {
|
|
26
|
+
require(path.join(__dirname, 'actions', file));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
console.log(`Registered ${Object.keys(GLOBAL_ACTION_REGISTRY).length} action(s):`);
|
|
31
|
+
for(const key of Object.keys(GLOBAL_ACTION_REGISTRY)) {
|
|
32
|
+
console.log(`\t- ${appConfig.appIdentifier}:${key}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// If the module is being run directly, run the mock server
|
|
38
|
+
// https://nodejs.org/api/modules.html#accessing-the-main-module
|
|
39
|
+
if (require.main === module) {
|
|
40
|
+
runMockServer(new AppModule(), null);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// special handler for Lambda
|
|
44
|
+
export async function handle(data: AppActionRequest): Promise<AppActionResponse> {
|
|
45
|
+
// start the module
|
|
46
|
+
new AppModule().initModule();
|
|
47
|
+
return ActionDispatcher.dispatchActionRequest(data);
|
|
48
|
+
}
|
|
@@ -1,17 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"module": "commonjs",
|
|
5
3
|
"declaration": true,
|
|
4
|
+
"emitDecoratorMetadata": true,
|
|
6
5
|
"esModuleInterop": true,
|
|
7
|
-
"outDir": "dist",
|
|
8
|
-
"strict": false,
|
|
9
6
|
"experimentalDecorators": true,
|
|
10
|
-
"strictPropertyInitialization": false,
|
|
11
|
-
"noImplicitAny": false,
|
|
12
|
-
"emitDecoratorMetadata": true,
|
|
13
|
-
"skipLibCheck": true,
|
|
14
|
-
"moduleResolution": "node",
|
|
15
7
|
"lib": [
|
|
16
8
|
"es5",
|
|
17
9
|
"ES2015",
|
|
@@ -21,8 +13,25 @@
|
|
|
21
13
|
"dom",
|
|
22
14
|
"esnext.asynciterable"
|
|
23
15
|
],
|
|
24
|
-
"
|
|
16
|
+
"module": "CommonJS",
|
|
17
|
+
// "moduleResolution": "node",
|
|
18
|
+
"noImplicitAny": false,
|
|
19
|
+
"outDir": "dist",
|
|
20
|
+
"resolveJsonModule": true,
|
|
21
|
+
"skipLibCheck": true,
|
|
22
|
+
"strict": false,
|
|
23
|
+
"strictPropertyInitialization": false,
|
|
24
|
+
"target": "ES2020",
|
|
25
|
+
"types": [
|
|
26
|
+
"node"
|
|
27
|
+
]
|
|
25
28
|
},
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
"exclude": [
|
|
30
|
+
"node_modules",
|
|
31
|
+
"**/__tests__/*"
|
|
32
|
+
],
|
|
33
|
+
"include": [
|
|
34
|
+
"src",
|
|
35
|
+
"package.json"
|
|
36
|
+
]
|
|
37
|
+
}
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.
|
|
2
|
+
"version": "2.1.2",
|
|
3
3
|
"commands": {
|
|
4
4
|
"app:create": {
|
|
5
5
|
"id": "app:create",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"appIdentifier": {
|
|
45
45
|
"name": "appIdentifier",
|
|
46
46
|
"type": "option",
|
|
47
|
+
"char": "a",
|
|
47
48
|
"description": "The app identifier",
|
|
48
49
|
"required": false,
|
|
49
50
|
"multiple": false
|
|
@@ -110,13 +111,21 @@
|
|
|
110
111
|
"required": false,
|
|
111
112
|
"allowNo": false
|
|
112
113
|
},
|
|
113
|
-
"
|
|
114
|
-
"name": "
|
|
114
|
+
"verbose": {
|
|
115
|
+
"name": "verbose",
|
|
115
116
|
"type": "boolean",
|
|
116
|
-
"char": "
|
|
117
|
+
"char": "v",
|
|
117
118
|
"description": "Debug the app deployment step and do not remove the intermediate build artifacts.",
|
|
118
119
|
"required": false,
|
|
119
120
|
"allowNo": false
|
|
121
|
+
},
|
|
122
|
+
"dryRun": {
|
|
123
|
+
"name": "dryRun",
|
|
124
|
+
"type": "boolean",
|
|
125
|
+
"char": "d",
|
|
126
|
+
"description": "Dry run the upgrade without actually updating the app.",
|
|
127
|
+
"required": false,
|
|
128
|
+
"allowNo": false
|
|
120
129
|
}
|
|
121
130
|
},
|
|
122
131
|
"args": {}
|
|
@@ -881,30 +890,6 @@
|
|
|
881
890
|
},
|
|
882
891
|
"args": {}
|
|
883
892
|
},
|
|
884
|
-
"types:uploadTypePolicies": {
|
|
885
|
-
"id": "types:uploadTypePolicies",
|
|
886
|
-
"description": "Upload type policies",
|
|
887
|
-
"strict": true,
|
|
888
|
-
"pluginName": "@contrail/cli",
|
|
889
|
-
"pluginAlias": "@contrail/cli",
|
|
890
|
-
"pluginType": "core",
|
|
891
|
-
"aliases": [],
|
|
892
|
-
"examples": [
|
|
893
|
-
"$ contrail types UploadTypePolicies\n"
|
|
894
|
-
],
|
|
895
|
-
"flags": {
|
|
896
|
-
"dir": {
|
|
897
|
-
"name": "dir",
|
|
898
|
-
"type": "option",
|
|
899
|
-
"char": "d",
|
|
900
|
-
"description": "The directory from which to export the type policy data. Defaults to the current directory. The type policy data will be loaded from $dir/type-policies/*.yml",
|
|
901
|
-
"required": false,
|
|
902
|
-
"multiple": false,
|
|
903
|
-
"default": "."
|
|
904
|
-
}
|
|
905
|
-
},
|
|
906
|
-
"args": {}
|
|
907
|
-
},
|
|
908
893
|
"types:uploadTypePropertyPolicies": {
|
|
909
894
|
"id": "types:uploadTypePropertyPolicies",
|
|
910
895
|
"description": "Upload type property policies",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contrail/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "VibeIQ's Contrail Platform CLI.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"contrail-cli": "./bin/run",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"/oclif.manifest.json"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@contrail/sdk": "^1.2.
|
|
25
|
+
"@contrail/sdk": "^1.2.0",
|
|
26
26
|
"@contrail/types": "^3.0.20",
|
|
27
27
|
"@contrail/util": "^1.0.17",
|
|
28
28
|
"@oclif/core": "^2",
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Command } from '@oclif/core';
|
|
2
|
-
export default class UploadTypePolicies extends Command {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static flags: {
|
|
6
|
-
dir: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
7
|
-
};
|
|
8
|
-
run(): Promise<void>;
|
|
9
|
-
}
|
|
10
|
-
export declare function uploadTypePolicies(dir: string): Promise<void>;
|
|
@@ -1,226 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.uploadTypePolicies = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const sdk_1 = require("@contrail/sdk");
|
|
6
|
-
const fs_1 = tslib_1.__importDefault(require("fs"));
|
|
7
|
-
const path = tslib_1.__importStar(require("path"));
|
|
8
|
-
const login_1 = require("../../auth/login");
|
|
9
|
-
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
10
|
-
const core_1 = require("@oclif/core");
|
|
11
|
-
const type_extractor_1 = require("../../helpers/types/type-extractor");
|
|
12
|
-
const users_1 = require("../../api/users");
|
|
13
|
-
const yaml = require('js-yaml');
|
|
14
|
-
class UploadTypePolicies extends core_1.Command {
|
|
15
|
-
async run() {
|
|
16
|
-
const { flags } = await this.parse(UploadTypePolicies);
|
|
17
|
-
return await uploadTypePolicies(flags.dir);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
exports.default = UploadTypePolicies;
|
|
21
|
-
UploadTypePolicies.description = 'Upload type policies';
|
|
22
|
-
UploadTypePolicies.examples = [
|
|
23
|
-
`$ contrail types UploadTypePolicies
|
|
24
|
-
`,
|
|
25
|
-
];
|
|
26
|
-
UploadTypePolicies.flags = {
|
|
27
|
-
dir: core_1.Flags.string({ char: 'd', description: 'The directory from which to export the type policy data. Defaults to the current directory. The type policy data will be loaded from $dir/type-policies/*.yml', required: false, default: '.' }),
|
|
28
|
-
};
|
|
29
|
-
async function uploadTypePolicies(dir) {
|
|
30
|
-
try {
|
|
31
|
-
await (0, login_1.authUser)();
|
|
32
|
-
console.log('%s Uploading', chalk_1.default.yellow.bold('TYPE POLICY'));
|
|
33
|
-
const [reducedTypePolicies, reducedTypePolicyLinks] = await loadTypePolicies(dir);
|
|
34
|
-
await uploadTypePolicyObjects(reducedTypePolicies);
|
|
35
|
-
await uploadTypePolicyLinks(reducedTypePolicyLinks);
|
|
36
|
-
console.log('%s Uploaded', chalk_1.default.yellow.bold('TYPE POLICY'));
|
|
37
|
-
}
|
|
38
|
-
catch (e) {
|
|
39
|
-
console.log(`%s Type Policy Upload Failed. ${e}`, chalk_1.default.red.bold('FAIL'));
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
console.log('%s Type Policy Upload Complete.', chalk_1.default.green.bold('COMPLETE'));
|
|
43
|
-
}
|
|
44
|
-
exports.uploadTypePolicies = uploadTypePolicies;
|
|
45
|
-
function loadTypePolicies(fromDir) {
|
|
46
|
-
const tps = [];
|
|
47
|
-
let tpLinks = [];
|
|
48
|
-
const dir = path.join(fromDir, 'type-policies');
|
|
49
|
-
try {
|
|
50
|
-
const files = fs_1.default.readdirSync(dir);
|
|
51
|
-
for (const file of files) {
|
|
52
|
-
tps.push(yaml.load(fs_1.default.readFileSync(path.join(dir, file), 'utf8')));
|
|
53
|
-
}
|
|
54
|
-
tpLinks = yaml.load(fs_1.default.readFileSync(path.join(fromDir, 'type-policy-links.yml'), 'utf8'));
|
|
55
|
-
return [tps, tpLinks];
|
|
56
|
-
}
|
|
57
|
-
catch (e) {
|
|
58
|
-
throw new Error(`ERROR PARSING YAML: ${e}`);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
async function uploadTypePolicyObjects(reducedTypePolicies) {
|
|
62
|
-
const orgUsers = await (0, users_1.getUserOrgs)();
|
|
63
|
-
const groups = await (0, users_1.getGroups)();
|
|
64
|
-
function fillPrincipal(statement) {
|
|
65
|
-
const principal = statement === null || statement === void 0 ? void 0 : statement.principal;
|
|
66
|
-
if (!principal) {
|
|
67
|
-
console.warn(`skipping bad statement principal ${statement === null || statement === void 0 ? void 0 : statement.principal}`);
|
|
68
|
-
return statement;
|
|
69
|
-
}
|
|
70
|
-
const [type, identifier] = principal.split(':');
|
|
71
|
-
if (!type || !identifier) {
|
|
72
|
-
console.warn(`skipping bad statement principal ${statement === null || statement === void 0 ? void 0 : statement.principal}`);
|
|
73
|
-
return statement;
|
|
74
|
-
}
|
|
75
|
-
if (type === 'group') {
|
|
76
|
-
const group = groups.find(x => x.name === identifier);
|
|
77
|
-
if (!group) {
|
|
78
|
-
console.log(`Could not find group ${identifier}`);
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
statement.principal = `group:${group.id}`;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
else if (type === 'user') {
|
|
85
|
-
const orgUser = orgUsers.find(x => x.user.email === identifier);
|
|
86
|
-
if (!orgUser) {
|
|
87
|
-
console.log(`Could not find user ${identifier}`);
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
statement.principal = `user:${orgUser.user.id}`;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return statement;
|
|
94
|
-
}
|
|
95
|
-
reducedTypePolicies.forEach(policy => {
|
|
96
|
-
policy.policy.statements = policy.policy.statements.map(x => fillPrincipal(x));
|
|
97
|
-
});
|
|
98
|
-
const currentTypePolicies = await new sdk_1.Entities().get({
|
|
99
|
-
entityName: 'type-policy',
|
|
100
|
-
});
|
|
101
|
-
const currentTypePolicyByLabel = {};
|
|
102
|
-
for (const currentTypePolicy of currentTypePolicies) {
|
|
103
|
-
currentTypePolicyByLabel[currentTypePolicy.label] = currentTypePolicy;
|
|
104
|
-
}
|
|
105
|
-
const loadedTypePolicyByName = {};
|
|
106
|
-
for (const loadedTPP of reducedTypePolicies) {
|
|
107
|
-
loadedTypePolicyByName[loadedTPP.label] = loadedTPP;
|
|
108
|
-
}
|
|
109
|
-
for (const [label, loadedTPP] of Object.entries(loadedTypePolicyByName)) {
|
|
110
|
-
try {
|
|
111
|
-
const found = currentTypePolicyByLabel[label];
|
|
112
|
-
if (!found) {
|
|
113
|
-
console.log('Creating: ', label);
|
|
114
|
-
await new sdk_1.Entities().create({
|
|
115
|
-
entityName: 'type-policy',
|
|
116
|
-
object: loadedTPP
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
console.log('Updating: ', label);
|
|
121
|
-
await new sdk_1.Entities().update({
|
|
122
|
-
entityName: 'type-policy',
|
|
123
|
-
id: found.id,
|
|
124
|
-
object: loadedTPP,
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
catch (err) {
|
|
129
|
-
throw new Error(`Error Uploading Type Policy: ${err}`);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
for (const [label, currentTPP] of Object.entries(currentTypePolicyByLabel)) {
|
|
133
|
-
try {
|
|
134
|
-
const found = loadedTypePolicyByName[label];
|
|
135
|
-
if (!found) {
|
|
136
|
-
console.log('Deleting: ', label);
|
|
137
|
-
await new sdk_1.Entities().delete({
|
|
138
|
-
entityName: 'type-policy',
|
|
139
|
-
id: currentTPP['id'],
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
catch (err) {
|
|
144
|
-
throw new Error(`Error Type Policy: ${err}`);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
async function uploadTypePolicyLinks(reducedTypePolicyLinks) {
|
|
149
|
-
const types = await (0, type_extractor_1.getTypes)();
|
|
150
|
-
const currentTypePolicies = await new sdk_1.Entities().get({
|
|
151
|
-
entityName: 'type-policy',
|
|
152
|
-
});
|
|
153
|
-
const currentTypePolicyLinks = await new sdk_1.Entities().get({
|
|
154
|
-
entityName: 'type-policy-link',
|
|
155
|
-
});
|
|
156
|
-
const currentLinksHashes = {};
|
|
157
|
-
for (const currentLink of currentTypePolicyLinks) {
|
|
158
|
-
const foundType = types.find(type => type.id === currentLink.typeId);
|
|
159
|
-
const foundTypePolicy = currentTypePolicies.find(tp => tp.id === currentLink.typePolicyId);
|
|
160
|
-
if (!foundType || !foundTypePolicy) {
|
|
161
|
-
console.log('skipping unhashable, invalid policy link:', currentLink);
|
|
162
|
-
}
|
|
163
|
-
const hash = `${foundType.slug}|${foundTypePolicy.label}`;
|
|
164
|
-
currentLinksHashes[hash] = currentLink;
|
|
165
|
-
}
|
|
166
|
-
const reducedLinksByHashes = {};
|
|
167
|
-
for (const loadedLink of reducedTypePolicyLinks) {
|
|
168
|
-
const hash = `${loadedLink.typeSlug}|${loadedLink.typePolicyLabel}`;
|
|
169
|
-
reducedLinksByHashes[hash] = loadedLink;
|
|
170
|
-
}
|
|
171
|
-
for (const loadedTPLink of reducedTypePolicyLinks) {
|
|
172
|
-
try {
|
|
173
|
-
const found = currentLinksHashes[`${loadedTPLink.typeSlug}|${loadedTPLink.typePolicyLabel}`];
|
|
174
|
-
if (!found) {
|
|
175
|
-
if (!transformReducedLink(loadedTPLink, types, currentTypePolicies)) {
|
|
176
|
-
continue;
|
|
177
|
-
}
|
|
178
|
-
await new sdk_1.Entities().create({
|
|
179
|
-
entityName: 'type-policy-link',
|
|
180
|
-
object: {
|
|
181
|
-
typePolicyId: loadedTPLink.typePolicyId,
|
|
182
|
-
typeId: loadedTPLink.typeId,
|
|
183
|
-
},
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
if (!transformReducedLink(loadedTPLink, types, currentTypePolicies)) {
|
|
188
|
-
continue;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
catch (err) {
|
|
193
|
-
throw new Error(`Error Uploading type policy links: ${err}`);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
for (const [currentLinkHash, currentLink] of Object.entries(currentLinksHashes)) {
|
|
197
|
-
try {
|
|
198
|
-
const found = reducedLinksByHashes[currentLinkHash];
|
|
199
|
-
if (!found) {
|
|
200
|
-
console.log('Deleting: ', currentLinkHash);
|
|
201
|
-
await new sdk_1.Entities().delete({
|
|
202
|
-
entityName: 'type-policy-link',
|
|
203
|
-
id: currentLink['id'],
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
catch (err) {
|
|
208
|
-
throw new Error(`Error Deleting rule set link: ${err}`);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
function transformReducedLink(typePolicyLink, types, typePolicies) {
|
|
213
|
-
const foundType = types.find(type => type.slug === typePolicyLink.typeSlug);
|
|
214
|
-
if (!foundType) {
|
|
215
|
-
console.error('Could not find type with slug', typePolicyLink.typeSlug);
|
|
216
|
-
return false;
|
|
217
|
-
}
|
|
218
|
-
typePolicyLink.typeId = foundType.id;
|
|
219
|
-
const foundTypePolicy = typePolicies.find(tpp => tpp.label === typePolicyLink.typePolicyLabel);
|
|
220
|
-
if (!foundTypePolicy) {
|
|
221
|
-
console.error('Could not find type policy with label', typePolicyLink.typePolicyLabel);
|
|
222
|
-
return false;
|
|
223
|
-
}
|
|
224
|
-
typePolicyLink.typePolicyId = foundTypePolicy.id;
|
|
225
|
-
return true;
|
|
226
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# docker build -t app-name .
|
|
2
|
-
# docker run -p 9000:8080 app-name
|
|
3
|
-
FROM public.ecr.aws/lambda/nodejs:16
|
|
4
|
-
|
|
5
|
-
# Install NPM dependencies for function
|
|
6
|
-
COPY package* ${LAMBDA_TASK_ROOT}
|
|
7
|
-
COPY app.yml ${LAMBDA_TASK_ROOT}
|
|
8
|
-
RUN npm install
|
|
9
|
-
|
|
10
|
-
COPY tsconfig.json ${LAMBDA_TASK_ROOT}
|
|
11
|
-
COPY src/ ${LAMBDA_TASK_ROOT}/src
|
|
12
|
-
|
|
13
|
-
RUN npm run build
|
|
14
|
-
|
|
15
|
-
CMD ["dist/framework/handler.execute"]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
npm run docker-ecr-login:win && npm version patch && npm run docker-build:win && npm run docker-tag:win && npm run docker-push:win
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WARNING: Do not modify this file, it is part of the generic runtime handling logic
|
|
3
|
-
* for VibeIQ app actions.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import { setAppCredentials } from "@contrail/sdk";
|
|
8
|
-
import { loadAppConfig } from "./app-config";
|
|
9
|
-
import { AppActionCallbackStatus, AppActionRequest, AppActionResponse } from "./interfaces";
|
|
10
|
-
import { Logger } from "./logger";
|
|
11
|
-
var pjson = require('../../package.json');
|
|
12
|
-
|
|
13
|
-
const APP_CONFIG = loadAppConfig();
|
|
14
|
-
const appName = APP_CONFIG.appIdentifier;
|
|
15
|
-
|
|
16
|
-
export class ActionDispatcher {
|
|
17
|
-
|
|
18
|
-
public static async dispatchActionRequest(data: AppActionRequest) : Promise<AppActionResponse> {
|
|
19
|
-
// Sets the auth creds on the SDK
|
|
20
|
-
await setAppCredentials(data.apiKey, data.orgSlug);
|
|
21
|
-
|
|
22
|
-
const logger = new Logger();
|
|
23
|
-
const event = (typeof data.event === 'string')
|
|
24
|
-
? JSON.parse(data.event)
|
|
25
|
-
: data.event;
|
|
26
|
-
|
|
27
|
-
logger.log(`App Info: `, pjson.name, ':', pjson.version);
|
|
28
|
-
return ActionDispatcher.delegateToHandler(event, data, logger);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
private static async delegateToHandler(event, data: AppActionRequest, logger: Logger) : Promise<AppActionResponse>{
|
|
32
|
-
try {
|
|
33
|
-
const handler = ActionDispatcher.getActionHandler(data);
|
|
34
|
-
let actionResults = await handler(event, data, logger)
|
|
35
|
-
let body: any = {
|
|
36
|
-
logs: logger.allEntries,
|
|
37
|
-
taskId: data.taskId,
|
|
38
|
-
status: AppActionCallbackStatus.SUCCESS,
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
if(typeof actionResults === 'string'){
|
|
42
|
-
body.output = { message: actionResults }
|
|
43
|
-
} else if(typeof actionResults === 'object'){
|
|
44
|
-
if(actionResults.output){
|
|
45
|
-
body.output = actionResults.output;
|
|
46
|
-
}
|
|
47
|
-
if(actionResults.status) {
|
|
48
|
-
body.status = actionResults.status;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return {
|
|
52
|
-
statusCode: 200,
|
|
53
|
-
body
|
|
54
|
-
}
|
|
55
|
-
} catch (error) {
|
|
56
|
-
console.log("Error caught in handling action, sending Failure status: ", error)
|
|
57
|
-
return {
|
|
58
|
-
statusCode: 200,
|
|
59
|
-
body: {
|
|
60
|
-
output: {
|
|
61
|
-
errorMessage: error.message,
|
|
62
|
-
errorDetails: error.details
|
|
63
|
-
},
|
|
64
|
-
taskId: data.taskId,
|
|
65
|
-
logs: logger.allEntries,
|
|
66
|
-
status: AppActionCallbackStatus.FAILURE,
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** Retrives the handler function for the requested action
|
|
73
|
-
*/
|
|
74
|
-
private static getActionHandler(data: AppActionRequest): (event, data, logger) => any {
|
|
75
|
-
try {
|
|
76
|
-
const actionPath = data.action;
|
|
77
|
-
const actionName = actionPath.substring(appName.length + 1, actionPath.length);
|
|
78
|
-
console.log('action: ', actionPath, actionName);
|
|
79
|
-
const handlerFile = require(`../actions/${actionName}`);
|
|
80
|
-
if(!handlerFile) {
|
|
81
|
-
throw new Error(`Handler file could not be located for action : ${data.action}`);
|
|
82
|
-
}
|
|
83
|
-
const handlerFunction = handlerFile.execute;
|
|
84
|
-
if(!handlerFunction) {
|
|
85
|
-
throw new Error(`Handler function 'execute' could not be located for action : ${data.action}`);
|
|
86
|
-
}
|
|
87
|
-
return handlerFunction;
|
|
88
|
-
} catch (error) {
|
|
89
|
-
console.log("Error caught in getActionHandler: ", error)
|
|
90
|
-
throw new Error(`Could not locate handler function for requested action: ${data.action}`);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WARNING: Do not modify this file, it is part of the generic runtime handling logic
|
|
3
|
-
* for VibeIQ app actions.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import fs from 'fs';
|
|
7
|
-
const yaml = require('js-yaml');
|
|
8
|
-
|
|
9
|
-
export function loadAppConfig(){
|
|
10
|
-
const TARGET_DIR = process.cwd();
|
|
11
|
-
try {
|
|
12
|
-
const separator = getSeparatorByPlatform();
|
|
13
|
-
const doc = yaml.load(fs.readFileSync(TARGET_DIR + separator + 'app.yml', 'utf8'));
|
|
14
|
-
return doc;
|
|
15
|
-
} catch (e) {
|
|
16
|
-
throw new Error(`ERROR PARSING YAML: ${e}`);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function getSeparatorByPlatform() {
|
|
21
|
-
const isWin = process.platform === 'win32';
|
|
22
|
-
const separator = isWin ? '\\' : '/';
|
|
23
|
-
return separator;
|
|
24
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WARNING: Do not modify this file, it is part of the generic runtime handling logic
|
|
3
|
-
* for VibeIQ app actions.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import { AppActionRequest, AppActionResponse, ActionDispatcher } from '.';
|
|
8
|
-
|
|
9
|
-
export async function execute(data: AppActionRequest): Promise<AppActionResponse> {
|
|
10
|
-
return ActionDispatcher.dispatchActionRequest(data);
|
|
11
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WARNING: Do not modify this file, it is part of the generic runtime handling logic
|
|
3
|
-
* for VibeIQ app actions.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export interface AppActionRequest {
|
|
7
|
-
action: string;
|
|
8
|
-
apiKey: string;
|
|
9
|
-
orgSlug: string;
|
|
10
|
-
taskId: string;
|
|
11
|
-
event: any;
|
|
12
|
-
[key:string] : any;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
export interface AppActionResponse {
|
|
17
|
-
statusCode: number;
|
|
18
|
-
body: AppActionCallBack;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface AppActionCallBack {
|
|
22
|
-
output?: any;
|
|
23
|
-
status?: AppActionCallbackStatus;
|
|
24
|
-
logs?: Array<string>;
|
|
25
|
-
taskId?: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
export enum AppActionCallbackStatus {
|
|
30
|
-
FAILURE = 'FAILURE',
|
|
31
|
-
SUCCESS = 'SUCCESS'
|
|
32
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WARNING: Do not modify this file, it is part of the generic runtime handling logic
|
|
3
|
-
* for VibeIQ app actions.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export class Logger {
|
|
8
|
-
allEntries : Array<string> = [];
|
|
9
|
-
public log(...args){
|
|
10
|
-
console.log(...args);
|
|
11
|
-
this.allEntries.push(new Date().toISOString() + ': ' + args.join(''));
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
public getEntries(){
|
|
15
|
-
return this.allEntries.join('\n');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
public clearEntries(){
|
|
19
|
-
this.allEntries = [];
|
|
20
|
-
}
|
|
21
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WARNING: Do not modify this file, it is part of the generic runtime handling logic
|
|
3
|
-
* for VibeIQ app actions.
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import { execute } from './handler';
|
|
8
|
-
|
|
9
|
-
const express = require('express');
|
|
10
|
-
const bodyParser = require('body-parser');
|
|
11
|
-
const app = express();
|
|
12
|
-
const port = 5050;
|
|
13
|
-
|
|
14
|
-
// parse application/x-www-form-urlencoded
|
|
15
|
-
app.use(bodyParser.urlencoded({ extended: false }));
|
|
16
|
-
// parse application/json
|
|
17
|
-
app.use(bodyParser.json());
|
|
18
|
-
|
|
19
|
-
app.get('/health_check', (req, res) => {
|
|
20
|
-
res.send('Hello World!');
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
// DO NOT CHANGE THIS IMPLEMENTATION
|
|
24
|
-
app.post('/', async (req, res) => {
|
|
25
|
-
const result = await execute(req.body);
|
|
26
|
-
res.send(result);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
app.listen(port, () => {
|
|
30
|
-
console.log(`Mock server listening on port ${port}`);
|
|
31
|
-
});
|