@contrail/cli 2.0.3 → 2.0.5

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 (42) hide show
  1. package/README.md +330 -187
  2. package/dist/api/apps.d.ts +1 -1
  3. package/dist/api/apps.js +2 -1
  4. package/dist/commands/app/install.d.ts +1 -0
  5. package/dist/commands/app/install.js +3 -2
  6. package/dist/commands/groups/export.d.ts +12 -0
  7. package/dist/commands/groups/export.js +93 -0
  8. package/dist/commands/groups/upload.d.ts +10 -0
  9. package/dist/commands/groups/upload.js +166 -0
  10. package/dist/commands/instance/export.d.ts +10 -0
  11. package/dist/commands/instance/export.js +24 -0
  12. package/dist/commands/instance/import.d.ts +9 -0
  13. package/dist/commands/instance/import.js +23 -0
  14. package/dist/commands/types/getAll.d.ts +5 -1
  15. package/dist/commands/types/getAll.js +31 -11
  16. package/dist/commands/types/loadAll.d.ts +5 -2
  17. package/dist/commands/types/loadAll.js +17 -13
  18. package/dist/commands/types/uploadOptionSetHierarchies.d.ts +4 -1
  19. package/dist/commands/types/uploadOptionSetHierarchies.js +13 -9
  20. package/dist/commands/types/uploadOptionSets.d.ts +4 -1
  21. package/dist/commands/types/uploadOptionSets.js +13 -9
  22. package/dist/commands/types/uploadRuleSets.d.ts +4 -1
  23. package/dist/commands/types/uploadRuleSets.js +12 -8
  24. package/dist/commands/types/uploadTypePropertyPolicies.d.ts +4 -1
  25. package/dist/commands/types/uploadTypePropertyPolicies.js +12 -8
  26. package/dist/commands/types/uploadUsageInfo.d.ts +4 -1
  27. package/dist/commands/types/uploadUsageInfo.js +9 -6
  28. package/dist/commands/users/export.d.ts +4 -1
  29. package/dist/commands/users/export.js +16 -7
  30. package/dist/commands/users/upload.d.ts +1 -0
  31. package/dist/commands/users/upload.js +5 -4
  32. package/dist/helpers/app/app-deployer.js +2 -0
  33. package/dist/helpers/file-helpers.d.ts +1 -0
  34. package/dist/helpers/file-helpers.js +23 -0
  35. package/dist/helpers/types/type-uploader.d.ts +1 -1
  36. package/dist/helpers/types/type-uploader.js +8 -8
  37. package/dist/interfaces.d.ts +1 -0
  38. package/dist/templates/typescript/app.yml +1 -0
  39. package/dist/templates/typescript/src/actions/logItem.ts +3 -8
  40. package/dist/templates/typescript/src/framework/app-config.ts +1 -4
  41. package/oclif.manifest.json +212 -15
  42. package/package.json +8 -3
@@ -10,4 +10,4 @@ export declare function upgradeAppVersion(appOrg: any, appVersionId: any): Promi
10
10
  export declare function deleteAppOrg(appOrgId: string): Promise<AppOrg>;
11
11
  export declare function getInstalledApps(): Promise<AppOrg[]>;
12
12
  export declare function installAppToOrg(app: any, configProperties: any): Promise<AppOrg>;
13
- export declare function getAvailableApps(): Promise<App[]>;
13
+ export declare function getAvailableApps(options?: any): Promise<App[]>;
package/dist/api/apps.js CHANGED
@@ -74,7 +74,7 @@ async function installAppToOrg(app, configProperties) {
74
74
  });
75
75
  }
76
76
  exports.installAppToOrg = installAppToOrg;
