@contrail/cli 2.0.18 → 2.0.21

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 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.18 darwin-arm64 node-v18.13.0
18
+ @contrail/cli/2.0.21 darwin-arm64 node-v18.13.0
19
19
  $ contrail --help [COMMAND]
20
20
  USAGE
21
21
  $ contrail COMMAND
@@ -75,6 +75,7 @@ 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)
78
79
  * [`contrail types uploadTypePropertyPolicies`](#contrail-types-uploadtypepropertypolicies)
79
80
  * [`contrail types uploadUsageInfo`](#contrail-types-uploadusageinfo)
80
81
  * [`contrail users export`](#contrail-users-export)
@@ -1046,6 +1047,25 @@ EXAMPLES
1046
1047
  $ contrail types uploadRuleSets
1047
1048
  ```
1048
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
+
1049
1069
  ## `contrail types uploadTypePropertyPolicies`
1050
1070
 
1051
1071
  Upload type property policies
@@ -5,3 +5,5 @@ 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.getTypePropertyPolicyLinks = exports.getTypePropertyPolicies = exports.getUsageInfo = exports.getRuleSetLinks = exports.getRuleSets = exports.getOptionSetHierarchies = exports.getOptionSets = void 0;
3
+ exports.getTypePolicyLinks = exports.getTypePolicies = 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,3 +50,17 @@ 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;
@@ -7,6 +7,7 @@ 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");
10
11
  class ImportInstance extends core_1.Command {
11
12
  async run() {
12
13
  const { flags } = await this.parse(ImportInstance);
@@ -14,6 +15,7 @@ class ImportInstance extends core_1.Command {
14
15
  await (0, upload_1.uploadUsers)(path.join(flags.dir, 'users.yml'));
15
16
  await (0, upload_2.uploadGroups)(path.join(flags.dir, 'groups.yml'));
16
17
  await (0, uploadTypePropertyPolicies_1.uploadTypePropertyPolicies)(flags.dir);
18
+ await (0, uploadTypePolicies_1.uploadTypePolicies)(flags.dir);
17
19
  }
18
20
  }
19
21
  exports.default = ImportInstance;
@@ -8,6 +8,8 @@ export interface DataHolder {
8
8
  usageInfo: any[];
9
9
  typePropertyPolicies: any[];
10
10
  typePropertyPolicyLinks: any[];
11
+ typePolicies: any[];
12
+ typePolicyLinks: any[];
11
13
  }
12
14
  export interface ReducedDataHolder {
13
15
  reducedTypes: any[];
@@ -18,6 +20,8 @@ export interface ReducedDataHolder {
18
20
  reducedUsageInfo: any[];
19
21
  reducedTypePropertyPolicies: any[];
20
22
  reducedTypePropertyPolicyLinks: any[];
23
+ reducedTypePolicies: any[];
24
+ reducedTypePolicyLinks: any[];
21
25
  }
22
26
  export default class GetAllTypes extends Command {
23
27
  static description: string;
@@ -45,6 +45,8 @@ 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)(),
48
50
  };
49
51
  const reducedData = await reduceData(data);
50
52
  await saveData(reducedData, outDir, overwrite);
@@ -101,11 +103,80 @@ async function reduceTypePropertyPolicies(data) {
101
103
  function reduceTypePropertyPolicyLinks(data) {
102
104
  var _a, _b;
103
105
  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
+ }, {});
104
113
  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 => {
105
176
  var _a, _b;
106
177
  return {
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,
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,
109
180
  };
110
181
  });
111
182
  }
@@ -197,7 +268,7 @@ function reduceTypes(dataHolder) {
197
268
  core: typeProperty.core,
198
269
  typePropertyOptionSetName: optionSetNameById[typeProperty.typePropertyOptionSetId],
199
270
  formula: typeProperty.formula,
200
- referencedTypeRootSlug: typeProperty.referencedTypeRootSlug,
271
+ referencedTypePath: typeProperty.referencedTypePath,
201
272
  defaultValue: typeProperty.defaultValue,
202
273
  propertyLevel: typeProperty.propertyLevel,
203
274
  inherited: typeProperty.inherited,
@@ -235,6 +306,8 @@ async function reduceData(data) {
235
306
  reducedUsageInfo: reduceUsageInfo(data),
236
307
  reducedTypePropertyPolicies: await reduceTypePropertyPolicies(data),
237
308
  reducedTypePropertyPolicyLinks: reduceTypePropertyPolicyLinks(data),
309
+ reducedTypePolicies: await reduceTypePolicies(data),
310
+ reducedTypePolicyLinks: reduceTypePolicyLinks(data),
238
311
  };
239
312
  }
240
313
  exports.reduceData = reduceData;
@@ -281,6 +354,8 @@ async function saveData(reducedData, dir, overwrite) {
281
354
  reducedUsageInfo: { filename: 'usage-info', split: false, fileLabel: '' },
282
355
  reducedTypePropertyPolicies: { filename: 'type-property-policies', split: true, fileLabel: 'label' },
283
356
  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: '' },
284
359
  };
285
360
  for (const [key, folder] of Object.entries(propertyToFolderMap)) {
286
361
  const CURRENT_DIR = process.cwd();
@@ -11,6 +11,7 @@ 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");
14
15
  class LoadAllTypes extends core_1.Command {
15
16
  async run() {
16
17
  const { flags } = await this.parse(LoadAllTypes);
@@ -36,6 +37,7 @@ async function loadAll(dir, skipPolicies = false) {
36
37
  await (0, uploadRuleSets_1.uploadRuleSets)(dir);
37
38
  if (!skipPolicies) {
38
39
  await (0, uploadTypePropertyPolicies_1.uploadTypePropertyPolicies)(dir);
40
+ await (0, uploadTypePolicies_1.uploadTypePolicies)(dir);
39
41
  }
40
42
  }
41
43
  catch (e) {
@@ -63,6 +63,8 @@ async function mergeTypeProperties(fileLocation, typePaths) {
63
63
  usageInfo: [],
64
64
  typePropertyPolicies: [],
65
65
  typePropertyPolicyLinks: [],
66
+ typePolicies: [],
67
+ typePolicyLinks: [],
66
68
  };
67
69
  const reducedData = await (0, getAll_1.reduceData)(data);
68
70
  for (const typePath of typePaths) {
@@ -0,0 +1,10 @@
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>;
@@ -0,0 +1,226 @@
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
+ }
@@ -37,6 +37,8 @@ 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);
40
42
  return;
41
43
  }
42
44
  console.log('%s Type Property Policy Upload Complete.', chalk_1.default.green.bold('COMPLETE'));
@@ -147,10 +149,16 @@ async function uploadTPPolicyObjects(reducedTypePropertyPolicies) {
147
149
  }
148
150
  async function uploadTypePropertyPolicyLinks(reducedTypePropertyPolicyLinks) {
149
151
  const typesWithProperties = await (0, type_extractor_1.getTypes)();
150
- const typeProperties = typesWithProperties
151
- .filter(t => !!t.typeProperties)
152
- .map(t => t.typeProperties)
153
- .reduce((a, b) => a.concat(b));
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
+ });
154
162
  const currentTPPs = await new sdk_1.Entities().get({
155
163
  entityName: 'type-property-policy',
156
164
  });
@@ -164,17 +172,17 @@ async function uploadTypePropertyPolicyLinks(reducedTypePropertyPolicyLinks) {
164
172
  if (!foundTypeProperty || !foundTPP) {
165
173
  console.log('skipping unhashable, invalid policy link:', currentLink);
166
174
  }
167
- const hash = `${foundTypeProperty.slug}|${foundTPP.label}`;
175
+ const hash = `${foundTypeProperty.typeSlug}${foundTypeProperty.slug}|${foundTPP.label}`;
168
176
  currentLinksHashes[hash] = currentLink;
169
177
  }
170
178
  const reducedLinksByHashes = {};
171
179
  for (const loadedLink of reducedTypePropertyPolicyLinks) {
172
- const hash = `${loadedLink.typePropertySlug}|${loadedLink.typePropertyPolicyLabel}`;
180
+ const hash = `${loadedLink.typeSlug}|${loadedLink.typePropertySlug}|${loadedLink.typePropertyPolicyLabel}`;
173
181
  reducedLinksByHashes[hash] = loadedLink;
174
182
  }
175
183
  for (const loadedTPPLink of reducedTypePropertyPolicyLinks) {
176
184
  try {
177
- const found = currentLinksHashes[`${loadedTPPLink.typePropertySlug}|${loadedTPPLink.typePropertyPolicyLabel}`];
185
+ const found = currentLinksHashes[`${loadedTPPLink.typeSlug}|${loadedTPPLink.typePropertySlug}|${loadedTPPLink.typePropertyPolicyLabel}`];
178
186
  if (!found) {
179
187
  if (!transformReducedLink(loadedTPPLink, typeProperties, currentTPPs)) {
180
188
  continue;
@@ -214,7 +222,7 @@ async function uploadTypePropertyPolicyLinks(reducedTypePropertyPolicyLinks) {
214
222
  }
215
223
  }
216
224
  function transformReducedLink(TPPLink, typeProperties, typePropertyPolicies) {
217
- const foundTP = typeProperties.find(tp => tp.slug === TPPLink.typePropertySlug);
225
+ const foundTP = typeProperties.find(tp => tp.slug === TPPLink.typePropertySlug && tp.typeSlug === TPPLink.typeSlug);
218
226
  if (!foundTP) {
219
227
  console.error('Could not find type property with label', TPPLink.typePropertySlug);
220
228
  return false;
@@ -148,7 +148,7 @@ async function uploadReducedTypeProperties(type, currentPropertyTypes, newProper
148
148
  core: newPropertyType.core,
149
149
  typePropertyOptionSetId: optionSetIdByName[newPropertyType.typePropertyOptionSetName],
150
150
  formula: newPropertyType.formula,
151
- referencedTypeRootSlug: newPropertyType.referencedTypeRootSlug,
151
+ referencedTypePath: newPropertyType.referencedTypePath,
152
152
  defaultValue: newPropertyType.defaultValue,
153
153
  propertyLevel: newPropertyType.propertyLevel,
154
154
  formulaFunction: newPropertyType.formulaFunction,
@@ -175,7 +175,7 @@ async function uploadReducedTypeProperties(type, currentPropertyTypes, newProper
175
175
  core: newPropertyType.core,
176
176
  typePropertyOptionSetId: optionSetIdByName[newPropertyType.typePropertyOptionSetName],
177
177
  formula: newPropertyType.formula,
178
- referencedTypeRootSlug: newPropertyType.referencedTypeRootSlug,
178
+ referencedTypePath: newPropertyType.referencedTypePath,
179
179
  defaultValue: newPropertyType.defaultValue,
180
180
  propertyLevel: newPropertyType.propertyLevel,
181
181
  formulaFunction: newPropertyType.formulaFunction,
@@ -218,7 +218,7 @@ function typePropertiesEqual(typeProperty1, typeProperty2, optionSetIdByName) {
218
218
  core: typeProperty1.core,
219
219
  typePropertyOptionSetId: optionSetIdByName[typeProperty1.typePropertyOptionSetName],
220
220
  formula: typeProperty1.formula,
221
- referencedTypeRootSlug: typeProperty1.referencedTypeRootSlug,
221
+ referencedTypePath: typeProperty1.referencedTypePath,
222
222
  defaultValue: typeProperty1.defaultValue,
223
223
  propertyLevel: typeProperty1.propertyLevel,
224
224
  formulaFunction: typeProperty1.formulaFunction,
@@ -234,7 +234,7 @@ function typePropertiesEqual(typeProperty1, typeProperty2, optionSetIdByName) {
234
234
  core: typeProperty2.core,
235
235
  typePropertyOptionSetId: optionSetIdByName[typeProperty2.typePropertyOptionSetName],
236
236
  formula: typeProperty2.formula,
237
- referencedTypeRootSlug: typeProperty2.referencedTypeRootSlug,
237
+ referencedTypePath: typeProperty2.referencedTypePath,
238
238
  defaultValue: typeProperty2.defaultValue,
239
239
  propertyLevel: typeProperty2.propertyLevel,
240
240
  formulaFunction: typeProperty2.formulaFunction,
@@ -301,7 +301,7 @@ export interface ReducedTypeProperty {
301
301
  core: boolean;
302
302
  typePropertyOptionSetName: string;
303
303
  formula: string;
304
- referencedTypeRootSlug: string;
304
+ referencedTypePath: string;
305
305
  defaultValue: string;
306
306
  propertyLevel: string;
307
307
  inherited: boolean;
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.0.18",
2
+ "version": "2.0.21",
3
3
  "commands": {
4
4
  "app:create": {
5
5
  "id": "app:create",
@@ -881,6 +881,30 @@
881
881
  },
882
882
  "args": {}
883
883
  },
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
+ },
884
908
  "types:uploadTypePropertyPolicies": {
885
909
  "id": "types:uploadTypePropertyPolicies",
886
910
  "description": "Upload type property policies",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrail/cli",
3
- "version": "2.0.18",
3
+ "version": "2.0.21",
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.0",
25
+ "@contrail/sdk": "^1.2.3",
26
26
  "@contrail/types": "^3.0.20",
27
27
  "@contrail/util": "^1.0.17",
28
28
  "@oclif/core": "^2",
@@ -33,6 +33,7 @@
33
33
  "amazon-cognito-identity-js": "^5.2.3",
34
34
  "arg": "^4.0.1",
35
35
  "aws-sdk": "^2.1044.0",
36
+ "axios": "^1.3.5",
36
37
  "chalk": "^4.0.0",
37
38
  "command-line-usage": "^6.1.1",
38
39
  "csvtojson": "^2.0.10",
@@ -46,7 +47,6 @@
46
47
  "lodash": "^4.17.21",
47
48
  "ncp": "^2.0.0",
48
49
  "pkg-install": "^1.0.0",
49
- "axios": "^1.3.5",
50
50
  "zip-a-folder": "^1.1.5"
51
51
  },
52
52
  "devDependencies": {