@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.
Files changed (33) hide show
  1. package/README.md +6 -25
  2. package/dist/api/types.d.ts +0 -2
  3. package/dist/api/types.js +1 -15
  4. package/dist/commands/app/create.js +2 -1
  5. package/dist/commands/app/getApiKey.js +3 -3
  6. package/dist/commands/app/publish.d.ts +2 -1
  7. package/dist/commands/app/publish.js +3 -2
  8. package/dist/commands/instance/import.js +0 -2
  9. package/dist/commands/types/getAll.d.ts +0 -4
  10. package/dist/commands/types/getAll.js +2 -77
  11. package/dist/commands/types/loadAll.js +0 -2
  12. package/dist/commands/types/mergeTypeProperties.js +0 -2
  13. package/dist/commands/types/uploadTypePropertyPolicies.js +8 -16
  14. package/dist/helpers/app/app-deployer.d.ts +3 -2
  15. package/dist/helpers/app/app-deployer.js +25 -5
  16. package/dist/templates/typescript/app.yml +0 -1
  17. package/dist/templates/typescript/package.json +5 -18
  18. package/dist/templates/typescript/src/actions/logItem.ts +20 -17
  19. package/dist/templates/typescript/src/main.ts +48 -0
  20. package/dist/templates/typescript/tsconfig.json +22 -13
  21. package/oclif.manifest.json +13 -28
  22. package/package.json +2 -2
  23. package/dist/commands/types/uploadTypePolicies.d.ts +0 -10
  24. package/dist/commands/types/uploadTypePolicies.js +0 -226
  25. package/dist/templates/typescript/Dockerfile +0 -15
  26. package/dist/templates/typescript/docker_deploy.bat +0 -1
  27. package/dist/templates/typescript/src/framework/action-dispatcher.ts +0 -93
  28. package/dist/templates/typescript/src/framework/app-config.ts +0 -24
  29. package/dist/templates/typescript/src/framework/handler.ts +0 -11
  30. package/dist/templates/typescript/src/framework/index.ts +0 -3
  31. package/dist/templates/typescript/src/framework/interfaces.ts +0 -32
  32. package/dist/templates/typescript/src/framework/logger.ts +0 -21
  33. 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.0.19 darwin-arm64 node-v18.13.0
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 [--appIdentifier <value>]
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, --debug Debug the app deployment step and do not remove the intermediate build artifacts.
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
@@ -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.getTypePolicyLinks = exports.getTypePolicies = exports.getTypePropertyPolicyLinks = exports.getTypePropertyPolicies = exports.getUsageInfo = exports.getRuleSetLinks = exports.getRuleSets = exports.getOptionSetHierarchies = exports.getOptionSets = void 0;
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: ${answers.appApiKey}`);
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: ${appFound.apiKey.apiKey}`);
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
- debug: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
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.debug).deploy(appDeclaration);
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
- debug: core_1.Flags.boolean({ char: 'd', description: 'Debug the app deployment step and do not remove the intermediate build artifacts.', required: false }),
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
- typeSlug: (_a = types.find(y => y.id === x.typeId)) === null || _a === void 0 ? void 0 : _a.slug,
179
- typePolicyLabel: (_b = data.typePolicies.find(y => y.id === x.typePolicyId)) === null || _b === void 0 ? void 0 : _b.label,
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
- typesWithProperties.forEach(type => {
154
- if (type.typeProperties) {
155
- for (const tp of type.typeProperties) {
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.typeSlug}${foundTypeProperty.slug}|${foundTPP.label}`;
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.typeSlug}|${loadedLink.typePropertySlug}|${loadedLink.typePropertyPolicyLabel}`;
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.typeSlug}|${loadedTPPLink.typePropertySlug}|${loadedTPPLink.typePropertyPolicyLabel}`];
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 && tp.typeSlug === TPPLink.typeSlug);
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
- constructor(debug?: boolean);
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/framework/mock-server.ts",
19
- "debug": "nodemon -r ts-node/register --inspect=127.0.0.1:60002 --watch 'actions/**/*.ts' --exec node src/framework/mock-server.ts",
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 "@contrail/sdk";
2
- import { AppActionCallBack, AppActionCallbackStatus } from "../framework";
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 async function execute(event, config: any, logger: Logger): Promise<AppActionCallBack> {
6
- logger.log('Starting Example Action');
7
- logger.log('Getting item from SDK');
4
+ export class LogItemAction implements AppAction {
8
5
 
9
- const item = await new Entities().get({
10
- entityName: 'item',
11
- id: event.id,
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
- return {
16
- output: {
17
- item,
18
- },
19
- status: AppActionCallbackStatus.SUCCESS
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
- "types": ["node"]
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
- "include": ["src"],
27
- "exclude": ["node_modules", "**/__tests__/*"]
28
- }
29
+ "exclude": [
30
+ "node_modules",
31
+ "**/__tests__/*"
32
+ ],
33
+ "include": [
34
+ "src",
35
+ "package.json"
36
+ ]
37
+ }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.0.19",
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
- "debug": {
114
- "name": "debug",
114
+ "verbose": {
115
+ "name": "verbose",
115
116
  "type": "boolean",
116
- "char": "d",
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.0.19",
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.3",
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,3 +0,0 @@
1
- export * from './interfaces';
2
- export * from './action-dispatcher';
3
- export * from './logger';
@@ -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
- });