77
- async function getAvailableApps() {
77
+ async function getAvailableApps(options) {
78
78
  const orgId = auth_1.Auth.config.orgId;
79
79
  const apps = [];
80
80
  apps.push(...await new sdk_1.Entities().get({
@@ -89,6 +89,7 @@ async function getAvailableApps() {
89
89
  criteria: {
90
90
  orgId,
91
91
  private: false,
92
+ ...options
92
93
  },
93
94
  }));
94
95
  return apps;
@@ -6,6 +6,7 @@ export default class InstallApp extends Command {
6
6
  static flags: {
7
7
  appIdentifier: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
8
8
  installWorkflowTemplates: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
+ showHidden: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
10
  };
10
11
  run(): Promise<void>;
11
12
  }
@@ -10,9 +10,9 @@ const apps_1 = require("../../api/apps");
10
10
  const workflow_template_definition_deployer_1 = require("../../helpers/workflow-template-definitions/workflow-template-definition-deployer");
11
11
  class InstallApp extends core_1.Command {
12
12
  async run() {
13
- const { args, flags } = await this.parse(InstallApp);
13
+ const { flags } = await this.parse(InstallApp);
14
14
  await (0, login_1.authUser)();
15
- const apps = await (0, apps_1.getAvailableApps)();
15
+ const apps = await (0, apps_1.getAvailableApps)({ hidden: flags.showHidden });
16
16
  if (!apps.length) {
17
17
  throw new Error('No apps are available to install...');
18
18
  }
@@ -94,6 +94,7 @@ InstallApp.strict = true;
94
94
  InstallApp.flags = {
95
95
  appIdentifier: core_1.Flags.string({ char: 'i', description: 'The identifier of the app to install', required: false }),
96
96
  installWorkflowTemplates: core_1.Flags.boolean({ char: 'w', description: 'Install the app\'s accompanying workflows', required: false }),
97
+ showHidden: core_1.Flags.boolean({ char: 'h', description: 'Show the option to install public but hidden apps', required: false }),
97
98
  };
98
99
  async function getConfigProperties(app) {
99
100
  const config = {};
@@ -0,0 +1,12 @@
1
+ import { Command } from '@oclif/core';
2
+ export declare const DEFAULT_FILE_LOCATION = "groups.yml";
3
+ export default class ExportGroups extends Command {
4
+ static description: string;
5
+ static examples: string[];
6
+ static flags: {
7
+ outDir: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
8
+ overwrite: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
+ };
10
+ run(): Promise<void>;
11
+ }
12
+ export declare function exportGroups(fileLocation: string, overwrite: boolean): Promise<void>;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.exportGroups = exports.DEFAULT_FILE_LOCATION = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const path = tslib_1.__importStar(require("path"));
6
+ const sdk_1 = require("@contrail/sdk");
7
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
8
+ const fs_1 = tslib_1.__importDefault(require("fs"));
9
+ const login_1 = require("../../auth/login");
10
+ const js_yaml_1 = tslib_1.__importDefault(require("js-yaml"));
11
+ const core_1 = require("@oclif/core");
12
+ const file_helpers_1 = require("../../helpers/file-helpers");
13
+ exports.DEFAULT_FILE_LOCATION = 'groups.yml';
14
+ class ExportGroups extends core_1.Command {
15
+ async run() {
16
+ var _a;
17
+ const { flags } = await this.parse(ExportGroups);
18
+ try {
19
+ await (0, login_1.authUser)();
20
+ this.log('%s Getting Groups.', chalk_1.default.blue.bold('START'));
21
+ await exportGroups((_a = flags.outDir) !== null && _a !== void 0 ? _a : exports.DEFAULT_FILE_LOCATION, flags.overwrite);
22
+ this.log('%s Done', chalk_1.default.yellow.bold('GROUPS'));
23
+ }
24
+ catch (e) {
25
+ this.log(`%s Groups download Failed. ${e}`, chalk_1.default.red.bold('FAIL'));
26
+ return;
27
+ }
28
+ this.log('%s Groups download Complete.', chalk_1.default.green.bold('COMPLETE'));
29
+ }
30
+ }
31
+ exports.default = ExportGroups;
32
+ ExportGroups.description = 'Export all groups in the org.';
33
+ ExportGroups.examples = [
34
+ `$ contrail groups export
35
+ `,
36
+ ];
37
+ ExportGroups.flags = {
38
+ outDir: core_1.Flags.string({ char: 'd', description: 'The location for the file to be saved', required: false, default: exports.DEFAULT_FILE_LOCATION }),
39
+ overwrite: core_1.Flags.boolean({ description: 'Replaces existing files if they exist', required: false, default: false })
40
+ };
41
+ async function exportGroups(fileLocation, overwrite) {
42
+ const allGroups = await new sdk_1.Entities().get({
43
+ entityName: 'group', relations: ['groupPrincipals']
44
+ });
45
+ const allUsersInOrg = await new sdk_1.Entities().get({
46
+ entityName: 'user-org',
47
+ });
48
+ const groups = [];
49
+ for (const group of allGroups) {
50
+ const groupPrincipals = getGroupPrincipals(group, allGroups, allUsersInOrg);
51
+ groups.push({
52
+ name: group.name,
53
+ groupPrincipals,
54
+ });
55
+ }
56
+ await saveData(groups, fileLocation, overwrite);
57
+ }
58
+ exports.exportGroups = exportGroups;
59
+ async function saveData(data, fileLocation, overwrite) {
60
+ const yamlStr = js_yaml_1.default.dump(data);
61
+ const CURRENT_DIR = process.cwd();
62
+ const pathToWrite = path.resolve(path.join(CURRENT_DIR, fileLocation));
63
+ if (fs_1.default.existsSync(pathToWrite)) {
64
+ await (0, file_helpers_1.safeFileOverwrite)(pathToWrite, overwrite);
65
+ }
66
+ fs_1.default.writeFileSync(pathToWrite, yamlStr, 'utf8');
67
+ }
68
+ function getGroupPrincipals(group, allGroups, orgUsers) {
69
+ const principals = [];
70
+ for (const principal of group.groupPrincipals) {
71
+ const [type, id] = principal.principalReference.split(':');
72
+ if (type === 'user') {
73
+ const user = orgUsers.find(x => x.user.id === id);
74
+ if (user) {
75
+ principals.push({
76
+ type,
77
+ email: user.user.email
78
+ });
79
+ }
80
+ else {
81
+ console.log('couldn\'t find user', id);
82
+ }
83
+ }
84
+ else if (type === 'group') {
85
+ const nestedGroup = allGroups.find(x => x.id === id);
86
+ principals.push({
87
+ type: 'group',
88
+ name: nestedGroup.name
89
+ });
90
+ }
91
+ }
92
+ return principals;
93
+ }
@@ -0,0 +1,10 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ImportGroups extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static args: {
6
+ groupsFile: import("@oclif/core/lib/interfaces/parser").Arg<string, Record<string, unknown>>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
10
+ export declare function uploadGroups(fileLocation: string): Promise<void>;
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.uploadGroups = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const path = tslib_1.__importStar(require("path"));
6
+ const sdk_1 = require("@contrail/sdk");
7
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
8
+ const fs_1 = tslib_1.__importDefault(require("fs"));
9
+ const login_1 = require("../../auth/login");
10
+ const js_yaml_1 = tslib_1.__importDefault(require("js-yaml"));
11
+ const core_1 = require("@oclif/core");
12
+ class ImportGroups extends core_1.Command {
13
+ async run() {
14
+ const { args } = await this.parse(ImportGroups);
15
+ try {
16
+ await (0, login_1.authUser)();
17
+ this.log('%s Uploading Groups.', chalk_1.default.blue.bold('START'));
18
+ this.log('%s Uploading', chalk_1.default.yellow.bold('GROUP'));
19
+ await uploadGroups(args.groupsFile);
20
+ this.log('%s Uploaded', chalk_1.default.yellow.bold('GROUP'));
21
+ }
22
+ catch (e) {
23
+ this.log(`%s Group Upload Failed. ${e}`, chalk_1.default.red.bold('FAIL'));
24
+ return;
25
+ }
26
+ this.log('%s Group Upload Complete.', chalk_1.default.green.bold('COMPLETE'));
27
+ }
28
+ }
29
+ exports.default = ImportGroups;
30
+ ImportGroups.description = 'Import all groups in the groups.yml file';
31
+ ImportGroups.examples = [
32
+ `$ contrail groups import <GROUPS_FILE>
33
+ `,
34
+ ];
35
+ ImportGroups.args = {
36
+ groupsFile: core_1.Args.string({ description: 'The .yml file containing the groups', required: true }),
37
+ };
38
+ function getGroupsFile(fileLocation) {
39
+ const CURRENT_DIR = process.cwd();
40
+ try {
41
+ const fullPath = path.join(CURRENT_DIR, fileLocation);
42
+ const doc = js_yaml_1.default.load(fs_1.default.readFileSync(fullPath, 'utf8'));
43
+ return doc;
44
+ }
45
+ catch (e) {
46
+ throw new Error(`ERROR PARSING YAML: ${e}`);
47
+ }
48
+ }
49
+ async function uploadGroups(fileLocation) {
50
+ const existingGroups = await new sdk_1.Entities().get({
51
+ entityName: 'group', relations: ['groupPrincipals']
52
+ });
53
+ const groupsToImport = getGroupsFile(fileLocation);
54
+ const orgUsers = await new sdk_1.Entities().get({
55
+ entityName: 'user-org',
56
+ });
57
+ const toDelete = existingGroups.filter(x => !groupsToImport.map(y => y.name).includes(x.name));
58
+ const toCreate = groupsToImport.filter(x => !existingGroups.map(y => y.name).includes(x.name));
59
+ const toUpdate = existingGroups.filter(x => groupsToImport.map(y => y.name).includes(x.name));
60
+ const createdGroups = [];
61
+ // it's important to create all the groups first, to resolve any downstream principal dependencies
62
+ for (const group of toCreate) {
63
+ if (!group.groupPrincipals || !group.name) {
64
+ console.log('skipping invalid group');
65
+ }
66
+ createdGroups.push(await new sdk_1.Entities().create({
67
+ entityName: 'group', object: { name: group.name }
68
+ }));
69
+ }
70
+ const allGroupsAfterCreate = existingGroups.concat(createdGroups);
71
+ for (const group of toCreate) {
72
+ const createdGroup = createdGroups.find(x => x.name === group.name);
73
+ if (!createdGroup) {
74
+ continue;
75
+ }
76
+ await createGroupPrincipals(createdGroup, group.groupPrincipals, orgUsers, allGroupsAfterCreate);
77
+ }
78
+ for (const group of toUpdate) {
79
+ if (!group.groupPrincipals || !group.name) {
80
+ console.log('skipping invalid group');
81
+ }
82
+ await updateGroup(group.groupPrincipals, orgUsers, group, allGroupsAfterCreate);
83
+ }
84
+ for (const group of toDelete) {
85
+ if (!group.groupPrincipals || !group.name) {
86
+ console.log('skipping invalid group');
87
+ }
88
+ await new sdk_1.Entities().delete({ entityName: 'group', id: group.id });
89
+ }
90
+ }
91
+ exports.uploadGroups = uploadGroups;
92
+ async function updateGroup(principals, orgUsers, existingGroup, allGroupsAfterCreate) {
93
+ const existingPrincipals = existingGroup.groupPrincipals;
94
+ for (const principal of principals) {
95
+ if (principal.type === 'user') {
96
+ const user = orgUsers.map(x => x.user).find(x => x.email === (principal === null || principal === void 0 ? void 0 : principal.email));
97
+ if (!user) {
98
+ console.log(`user ${principal.email} is not in this org's user list`);
99
+ }
100
+ const principalId = `user:${user.id}`;
101
+ if (existingPrincipals.map(x => x.principalReference).includes(principalId)) {
102
+ continue;
103
+ }
104
+ await new sdk_1.Entities().update({
105
+ entityName: 'group-principal', object: {
106
+ principalReference: `user:${user.id}`,
107
+ groupId: existingGroup.id
108
+ }
109
+ });
110
+ }
111
+ else if (principal.type === 'group') {
112
+ const group = allGroupsAfterCreate.find(x => x.name === principal.name);
113
+ if (!group) {
114
+ console.log(`group ${principal.name} is not in this org's group list`);
115
+ }
116
+ const principalId = `group:${principal.name}`;
117
+ if (existingPrincipals.map(x => x.principalReference).includes(principalId)) {
118
+ continue;
119
+ }
120
+ await new sdk_1.Entities().update({
121
+ entityName: 'group-principal', object: {
122
+ principalReference: `group:${group.id}`,
123
+ groupId: existingGroup.id
124
+ }
125
+ });
126
+ }
127
+ }
128
+ }
129
+ async function createGroupPrincipals(group, principals, orgUsers, allGroupsAfterCreate) {
130
+ for (const principal of principals) {
131
+ if (principal.type === 'user') {
132
+ try {
133
+ const user = orgUsers.map(x => x.user).find(x => x.email === (principal === null || principal === void 0 ? void 0 : principal.email));
134
+ if (!user) {
135
+ console.log(`user ${principal.email} is not in this org's user list`);
136
+ }
137
+ await new sdk_1.Entities().create({
138
+ entityName: 'group-principal', object: {
139
+ principalReference: `user:${user.id}`,
140
+ groupId: group.id
141
+ }
142
+ });
143
+ }
144
+ catch (e) {
145
+ console.log('could not create group principal');
146
+ }
147
+ }
148
+ else if (principal.type === 'group') {
149
+ try {
150
+ const nestedGroup = allGroupsAfterCreate.find(x => x.name === principal.name);
151
+ if (!nestedGroup) {
152
+ console.log(`group ${principal.name} is not in this org's group list`);
153
+ }
154
+ await new sdk_1.Entities().create({
155
+ entityName: 'group-principal', object: {
156
+ principalReference: `group:${nestedGroup.id}`,
157
+ groupId: group.id
158
+ }
159
+ });
160
+ }
161
+ catch (e) {
162
+ console.log('could not create nested group');
163
+ }
164
+ }
165
+ }
166
+ }
@@ -0,0 +1,10 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ExportInstance extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ outDir: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
+ overwrite: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
+ };
9
+ run(): Promise<void>;
10
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const path = tslib_1.__importStar(require("path"));
5
+ const core_1 = require("@oclif/core");
6
+ const getAll_1 = require("../types/getAll");
7
+ const export_1 = require("../users/export");
8
+ class ExportInstance extends core_1.Command {
9
+ async run() {
10
+ const { flags } = await this.parse(ExportInstance);
11
+ await (0, getAll_1.getAll)(flags.outDir, flags.overwrite);
12
+ await (0, export_1.exportUsers)(path.join(flags.outDir, 'users.yml'), flags.overwrite);
13
+ }
14
+ }
15
+ exports.default = ExportInstance;
16
+ ExportInstance.description = 'Exports an data of an instance including types and users';
17
+ ExportInstance.examples = [
18
+ `$ contrail instance export
19
+ `,
20
+ ];
21
+ ExportInstance.flags = {
22
+ outDir: core_1.Flags.string({ description: 'The directory to which to export the instance data. Defaults to the current directory', required: false, default: '.' }),
23
+ overwrite: core_1.Flags.boolean({ description: 'Replaces any existing export files in outDir', required: false, default: false })
24
+ };
@@ -0,0 +1,9 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ImportInstance 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
+ }
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const path = tslib_1.__importStar(require("path"));
5
+ const core_1 = require("@oclif/core");
6
+ const loadAll_1 = require("../types/loadAll");
7
+ const upload_1 = require("../users/upload");
8
+ class ImportInstance extends core_1.Command {
9
+ async run() {
10
+ const { flags } = await this.parse(ImportInstance);
11
+ await (0, loadAll_1.loadAll)(flags.dir);
12
+ await (0, upload_1.uploadUsers)(path.join(flags.dir, 'users.yml'));
13
+ }
14
+ }
15
+ exports.default = ImportInstance;
16
+ ImportInstance.description = 'Import the data to an instance, including types and users';
17
+ ImportInstance.examples = [
18
+ `$ contrail instance import
19
+ `,
20
+ ];
21
+ ImportInstance.flags = {
22
+ dir: core_1.Flags.string({ description: 'The directory from which to export the instance data. Defaults to the current directory', required: false, default: '.' }),
23
+ };
@@ -22,8 +22,12 @@ export interface ReducedDataHolder {
22
22
  export default class GetAllTypes extends Command {
23
23
  static description: string;
24
24
  static examples: string[];
25
+ static flags: {
26
+ outDir: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
27
+ overwrite: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
28
+ };
25
29
  run(): Promise<void>;
26
30
  }
27
- export declare function getAll(): Promise<void>;
31
+ export declare function getAll(outDir: string, overwrite: boolean): Promise<void>;
28
32
  export declare function reduceTypes(dataHolder: DataHolder): any[];
29
33
  export declare function reduceData(data: DataHolder): ReducedDataHolder;
@@ -9,10 +9,12 @@ const login_1 = require("../../auth/login");
9
9
  const path = tslib_1.__importStar(require("path"));
10
10
  const type_extractor_1 = require("../../helpers/types/type-extractor");
11
11
  const types_1 = require("../../api/types");
12
+ const file_helpers_1 = require("../../helpers/file-helpers");
12
13
  const yaml = require('js-yaml');
13
14
  class GetAllTypes extends core_1.Command {
14
15
  async run() {
15
- await getAll();
16
+ const { flags } = await this.parse(GetAllTypes);
17
+ await getAll(flags.outDir, flags.overwrite);
16
18
  }
17
19
  }
18
20
  exports.default = GetAllTypes;
@@ -21,13 +23,18 @@ GetAllTypes.examples = [
21
23
  `$ contrail types getAll
22
24
  `,
23
25
  ];
24
- async function getAll() {
26
+ GetAllTypes.flags = {
27
+ outDir: core_1.Flags.string({ char: 'd', description: 'The directory to which to export the type data. Defaults to the current directory', required: false, default: '.' }),
28
+ overwrite: core_1.Flags.boolean({ description: 'Replaces any existing export files in outDir', required: false, default: false })
29
+ };
30
+ async function getAll(outDir, overwrite) {
25
31
  try {
26
32
  const userConfig = await (0, login_1.authUser)();
27
33
  console.log(`%s Getting all types for orgId: ${userConfig.orgId}`, chalk_1.default.blue.bold('START'));
28
34
  // make directory to house exports
29
- const dir = `./contrail-export-${Date.now()}`;
30
- fs_1.default.mkdirSync(dir);
35
+ if (!fs_1.default.existsSync(path.resolve(outDir))) {
36
+ fs_1.default.mkdirSync(path.resolve(outDir));
37
+ }
31
38
  const data = {
32
39
  types: await (0, type_extractor_1.getTypes)(),
33
40
  optionSets: await (0, types_1.getOptionSets)(),
@@ -39,7 +46,7 @@ async function getAll() {
39
46
  typePropertyPolicyLinks: await (0, types_1.getTypePropertyPolicyLinks)(),
40
47
  };
41
48
  const reducedData = reduceData(data);
42
- saveData(reducedData, dir);
49
+ await saveData(reducedData, outDir, overwrite);
43
50
  console.log('%s Retrieved', chalk_1.default.yellow.bold('TYPES'));
44
51
  }
45
52
  catch (e) {
@@ -196,7 +203,7 @@ function reduceData(data) {
196
203
  };
197
204
  }
198
205
  exports.reduceData = reduceData;
199
- const saveTypesFunction = function (data, dir) {
206
+ const saveTypesFunction = async (data, dir, overwrite) => {
200
207
  const roots = {};
201
208
  for (const type of data.reducedTypes) {
202
209
  const typePathParts = type.typePath.split(':');
@@ -222,10 +229,14 @@ const saveTypesFunction = function (data, dir) {
222
229
  if (!fileLabel) {
223
230
  console.warn('skipping bad type root:', root);
224
231
  }
225
- fs_1.default.writeFileSync(path.join(subDir, `${removeSlash(fileLabel)}.yml`), yamlStr, 'utf8');
232
+ const pathToWrite = path.join(subDir, `${removeSlash(fileLabel)}.yml`);
233
+ if (fs_1.default.existsSync(pathToWrite)) {
234
+ await (0, file_helpers_1.safeFileOverwrite)(pathToWrite, overwrite);
235
+ }
236
+ fs_1.default.writeFileSync(pathToWrite, yamlStr, 'utf8');
226
237
  }
227
238
  };
228
- function saveData(reducedData, dir) {
239
+ async function saveData(reducedData, dir, overwrite) {
229
240
  const propertyToFolderMap = {
230
241
  reducedTypes: { filename: 'types', split: false, fileLabel: 'slug', saveFunction: saveTypesFunction },
231
242
  reducedOptionSets: { filename: 'option-sets', split: true, fileLabel: 'name' },
@@ -239,7 +250,7 @@ function saveData(reducedData, dir) {
239
250
  for (const [key, folder] of Object.entries(propertyToFolderMap)) {
240
251
  const CURRENT_DIR = process.cwd();
241
252
  if (folder['saveFunction']) {
242
- folder['saveFunction'](reducedData, dir);
253
+ await folder['saveFunction'](reducedData, dir, overwrite);
243
254
  }
244
255
  else if (folder.split) {
245
256
  const subDir = path.join(CURRENT_DIR, dir, folder.filename);
@@ -251,13 +262,22 @@ function saveData(reducedData, dir) {
251
262
  const fileLabel = item[folder.fileLabel];
252
263
  if (!fileLabel) {
253
264
  console.warn('skipping bad data:', item);
265
+ continue;
254
266
  }
255
- fs_1.default.writeFileSync(path.join(subDir, `${removeSlash(fileLabel)}.yml`), yamlStr, 'utf8');
267
+ const pathToWrite = path.join(subDir, `${removeSlash(fileLabel)}.yml`);
268
+ if (fs_1.default.existsSync(pathToWrite)) {
269
+ await (0, file_helpers_1.safeFileOverwrite)(pathToWrite, overwrite);
270
+ }
271
+ fs_1.default.writeFileSync(pathToWrite, yamlStr, 'utf8');
256
272
  }
257
273
  }
258
274
  else {
259
275
  const yamlStr = yaml.dump(reducedData[key]);
260
- fs_1.default.writeFileSync(path.join(CURRENT_DIR, dir, `${folder.filename}.yml`), yamlStr, 'utf8');
276
+ const pathToWrite = path.join(CURRENT_DIR, dir, `${folder.filename}.yml`);
277
+ if (fs_1.default.existsSync(pathToWrite)) {
278
+ await (0, file_helpers_1.safeFileOverwrite)(pathToWrite, overwrite);
279
+ }
280
+ fs_1.default.writeFileSync(pathToWrite, yamlStr, 'utf8');
261
281
  }
262
282
  }
263
283
  }
@@ -1,7 +1,10 @@
1
1
  import { Command } from '@oclif/core';
2
- export default class GetAllTypes extends Command {
2
+ export default class LoadAllTypes extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
5
+ static flags: {
6
+ dir: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
+ };
5
8
  run(): Promise<void>;
6
9
  }
7
- export declare function loadAll(): Promise<void>;
10
+ export declare function loadAll(dir: string): Promise<void>;
@@ -11,26 +11,30 @@ 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
- class GetAllTypes extends core_1.Command {
14
+ class LoadAllTypes extends core_1.Command {
15
15
  async run() {
16
- await loadAll();
16
+ const { flags } = await this.parse(LoadAllTypes);
17
+ await loadAll(flags.dir);
17
18
  }
18
19
  }
19
- exports.default = GetAllTypes;
20
- GetAllTypes.description = 'Get all Types and associated data for your Org';
21
- GetAllTypes.examples = [
22
- `$ contrail types getAll
20
+ exports.default = LoadAllTypes;
21
+ LoadAllTypes.description = 'loads all the type data that has been exported by getAll';
22
+ LoadAllTypes.examples = [
23
+ `$ contrail types loadAll
23
24
  `,
24
25
  ];
25
- async function loadAll() {
26
+ LoadAllTypes.flags = {
27
+ dir: core_1.Flags.string({ char: 'd', description: 'The directory from which to load the types data. Defaults to the current directory.', required: false, default: '.' }),
28
+ };
29
+ async function loadAll(dir) {
26
30
  try {
27
31
  await (0, login_1.authUser)();
28
- await (0, uploadOptionSets_1.uploadOptionSets)();
29
- await (0, uploadOptionSetHierarchies_1.uploadOptionSetHierarchies)();
30
- await (0, type_uploader_1.uploadTypes)();
31
- await (0, uploadUsageInfo_1.uploadUsageInfo)();
32
- await (0, uploadRuleSets_1.uploadRuleSets)();
33
- await (0, uploadTypePropertyPolicies_1.uploadTypePropertyPolicies)();
32
+ await (0, uploadOptionSets_1.uploadOptionSets)(dir);
33
+ await (0, uploadOptionSetHierarchies_1.uploadOptionSetHierarchies)(dir);
34
+ await (0, type_uploader_1.uploadTypes)(dir);
35
+ await (0, uploadUsageInfo_1.uploadUsageInfo)(dir);
36
+ await (0, uploadRuleSets_1.uploadRuleSets)(dir);
37
+ await (0, uploadTypePropertyPolicies_1.uploadTypePropertyPolicies)(dir);
34
38
  }
35
39
  catch (e) {
36
40
  console.log(`%s Types Upload Failed. ${e}`, chalk_1.default.red.bold('FAIL'));
@@ -2,6 +2,9 @@ import { Command } from '@oclif/core';
2
2
  export default class UploadOptionSetHierarchies extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
5
+ static flags: {
6
+ dir: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
7
+ };
5
8
  run(): Promise<void>;
6
9
  }
7
- export declare function uploadOptionSetHierarchies(): Promise<void>;
10
+ export declare function uploadOptionSetHierarchies(dir: string): Promise<void>;
@@ -11,20 +11,24 @@ const core_1 = require("@oclif/core");
11
11
  const yaml = require('js-yaml');
12
12
  class UploadOptionSetHierarchies extends core_1.Command {
13
13
  async run() {
14
- return await uploadOptionSetHierarchies();
14
+ const { flags } = await this.parse(UploadOptionSetHierarchies);
15
+ return await uploadOptionSetHierarchies(flags.dir);
15
16
  }
16
17
  }
17
18
  exports.default = UploadOptionSetHierarchies;
18
- UploadOptionSetHierarchies.description = 'Upload OptionSets for your Org. OptionSets are loaded from .yml files in the option-sets directory.';
19
+ UploadOptionSetHierarchies.description = 'Upload Option Set Hierarchies for your Org. Option set hierarchies are loaded from .yml files in the option-set-hierarchies directory.';
19
20
  UploadOptionSetHierarchies.examples = [
20
21
  `$ contrail types uploadOptionSetHierarchies
21
22
  `,
22
23
  ];
23
- async function uploadOptionSetHierarchies() {
24
+ UploadOptionSetHierarchies.flags = {
25
+ dir: core_1.Flags.string({ char: 'd', description: 'The directory from which to export the option set hierarchies data. Defaults to the current directory. The option set data will be loaded from $dir/option-set-hierarchies', required: false, default: '.' }),
26
+ };
27
+ async function uploadOptionSetHierarchies(dir) {
24
28
  try {
25
29
  await (0, login_1.authUser)();
26
30
  console.log('%s Uploading', chalk_1.default.yellow.bold('OPTION SET HIERARCHIES'));
27
- const optionSetHierarchies = await loadOptionSetHierarchies();
31
+ const optionSetHierarchies = await loadOptionSetHierarchies(dir);
28
32
  await uploadOSH(optionSetHierarchies);
29
33
  console.log('%s Uploaded', chalk_1.default.yellow.bold('OPTION SET HIERARCHIES'));
30
34
  }
@@ -35,13 +39,13 @@ async function uploadOptionSetHierarchies() {
35
39
  console.log('%s Option set hierarchy Upload Complete.', chalk_1.default.green.bold('COMPLETE'));
36
40
  }
37
41
  exports.uploadOptionSetHierarchies = uploadOptionSetHierarchies;
38
- function loadOptionSetHierarchies() {
39
- const TARGET_DIR = process.cwd();
42
+ function loadOptionSetHierarchies(fromDir) {
40
43
  try {
41
- const files = fs_1.default.readdirSync(path.join(TARGET_DIR, 'option-set-hierarchies'));
44
+ const dir = path.resolve(path.join(fromDir, 'option-set-hierarchies'));
45
+ const files = fs_1.default.readdirSync(dir);
42
46
  const OSHs = [];
43
47
  for (const file of files) {
44
- OSHs.push(yaml.load(fs_1.default.readFileSync(path.join(TARGET_DIR, 'option-set-hierarchies', file), 'utf8')));
48
+ OSHs.push(yaml.load(fs_1.default.readFileSync(path.join(dir, file), 'utf8')));
45
49
  }
46
50
  return OSHs;
47
51
  }
@@ -117,7 +121,7 @@ async function uploadOSH(loadedOSHs) {
117
121
  }
118
122
  // transforms the passed hierarchy from names to ids, and returns true if operation succeeded.
119
123
  function transformOSHNameToID(hierarchy, optionSets) {
120
- console.log('passed hierarhy:', hierarchy);
124
+ console.log('passed hierarchy:', hierarchy);
121
125
  for (let i = 0; i < hierarchy.length; i++) {
122
126
  const os = optionSets.find(os => os.name === hierarchy[i]);
123
127
  if (!os) {