@axway/axway-central-cli 3.14.0-rc.1 → 3.15.0-rc.0

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/dist/cli.js CHANGED
@@ -17,6 +17,7 @@ var _edit = require("./commands/edit");
17
17
  var _get = require("./commands/get");
18
18
  var _install = require("./commands/install");
19
19
  var _utils = require("./common/utils");
20
+ var _productize = require("./commands/productize");
20
21
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
21
22
  _dayjs.default.extend(_relativeTime.default);
22
23
  require('tls').DEFAULT_ECDH_CURVE = 'auto';
@@ -45,7 +46,8 @@ const cliParams = exports.cliParams = {
45
46
  delete: _delete.deleteCmd,
46
47
  edit: _edit.edit,
47
48
  get: _get.get,
48
- install: _install.install
49
+ install: _install.install,
50
+ productize: _productize.productize
49
51
  },
50
52
  extensions
51
53
  };
@@ -0,0 +1,370 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ProductizationHelper = void 0;
7
+ var _types = require("../../../common/types");
8
+ var _utils = require("../../../common/utils");
9
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
10
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
11
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
12
+ class ProductizationHelper {
13
+ constructor(apiServerClient) {
14
+ _defineProperty(this, "apiServerClient", void 0);
15
+ this.apiServerClient = apiServerClient;
16
+ }
17
+
18
+ /**
19
+ * Bulk Productization of API services.
20
+ * @param resources array of API services to be productized
21
+ */
22
+ async bulkProductizeAPIServices(resources, sortedDefsMap, transferOwnership) {
23
+ const sortedDefsArray = Array.from(sortedDefsMap.values());
24
+ let bulkResultMap = new Map();
25
+ for (const resource of resources) {
26
+ var _resource$spec, _resource$spec$apiSer, _resource$metadata, _resource$metadata$sc, _resource$spec6, _resource$spec6$apiSe, _resource$metadata2, _resource$spec14, _resource$spec14$apiS;
27
+ let bulkResult = {
28
+ success: [],
29
+ error: [],
30
+ warning: []
31
+ };
32
+ if (!(resource !== null && resource !== void 0 && (_resource$spec = resource.spec) !== null && _resource$spec !== void 0 && (_resource$spec$apiSer = _resource$spec.apiService) !== null && _resource$spec$apiSer !== void 0 && _resource$spec$apiSer.name)) {
33
+ var _resource$spec2, _resource$spec2$apiSe, _resource$spec3, _resource$spec3$apiSe;
34
+ let errorMessage = `Found an entry without a logical name for "kind/${_types.Kind.APIService}".`;
35
+ bulkResult.error.push({
36
+ name: resource === null || resource === void 0 ? void 0 : (_resource$spec2 = resource.spec) === null || _resource$spec2 === void 0 ? void 0 : (_resource$spec2$apiSe = _resource$spec2.apiService) === null || _resource$spec2$apiSe === void 0 ? void 0 : _resource$spec2$apiSe.name,
37
+ kind: _types.Kind.APIService,
38
+ error: new Error(errorMessage)
39
+ });
40
+ bulkResultMap.set((_resource$spec3 = resource.spec) === null || _resource$spec3 === void 0 ? void 0 : (_resource$spec3$apiSe = _resource$spec3.apiService) === null || _resource$spec3$apiSe === void 0 ? void 0 : _resource$spec3$apiSe.name, bulkResult);
41
+ continue;
42
+ }
43
+ if (!((_resource$metadata = resource.metadata) !== null && _resource$metadata !== void 0 && (_resource$metadata$sc = _resource$metadata.scope) !== null && _resource$metadata$sc !== void 0 && _resource$metadata$sc.name)) {
44
+ var _resource$spec4, _resource$spec4$apiSe, _resource$spec5, _resource$spec5$apiSe;
45
+ let errorMessage = `Found an API Service without a scope name for "kind/${_types.Kind.Environment}".`;
46
+ bulkResult.error.push({
47
+ name: resource === null || resource === void 0 ? void 0 : (_resource$spec4 = resource.spec) === null || _resource$spec4 === void 0 ? void 0 : (_resource$spec4$apiSe = _resource$spec4.apiService) === null || _resource$spec4$apiSe === void 0 ? void 0 : _resource$spec4$apiSe.name,
48
+ kind: _types.Kind.Environment,
49
+ error: new Error(errorMessage)
50
+ });
51
+ bulkResultMap.set((_resource$spec5 = resource.spec) === null || _resource$spec5 === void 0 ? void 0 : (_resource$spec5$apiSe = _resource$spec5.apiService) === null || _resource$spec5$apiSe === void 0 ? void 0 : _resource$spec5$apiSe.name, bulkResult);
52
+ continue;
53
+ }
54
+ const apiSvcResourceDef = await (0, _utils.getResourceDefinition)(sortedDefsArray, _types.Kind.APIService, _types.Kind.Environment);
55
+ const envResourceDef = await (0, _utils.getResourceDefinition)(sortedDefsArray, _types.Kind.Environment);
56
+ const assetResourceDef = await (0, _utils.getResourceDefinition)(sortedDefsArray, _types.Kind.Asset);
57
+ const productResourceDef = await (0, _utils.getResourceDefinition)(sortedDefsArray, _types.Kind.Product);
58
+ const apiSvc = await this.apiServerClient.getResourceByName({
59
+ resourceDef: apiSvcResourceDef,
60
+ resourceName: resource === null || resource === void 0 ? void 0 : (_resource$spec6 = resource.spec) === null || _resource$spec6 === void 0 ? void 0 : (_resource$spec6$apiSe = _resource$spec6.apiService) === null || _resource$spec6$apiSe === void 0 ? void 0 : _resource$spec6$apiSe.name,
61
+ scopeDef: envResourceDef,
62
+ scopeName: (_resource$metadata2 = resource.metadata) === null || _resource$metadata2 === void 0 ? void 0 : _resource$metadata2.scope.name
63
+ });
64
+ if (apiSvc.data && !apiSvc.error) {
65
+ var _apiSvc$data, _apiSvc$data$metadata, _resource$metadata3, _apiServiceInstances$, _apiServiceInstances$2, _assetResourcesResult2, _assetResourcesResult3, _assetResourcesResult4, _assetResourcesResult5, _bulkResult$warning;
66
+ const apiSvcInstanceResDef = await (0, _utils.getResourceDefinition)(sortedDefsArray, _types.Kind.APIServiceInstance, _types.Kind.Environment);
67
+ const query = 'metadata.references.id==' + ((_apiSvc$data = apiSvc.data) === null || _apiSvc$data === void 0 ? void 0 : (_apiSvc$data$metadata = _apiSvc$data.metadata) === null || _apiSvc$data$metadata === void 0 ? void 0 : _apiSvc$data$metadata.id);
68
+ const apiServiceInstances = await this.apiServerClient.getResourcesList({
69
+ resourceDef: apiSvcInstanceResDef,
70
+ scopeDef: envResourceDef,
71
+ scopeName: (_resource$metadata3 = resource.metadata) === null || _resource$metadata3 === void 0 ? void 0 : _resource$metadata3.scope.name,
72
+ query: query
73
+ });
74
+ // Donot continue if there are no api service instances
75
+ if (apiServiceInstances.error && ((_apiServiceInstances$ = apiServiceInstances.error) === null || _apiServiceInstances$ === void 0 ? void 0 : _apiServiceInstances$.length) > 0 || !apiServiceInstances.data || ((_apiServiceInstances$2 = apiServiceInstances.data) === null || _apiServiceInstances$2 === void 0 ? void 0 : _apiServiceInstances$2.length) === 0) {
76
+ var _resource$spec7, _resource$spec7$apiSe, _resource$spec8, _resource$spec8$apiSe, _resource$spec9, _resource$spec9$apiSe;
77
+ bulkResult.error.push({
78
+ name: resource === null || resource === void 0 ? void 0 : (_resource$spec7 = resource.spec) === null || _resource$spec7 === void 0 ? void 0 : (_resource$spec7$apiSe = _resource$spec7.apiService) === null || _resource$spec7$apiSe === void 0 ? void 0 : _resource$spec7$apiSe.name,
79
+ kind: resource.kind,
80
+ error: new Error('Unable to find APIServiceInstances for API Service: ' + (resource === null || resource === void 0 ? void 0 : (_resource$spec8 = resource.spec) === null || _resource$spec8 === void 0 ? void 0 : (_resource$spec8$apiSe = _resource$spec8.apiService) === null || _resource$spec8$apiSe === void 0 ? void 0 : _resource$spec8$apiSe.name))
81
+ });
82
+ bulkResultMap.set((_resource$spec9 = resource.spec) === null || _resource$spec9 === void 0 ? void 0 : (_resource$spec9$apiSe = _resource$spec9.apiService) === null || _resource$spec9$apiSe === void 0 ? void 0 : _resource$spec9$apiSe.name, bulkResult);
83
+ continue;
84
+ }
85
+ let assetResourcesResult = await this.createAssetResourcesForAPIServiceProductization(apiSvc.data, sortedDefsMap, apiServiceInstances, transferOwnership);
86
+ if (assetResourcesResult.error.length > 0) {
87
+ var _assetResourcesResult, _resource$spec10, _resource$spec10$apiS;
88
+ // if there is an error at any stage while productizing an api service,
89
+ // clean up the resources created until that stage to avoid duplicate resources hanging around
90
+ const asset = (_assetResourcesResult = assetResourcesResult.warning) === null || _assetResourcesResult === void 0 ? void 0 : _assetResourcesResult.find(result => result.kind === _types.Kind.Asset);
91
+ if (asset !== undefined) {
92
+ await this.cleanupResourcesOnFailure(asset, assetResourceDef);
93
+ }
94
+ bulkResult.error.push(...assetResourcesResult.error);
95
+ bulkResultMap.set((_resource$spec10 = resource.spec) === null || _resource$spec10 === void 0 ? void 0 : (_resource$spec10$apiS = _resource$spec10.apiService) === null || _resource$spec10$apiS === void 0 ? void 0 : _resource$spec10$apiS.name, bulkResult);
96
+ continue;
97
+ }
98
+ const assetName = (_assetResourcesResult2 = assetResourcesResult.warning) === null || _assetResourcesResult2 === void 0 ? void 0 : (_assetResourcesResult3 = _assetResourcesResult2.find(res => res.kind === _types.Kind.Asset)) === null || _assetResourcesResult3 === void 0 ? void 0 : _assetResourcesResult3.name;
99
+ const assetReleaseTagName = (_assetResourcesResult4 = assetResourcesResult.warning) === null || _assetResourcesResult4 === void 0 ? void 0 : (_assetResourcesResult5 = _assetResourcesResult4.find(res => res.kind === _types.Kind.ReleaseTag)) === null || _assetResourcesResult5 === void 0 ? void 0 : _assetResourcesResult5.name;
100
+ if (assetResourcesResult.warning) (_bulkResult$warning = bulkResult.warning) === null || _bulkResult$warning === void 0 ? void 0 : _bulkResult$warning.push(...assetResourcesResult.warning);
101
+ // check if asset release tag is created, then only proceed with creation of product resources
102
+ await this.checkForAssetReleaseTag(sortedDefsArray, assetReleaseTagName, assetName).then(async result => {
103
+ if (result) {
104
+ var _bulkResult$warning2;
105
+ let productResourcesResult = await this.createProductResourcesForAPIServiceProductization(apiSvc.data, sortedDefsMap, transferOwnership, assetName);
106
+ if (productResourcesResult.error.length > 0) {
107
+ var _assetResourcesResult6, _productResourcesResu;
108
+ // if there is an error at any stage while productizing an api service,
109
+ // clean up the resources created until that stage to avoid duplicate resources hanging around
110
+ const asset = (_assetResourcesResult6 = assetResourcesResult.warning) === null || _assetResourcesResult6 === void 0 ? void 0 : _assetResourcesResult6.find(result => result.kind === _types.Kind.Asset);
111
+ const product = (_productResourcesResu = productResourcesResult.warning) === null || _productResourcesResu === void 0 ? void 0 : _productResourcesResu.find(result => result.kind === _types.Kind.Product);
112
+ if (asset !== undefined) {
113
+ await this.cleanupResourcesOnFailure(asset, assetResourceDef);
114
+ }
115
+ if (product !== undefined) {
116
+ await this.cleanupResourcesOnFailure(product, productResourceDef);
117
+ }
118
+ bulkResult.error.push(...productResourcesResult.error);
119
+ }
120
+ if (productResourcesResult.warning) (_bulkResult$warning2 = bulkResult.warning) === null || _bulkResult$warning2 === void 0 ? void 0 : _bulkResult$warning2.push(...productResourcesResult.warning);
121
+ } else {
122
+ var _resource$spec11, _resource$spec11$apiS;
123
+ if (assetResourcesResult.warning && assetResourcesResult.warning.length > 0) {
124
+ const asset = assetResourcesResult.warning.find(result => result.kind === _types.Kind.Asset);
125
+ asset ? await this.cleanupResourcesOnFailure(asset, assetResourceDef) : undefined;
126
+ }
127
+ bulkResult.error.push({
128
+ name: resource === null || resource === void 0 ? void 0 : (_resource$spec11 = resource.spec) === null || _resource$spec11 === void 0 ? void 0 : (_resource$spec11$apiS = _resource$spec11.apiService) === null || _resource$spec11$apiS === void 0 ? void 0 : _resource$spec11$apiS.name,
129
+ kind: _types.Kind.ReleaseTag,
130
+ error: new Error('Unable to get asset release status while productizing api service')
131
+ });
132
+ }
133
+ });
134
+ } else {
135
+ var _resource$spec12, _resource$spec12$apiS, _resource$spec13, _resource$spec13$apiS, _resource$metadata4;
136
+ bulkResult.error.push({
137
+ name: resource === null || resource === void 0 ? void 0 : (_resource$spec12 = resource.spec) === null || _resource$spec12 === void 0 ? void 0 : (_resource$spec12$apiS = _resource$spec12.apiService) === null || _resource$spec12$apiS === void 0 ? void 0 : _resource$spec12$apiS.name,
138
+ kind: resource.kind,
139
+ error: new Error('Unable to find API Service with name: ' + (resource === null || resource === void 0 ? void 0 : (_resource$spec13 = resource.spec) === null || _resource$spec13 === void 0 ? void 0 : (_resource$spec13$apiS = _resource$spec13.apiService) === null || _resource$spec13$apiS === void 0 ? void 0 : _resource$spec13$apiS.name) + ' in Environment scope: ' + ((_resource$metadata4 = resource.metadata) === null || _resource$metadata4 === void 0 ? void 0 : _resource$metadata4.scope.name))
140
+ });
141
+ }
142
+ bulkResultMap.set((_resource$spec14 = resource.spec) === null || _resource$spec14 === void 0 ? void 0 : (_resource$spec14$apiS = _resource$spec14.apiService) === null || _resource$spec14$apiS === void 0 ? void 0 : _resource$spec14$apiS.name, bulkResult);
143
+ }
144
+ return bulkResultMap;
145
+ }
146
+
147
+ /**
148
+ * Create asset resources needed for productizing API services.
149
+ * @param apiService the apiService resource that needs to be productized
150
+ * @param sortedDefsMap sorted resource definition map
151
+ * @param apiServiceInstances api service instances referenced by the api service
152
+ * @param transferOwnership transfer ownership from api service to asset
153
+ */
154
+ async createAssetResourcesForAPIServiceProductization(apiService, sortedDefsMap, apiServiceInstances, transferOwnership) {
155
+ var _apiService$owner, _apiService$spec, _apiService$spec$icon, _assetResponse$warnin;
156
+ let bulkResult = {
157
+ success: [],
158
+ error: [],
159
+ warning: []
160
+ };
161
+ let resources = [];
162
+ const resourceName = apiService.name;
163
+ const sortedDefsArray = Array.from(sortedDefsMap.values());
164
+ // 1. Asset.
165
+ const assetResourceDef = await (0, _utils.getResourceDefinition)(sortedDefsArray, _types.Kind.Asset);
166
+ let assetResource = (0, _utils.buildGenericResource)({
167
+ resourceDef: assetResourceDef
168
+ });
169
+ // carry over the title of API Service to the asset title
170
+ assetResource.title = apiService === null || apiService === void 0 ? void 0 : apiService.title;
171
+ // transfer the ownership from api service if asked to
172
+ if (transferOwnership && apiService !== null && apiService !== void 0 && apiService.owner) assetResource.owner = {
173
+ type: 'team',
174
+ id: apiService === null || apiService === void 0 ? void 0 : (_apiService$owner = apiService.owner) === null || _apiService$owner === void 0 ? void 0 : _apiService$owner.id
175
+ };
176
+ // 1.1 set autorelease
177
+ assetResource.spec = {
178
+ type: 'API',
179
+ autoRelease: {
180
+ releaseType: 'patch',
181
+ requiresInitialActivation: true
182
+ }
183
+ };
184
+ // 1.2 add asset icon, if one exists
185
+ if (apiService !== null && apiService !== void 0 && (_apiService$spec = apiService.spec) !== null && _apiService$spec !== void 0 && (_apiService$spec$icon = _apiService$spec.icon) !== null && _apiService$spec$icon !== void 0 && _apiService$spec$icon.data) {
186
+ var _apiService$spec2, _apiService$spec2$ico;
187
+ assetResource.icon = apiService === null || apiService === void 0 ? void 0 : (_apiService$spec2 = apiService.spec) === null || _apiService$spec2 === void 0 ? void 0 : (_apiService$spec2$ico = _apiService$spec2.icon) === null || _apiService$spec2$ico === void 0 ? void 0 : _apiService$spec2$ico.data;
188
+ }
189
+ // 1.3 add asset access approval
190
+ assetResource.access = {
191
+ approval: 'automatic'
192
+ };
193
+ let assetResources = [];
194
+ assetResources.push(assetResource);
195
+ const assetResponse = await this.apiServerClient.bulkCreate(assetResources, sortedDefsMap, true);
196
+ if (assetResponse && assetResponse.warning && ((_assetResponse$warnin = assetResponse.warning) === null || _assetResponse$warnin === void 0 ? void 0 : _assetResponse$warnin.length) > 0 && assetResponse.error.length === 0) {
197
+ var _bulkResult$warning3, _assetResponse$warnin2, _assetResponse$warnin3;
198
+ (_bulkResult$warning3 = bulkResult.warning) === null || _bulkResult$warning3 === void 0 ? void 0 : _bulkResult$warning3.push(...assetResponse.warning);
199
+ const assetName = (_assetResponse$warnin2 = assetResponse.warning) === null || _assetResponse$warnin2 === void 0 ? void 0 : (_assetResponse$warnin3 = _assetResponse$warnin2.find(res => res.kind === _types.Kind.Asset)) === null || _assetResponse$warnin3 === void 0 ? void 0 : _assetResponse$warnin3.name;
200
+ // 1.4 Asset Mapping
201
+ const assetMappingResourceDef = await (0, _utils.getResourceDefinition)(sortedDefsArray, _types.Kind.AssetMapping, _types.Kind.Asset);
202
+ let assetMappingResource = (0, _utils.buildGenericResource)({
203
+ resourceDef: assetMappingResourceDef,
204
+ scopeName: assetName
205
+ });
206
+ // 1.5 set inputs
207
+ apiServiceInstances.data.forEach(instance => {
208
+ var _apiService$metadata, _apiService$metadata$, _instance$metadata;
209
+ assetMappingResource.spec = {
210
+ inputs: {
211
+ apiService: `management/${(_apiService$metadata = apiService.metadata) === null || _apiService$metadata === void 0 ? void 0 : (_apiService$metadata$ = _apiService$metadata.scope) === null || _apiService$metadata$ === void 0 ? void 0 : _apiService$metadata$.name}/${resourceName}`,
212
+ apiServiceInstance: `management/${(_instance$metadata = instance.metadata) === null || _instance$metadata === void 0 ? void 0 : _instance$metadata.scope.name}/${instance.name}`
213
+ }
214
+ };
215
+ });
216
+ resources.push(assetMappingResource);
217
+ // 1.6 Asset Release Tag
218
+ const assetReleaseResourceDef = await (0, _utils.getResourceDefinition)(sortedDefsArray, _types.Kind.ReleaseTag, _types.Kind.Asset);
219
+ let assetReleaseResource = (0, _utils.buildGenericResource)({
220
+ resourceDef: assetReleaseResourceDef,
221
+ scopeName: assetName
222
+ });
223
+ assetReleaseResource.spec = {
224
+ releaseType: 'major'
225
+ };
226
+ resources.push(assetReleaseResource);
227
+ let assetResourcesResult = await this.apiServerClient.bulkCreate(resources, sortedDefsMap, true);
228
+ if (assetResourcesResult && assetResourcesResult.warning && assetResourcesResult.warning.length > 0 && assetResourcesResult.error.length === 0) {
229
+ var _bulkResult$warning4;
230
+ (_bulkResult$warning4 = bulkResult.warning) === null || _bulkResult$warning4 === void 0 ? void 0 : _bulkResult$warning4.push(...assetResourcesResult.warning);
231
+ } else {
232
+ bulkResult.error.push(...assetResourcesResult.error);
233
+ }
234
+ } else {
235
+ bulkResult.error.push(...assetResponse.error);
236
+ }
237
+ return bulkResult;
238
+ }
239
+
240
+ /**
241
+ * Create product resources needed for productizing API services.
242
+ * @param apiService the apiService resource that needs to be productized
243
+ * @param sortedDefsMap sorted resource definition map
244
+ * @param transferOwnership transfer ownership from api service to product
245
+ */
246
+ async createProductResourcesForAPIServiceProductization(apiService, sortedDefsMap, transferOwnership, assetName) {
247
+ var _apiService$owner2, _apiService$spec3, _apiService$spec3$ico;
248
+ let bulkResult = {
249
+ success: [],
250
+ error: [],
251
+ warning: []
252
+ };
253
+ const sortedDefsArray = Array.from(sortedDefsMap.values());
254
+ // 1. Product
255
+ const productResourceDef = await (0, _utils.getResourceDefinition)(sortedDefsArray, _types.Kind.Product);
256
+ let productResource = (0, _utils.buildGenericResource)({
257
+ resourceDef: productResourceDef
258
+ });
259
+ // carry over the title of API Service to the product title
260
+ productResource.title = apiService === null || apiService === void 0 ? void 0 : apiService.title;
261
+ productResource.spec = {
262
+ autoRelease: {
263
+ releaseType: 'patch',
264
+ requiresInitialActivation: true
265
+ },
266
+ assets: [{
267
+ name: assetName
268
+ }]
269
+ };
270
+ // transfer the ownership from api service if asked to
271
+ if (transferOwnership && apiService !== null && apiService !== void 0 && apiService.owner) productResource.owner = {
272
+ type: 'team',
273
+ id: apiService === null || apiService === void 0 ? void 0 : (_apiService$owner2 = apiService.owner) === null || _apiService$owner2 === void 0 ? void 0 : _apiService$owner2.id
274
+ };
275
+ // 1.1 add product icon, if one exists
276
+ if (apiService !== null && apiService !== void 0 && (_apiService$spec3 = apiService.spec) !== null && _apiService$spec3 !== void 0 && (_apiService$spec3$ico = _apiService$spec3.icon) !== null && _apiService$spec3$ico !== void 0 && _apiService$spec3$ico.data) {
277
+ var _apiService$spec4, _apiService$spec4$ico;
278
+ productResource.icon = apiService === null || apiService === void 0 ? void 0 : (_apiService$spec4 = apiService.spec) === null || _apiService$spec4 === void 0 ? void 0 : (_apiService$spec4$ico = _apiService$spec4.icon) === null || _apiService$spec4$ico === void 0 ? void 0 : _apiService$spec4$ico.data;
279
+ }
280
+ let productResources = [];
281
+ productResources.push(productResource);
282
+ let productResponse = await this.apiServerClient.bulkCreate(productResources, sortedDefsMap, true);
283
+ if (productResponse && productResponse.warning && productResponse.warning.length > 0 && productResponse.error.length === 0) {
284
+ var _productResponse$warn, _productResponse$warn2, _bulkResult$warning5;
285
+ const productName = (_productResponse$warn = productResponse.warning) === null || _productResponse$warn === void 0 ? void 0 : (_productResponse$warn2 = _productResponse$warn.find(res => res.kind === _types.Kind.Product)) === null || _productResponse$warn2 === void 0 ? void 0 : _productResponse$warn2.name;
286
+ (_bulkResult$warning5 = bulkResult.warning) === null || _bulkResult$warning5 === void 0 ? void 0 : _bulkResult$warning5.push(...productResponse.warning);
287
+ // 1.2 Product Release Tag
288
+ const productReleaseResourceDef = await (0, _utils.getResourceDefinition)(sortedDefsArray, _types.Kind.ReleaseTag, _types.Kind.Product);
289
+ let productReleaseResource = (0, _utils.buildGenericResource)({
290
+ resourceDef: productReleaseResourceDef,
291
+ scopeName: productName
292
+ });
293
+ productReleaseResource.spec = {
294
+ releaseType: 'major'
295
+ };
296
+ let productResources = [];
297
+ productResources.push(productReleaseResource);
298
+ let productReleaseResult = await this.apiServerClient.bulkCreate(productResources, sortedDefsMap, true);
299
+ if (productReleaseResult && productReleaseResult.warning && productReleaseResult.warning.length > 0 && productReleaseResult.error.length === 0) {
300
+ var _bulkResult$warning6;
301
+ (_bulkResult$warning6 = bulkResult.warning) === null || _bulkResult$warning6 === void 0 ? void 0 : _bulkResult$warning6.push(...productReleaseResult.warning);
302
+ } else {
303
+ bulkResult.error.push(...productReleaseResult.error);
304
+ }
305
+ } else {
306
+ bulkResult.error.push(...productResponse.error);
307
+ }
308
+ return bulkResult;
309
+ }
310
+
311
+ /**
312
+ * Verify if an asset release tag has been created
313
+ * @param sortedDefsArray array of sorted defs
314
+ * @param releaseTag name of the asset release tag
315
+ * @param assetName name of the asset where the release tag is scoped under
316
+ * @param totalAttempts max number of attempts to successfully verify
317
+ * @param delay time in ms to wait to restart a new attempt
318
+ * @param retried number of retries to make
319
+ */
320
+ async checkForAssetReleaseTag(sortedDefsArray, releaseTag, assetName, totalAttempts = 8, delay = 100, retries = 0) {
321
+ var _assetReleaseTag$data;
322
+ const assetReleaseResourceDef = await (0, _utils.getResourceDefinition)(sortedDefsArray, _types.Kind.ReleaseTag, _types.Kind.Asset);
323
+ const assetResourceDef = await (0, _utils.getResourceDefinition)(sortedDefsArray, _types.Kind.Asset);
324
+ await (0, _utils.wait)(delay);
325
+ let assetReleaseTag = await this.apiServerClient.getResourceByName({
326
+ resourceDef: assetReleaseResourceDef,
327
+ resourceName: releaseTag,
328
+ scopeDef: assetResourceDef,
329
+ scopeName: assetName
330
+ });
331
+ if (assetReleaseTag.data && !assetReleaseTag.error && ((_assetReleaseTag$data = assetReleaseTag.data.status) === null || _assetReleaseTag$data === void 0 ? void 0 : _assetReleaseTag$data.level) === 'Success') {
332
+ return true;
333
+ } else if (retries < totalAttempts) {
334
+ // Try again after delay.
335
+ return await this.checkForAssetReleaseTag(sortedDefsArray, releaseTag, assetName, totalAttempts, 2 ** retries * 100, retries + 1);
336
+ } else {
337
+ // Ran out of attempts
338
+ return false;
339
+ }
340
+ }
341
+
342
+ /**
343
+ * Cleanup Asset/Product resources on Productization Failures
344
+ * @param resource the asset/product to be cleaned up
345
+ * @param resourceDef corresponding resource definition
346
+ */
347
+ async cleanupResourcesOnFailure(resource, resourceDef) {
348
+ // update the state of asset/product before deleting it and all the resources scoped under it
349
+ resource.state = 'archived';
350
+ const version = resource.apiVersion === undefined ? (0, _utils.getLatestServedAPIVersion)(resourceDef) : resource.apiVersion;
351
+ const subResourceReq = await this.apiServerClient.generateSubResourcesRequests({
352
+ resource: resource,
353
+ resourceName: resource.name,
354
+ resourceDef: resourceDef,
355
+ subResourceName: 'state',
356
+ version: version
357
+ });
358
+ const subResourceResult = await this.apiServerClient.resolveSubResourcesRequests(resource, subResourceReq);
359
+ if (subResourceResult.data && !subResourceResult.error) {
360
+ // delete the asset/product and all resources scoped under it if any
361
+ await this.apiServerClient.deleteResourceByName({
362
+ resourceDef: resourceDef,
363
+ resourceName: resource.name,
364
+ wait: true,
365
+ forceDelete: true
366
+ });
367
+ }
368
+ }
369
+ }
370
+ exports.ProductizationHelper = ProductizationHelper;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.productize = void 0;
7
+ var _snooplogg = _interopRequireDefault(require("snooplogg"));
8
+ var _amplifyCliUtils = require("@axway/amplify-cli-utils");
9
+ var _ApiServerClient = require("../../common/ApiServerClient");
10
+ var _DefinitionsManager = require("../../common/DefinitionsManager");
11
+ var _Renderer = _interopRequireDefault(require("../../common/Renderer"));
12
+ var _types = require("../../common/types");
13
+ var _productizationHelper = require("../productize/helpers/productizationHelper");
14
+ var _utils = require("../../common/utils");
15
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
+ const {
17
+ log
18
+ } = (0, _snooplogg.default)('central: productize');
19
+ const action = async ({
20
+ argv,
21
+ console
22
+ }) => {
23
+ var _account;
24
+ const {
25
+ baseUrl,
26
+ file,
27
+ region,
28
+ cache,
29
+ transferOwnership
30
+ } = argv;
31
+ let commandIsSuccessful = true;
32
+ log(`verifying args`);
33
+ if (!file) throw new Error('To create resources from a file, please provide -f, --file [path] option');
34
+ log(`verifying file: ${file}`);
35
+ (0, _utils.verifyFile)(file);
36
+ const render = new _Renderer.default(console).startSpin('Productizing API Service(s)');
37
+ const config = (0, _amplifyCliUtils.loadConfig)();
38
+ const environment = !baseUrl || baseUrl === _types.ProdBaseUrls.US || baseUrl === _types.ProdBaseUrls.EU || baseUrl === _types.ProdBaseUrls.AP ? config.get('env') : 'staging';
39
+ const {
40
+ sdk
41
+ } = (0, _amplifyCliUtils.initSDK)({
42
+ env: environment
43
+ }, config);
44
+ const list = await sdk.auth.list({
45
+ validate: true
46
+ });
47
+ let account = undefined;
48
+ if (list.length === 1) {
49
+ account = list[0];
50
+ } else if (list.length > 1) {
51
+ // try to find the default account
52
+ account = list.find(a => a.name === config.get('auth.defaultAccount')) || list.find(a => a.default) || list[0];
53
+ }
54
+ const client = new _ApiServerClient.ApiServerClient({
55
+ baseUrl,
56
+ account: (_account = account) === null || _account === void 0 ? void 0 : _account.name,
57
+ region,
58
+ useCache: cache,
59
+ forceGetAuthInfo: true
60
+ });
61
+ const defsManager = new _DefinitionsManager.DefinitionsManager(client);
62
+ let results = new Map();
63
+ log(`executing api calls`);
64
+ try {
65
+ await defsManager.init();
66
+ log(`loading and verifying specs`);
67
+ const allowedKind = new Set().add(_types.Kind.APIService);
68
+ const {
69
+ docs
70
+ } = await (0, _utils.loadAndVerifySpecs)(file, allowedKind, true);
71
+ render.startSpin('Productizing API Service(s)\n');
72
+ const sortedKindsMap = defsManager.getSortedKindsMap();
73
+ const helper = new _productizationHelper.ProductizationHelper(client);
74
+ results = await helper.bulkProductizeAPIServices(docs, sortedKindsMap, transferOwnership);
75
+ render.stopSpin();
76
+ render.productizationResult(results);
77
+ results.forEach(value => {
78
+ if (value.error.length > 0) commandIsSuccessful = false;
79
+ });
80
+ } catch (e) {
81
+ log('command error', e);
82
+ render.anyError(e);
83
+ } finally {
84
+ log(`command finished, success = ${commandIsSuccessful}`);
85
+ !commandIsSuccessful && process.exit(1);
86
+ }
87
+ };
88
+ const productize = exports.productize = {
89
+ action,
90
+ desc: 'Productize one or more API Services from a file',
91
+ options: {
92
+ ..._types.commonCmdArgsDescription,
93
+ '-f, --file [path]': {
94
+ desc: `Filename to use to create the resource`,
95
+ type: 'string'
96
+ },
97
+ '--transferOwnership': `Transfers the ownership(if exisiting) of API Service(s) to corresponding Asset(s) and Product(s)`
98
+ }
99
+ };
@@ -41,19 +41,22 @@ class ApiServerClient {
41
41
  region,
42
42
  account,
43
43
  useCache,
44
- team
44
+ team,
45
+ forceGetAuthInfo
45
46
  } = {}) {
46
47
  _defineProperty(this, "baseUrl", void 0);
47
48
  _defineProperty(this, "region", void 0);
48
49
  _defineProperty(this, "useCache", void 0);
49
50
  _defineProperty(this, "account", void 0);
50
51
  _defineProperty(this, "team", void 0);
52
+ _defineProperty(this, "forceGetAuthInfo", void 0);
51
53
  log(`initializing client with params: baseUrl = ${baseUrl}, region = ${region}, account = ${account}, useCache = ${useCache}, team = ${team}`);
52
54
  this.baseUrl = baseUrl;
53
55
  this.account = account;
54
56
  this.region = region;
55
57
  this.useCache = useCache === undefined ? true : useCache; // using cache by default
56
58
  this.team = team;
59
+ this.forceGetAuthInfo = forceGetAuthInfo;
57
60
  }
58
61
 
59
62
  /**
@@ -70,13 +73,14 @@ class ApiServerClient {
70
73
  forceDelete = false,
71
74
  expand,
72
75
  langDef,
73
- fieldSet
76
+ fieldSet,
77
+ embed
74
78
  }) {
75
79
  const groupUrl = `/${resourceDef.metadata.scope.name}/${version}`;
76
80
  const scopeUrl = scopeName && scopeDef ? `/${scopeDef.spec.plural}/${encodeURIComponent(scopeName)}` : '';
77
81
  const resourceUrl = `/${resourceDef.spec.plural}`;
78
82
  const nameUrl = resourceName ? `/${encodeURIComponent(resourceName)}` : '';
79
- const embedSet = new Set();
83
+ const embedSet = new Set(embed === null || embed === void 0 ? void 0 : embed.split(','));
80
84
  const expandSet = new Set(expand === null || expand === void 0 ? void 0 : expand.split(','));
81
85
  if (langDef) {
82
86
  var _fieldSet;
@@ -165,7 +169,7 @@ class ApiServerClient {
165
169
  if (language) {
166
170
  const langSubResourcesNames = (0, _utils.createLanguageSubresourceNames)(language);
167
171
  langSubResourcesNames.forEach(name => {
168
- if (!Object.keys(foundSubResources).includes(name) && name !== "languages") {
172
+ if (!Object.keys(foundSubResources).includes(name) && name !== 'languages') {
169
173
  console.log(_chalk.default.yellow(`\n\'${name}\' subresource definition not found, hence create/update cannot be performed on \'${name}\' subresource.`));
170
174
  }
171
175
  });
@@ -303,7 +307,8 @@ class ApiServerClient {
303
307
  baseUrl: this.baseUrl,
304
308
  region: this.region,
305
309
  account: this.account,
306
- team: this.team
310
+ team: this.team,
311
+ forceGetAuthInfo: this.forceGetAuthInfo
307
312
  });
308
313
  const version = resource.apiVersion === undefined ? (0, _utils.getLatestServedAPIVersion)(resourceDef) : resource.apiVersion;
309
314
  const urlPath = this.buildResourceUrlPath({
@@ -398,7 +403,6 @@ class ApiServerClient {
398
403
  } else {
399
404
  throw e;
400
405
  }
401
- ;
402
406
  }
403
407
  }
404
408
  result.pending = await this.generateSubResourcesRequests({
@@ -514,7 +518,8 @@ class ApiServerClient {
514
518
  baseUrl: this.baseUrl,
515
519
  region: this.region,
516
520
  account: this.account,
517
- team: this.team
521
+ team: this.team,
522
+ forceGetAuthInfo: this.forceGetAuthInfo
518
523
  });
519
524
  const urlPath = this.buildResourceUrlPath({
520
525
  resourceDef,
@@ -594,7 +599,8 @@ class ApiServerClient {
594
599
  baseUrl: this.baseUrl,
595
600
  region: this.region,
596
601
  account: this.account,
597
- team: this.team
602
+ team: this.team,
603
+ forceGetAuthInfo: this.forceGetAuthInfo
598
604
  });
599
605
  const urlPath = this.buildResourceUrlPath({
600
606
  resourceDef,
@@ -636,7 +642,8 @@ class ApiServerClient {
636
642
  expand,
637
643
  langDef,
638
644
  fieldSet,
639
- resourceVersion
645
+ resourceVersion,
646
+ embed
640
647
  }) {
641
648
  log(`getResourceByName, spec.kind = ${resourceDef.spec.kind}, name = ${resourceName}`);
642
649
  const version = resourceVersion === undefined ? (0, _utils.getLatestServedAPIVersion)(resourceDef) : resourceVersion;
@@ -649,7 +656,8 @@ class ApiServerClient {
649
656
  baseUrl: this.baseUrl,
650
657
  region: this.region,
651
658
  account: this.account,
652
- team: this.team
659
+ team: this.team,
660
+ forceGetAuthInfo: this.forceGetAuthInfo
653
661
  });
654
662
  const urlPath = this.buildResourceUrlPath({
655
663
  resourceDef,
@@ -659,7 +667,8 @@ class ApiServerClient {
659
667
  version,
660
668
  expand,
661
669
  langDef,
662
- fieldSet
670
+ fieldSet,
671
+ embed: embed
663
672
  });
664
673
  const response = await service.get(urlPath);
665
674
  result.data = response;
@@ -737,7 +746,7 @@ class ApiServerClient {
737
746
  * sorting of the array of resources with "compareResourcesByKindAsc".
738
747
  * @param resources array of resources to create
739
748
  */
740
- async bulkCreate(resources, sortedDefsMap) {
749
+ async bulkCreate(resources, sortedDefsMap, exitOnError = false) {
741
750
  log(`bulk create`);
742
751
  const sortedDefsArray = Array.from(sortedDefsMap.values());
743
752
  const pendingSubResources = [];
@@ -798,6 +807,9 @@ class ApiServerClient {
798
807
  error: nextError
799
808
  });
800
809
  }
810
+ if (exitOnError) {
811
+ return bulkResult;
812
+ }
801
813
  }
802
814
  }
803
815
 
@@ -22,7 +22,7 @@ const {
22
22
  // }
23
23
  let AccountRole = exports.AccountRole = /*#__PURE__*/function (AccountRole) {
24
24
  AccountRole["AnalyticsSpecialist"] = "analytics_specialist";
25
- AccountRole["ApiCentralAdmin"] = "api_engage_admin";
25
+ AccountRole["ApiCentralAdmin"] = "api_central_admin";
26
26
  AccountRole["FileTransferServicesAdmin"] = "fts_admin";
27
27
  AccountRole["FlowCentralAccessManager"] = "fc_access_manager";
28
28
  AccountRole["FlowCentralIntegration"] = "fc_integration";
@@ -54,7 +54,8 @@ class CoreConfigController {
54
54
  async getAuthInfo({
55
55
  account,
56
56
  clientId,
57
- team
57
+ team,
58
+ forceGetAuthInfo
58
59
  } = {}) {
59
60
  var _devOpsAccount, _devOpsAccount$org, _devOpsAccount$org$id, _devOpsAccount$org2;
60
61
  const configCtrl = new _CliConfigManager.CliConfigManager();
@@ -77,6 +78,9 @@ class CoreConfigController {
77
78
  let {
78
79
  devOpsAccount
79
80
  } = CoreConfigController;
81
+ if (forceGetAuthInfo) {
82
+ devOpsAccount = null;
83
+ }
80
84
  if (!devOpsAccount || account && devOpsAccount.name !== account) {
81
85
  log(`getAuthInfo, no cached devOpsAccount found, or account name does not match`);
82
86
  if (clientId) {
@@ -21,7 +21,7 @@ let PlatformAuthMethod = exports.PlatformAuthMethod = /*#__PURE__*/function (Pla
21
21
  return PlatformAuthMethod;
22
22
  }({});
23
23
  let PlatformServiceAccountRole = exports.PlatformServiceAccountRole = /*#__PURE__*/function (PlatformServiceAccountRole) {
24
- PlatformServiceAccountRole["ApiCentralAdmin"] = "api_engage_admin";
24
+ PlatformServiceAccountRole["ApiCentralAdmin"] = "api_central_admin";
25
25
  PlatformServiceAccountRole["FlowCentralAccessManager"] = "fc_access_manager";
26
26
  PlatformServiceAccountRole["FlowCentralIntegration"] = "fc_integration";
27
27
  PlatformServiceAccountRole["FlowCentralITAdmin"] = "fc_it_admin";
@@ -160,6 +160,28 @@ class Renderer {
160
160
  }
161
161
  }
162
162
 
163
+ /**
164
+ * Render bulk call result.
165
+ * If error is happening - render as simple output (even if "output" param has been provided)
166
+ * @param bulkResult bulk response from ApiServerClient
167
+ * @param simpleSuccessMsg message to display for each created "kind/name"
168
+ */
169
+ productizationResult(bulkResultMap) {
170
+ bulkResultMap.forEach((value, key) => {
171
+ console.log('\n\n' + 'API Service: ' + key);
172
+ if (value.warning && value.warning.length > 0) {
173
+ var _value$warning;
174
+ (_value$warning = value.warning) === null || _value$warning === void 0 ? void 0 : _value$warning.forEach(r => this.success(`${this.resourceAndScopeKinds(r)} was created successfully with an autogenerated logical name.`));
175
+ }
176
+ if (value.error.length > 0) {
177
+ value.error.forEach(r => this.anyError(r.error, `"${r.kind}/${r.name}" `, true));
178
+ if (key) this.warning('Unable to productize API Service ' + "'" + key + "' for the above errors.");
179
+ } else {
180
+ console.log('API Service ' + "'" + key + "' has been successfully productized.");
181
+ }
182
+ });
183
+ }
184
+
163
185
  /**
164
186
  * Render bulk "apply" result (with different success messages).
165
187
  * If error is happening - render as simple output (even if "output" param has been provided)
@@ -64,7 +64,7 @@ const getBaseUrl = async (baseUrl, basePath, region, orgRegion) => {
64
64
  const configuredRegion = String(region || configRegion || orgRegion || _types.Regions.US).toUpperCase();
65
65
  log(`Using region "${configuredRegion}" from ${region ? '--region' : configRegion ? 'config' : orgRegion ? 'org' : 'default'}`);
66
66
  const prodBaseurl = _types.ProdBaseUrls[configuredRegion];
67
- if (!prodBaseurl) throw Error('Unknown region provided, check your region config, should be one of: ' + Object.keys(_types.ProdBaseUrls).join(", "));
67
+ if (!prodBaseurl) throw Error('Unknown region provided, check your region config, should be one of: ' + Object.keys(_types.ProdBaseUrls).join(', '));
68
68
  return basePath ? prodBaseurl + basePath : prodBaseurl;
69
69
  }
70
70
  };
@@ -112,7 +112,8 @@ const dataService = async ({
112
112
  basePath = _types.BasePaths.ApiServer,
113
113
  clientId,
114
114
  region,
115
- team
115
+ team,
116
+ forceGetAuthInfo
116
117
  }) => {
117
118
  // see above
118
119
  // await versionCheckWarning();
@@ -124,7 +125,8 @@ const dataService = async ({
124
125
  } = await new _CoreConfigController.CoreConfigController().getAuthInfo({
125
126
  account,
126
127
  clientId,
127
- team
128
+ team,
129
+ forceGetAuthInfo
128
130
  });
129
131
  baseUrl = await getBaseUrl(baseUrl, basePath, region, orgRegion);
130
132
  const defaultHeaders = getDefaultHeaders({
@@ -24,6 +24,10 @@ let Kind = exports.Kind = /*#__PURE__*/function (Kind) {
24
24
  Kind["APIService"] = "APIService";
25
25
  Kind["APIServiceRevision"] = "APIServiceRevision";
26
26
  Kind["APIServiceInstance"] = "APIServiceInstance";
27
+ Kind["Asset"] = "Asset";
28
+ Kind["AssetMapping"] = "AssetMapping";
29
+ Kind["Product"] = "Product";
30
+ Kind["ReleaseTag"] = "ReleaseTag";
27
31
  Kind["Secret"] = "Secret";
28
32
  Kind["Webhook"] = "Webhook";
29
33
  Kind["ConsumerSubscriptionDefinition"] = "ConsumerSubscriptionDefinition";
@@ -6,9 +6,9 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.FormatString = FormatString;
7
7
  exports.KeyValueMapToNameValueArray = KeyValueMapToNameValueArray;
8
8
  exports.ValueFromKey = ValueFromKey;
9
- exports.parseScopeParam = exports.loadAndVerifySpecs = exports.loadAndVerifyApigeeXCredentialFile = exports.isWindows = exports.isValidJson = exports.isApiServerErrorType = exports.isApiServerErrorResponseType = exports.hbsCompare = exports.getLatestServedAPIVersion = exports.getConfig = exports.createLanguageSubresourceNames = exports.configFile = exports.compareResourcesByKindDesc = exports.compareResourcesByKindAsc = exports.buildTemplate = exports.buildGenericResource = void 0;
9
+ exports.parseScopeParam = exports.loadAndVerifySpecs = exports.loadAndVerifyApigeeXCredentialFile = exports.isWindows = exports.isValidJson = exports.isApiServerErrorType = exports.isApiServerErrorResponseType = exports.hbsCompare = exports.getResourceDefinition = exports.getLatestServedAPIVersion = exports.getConfig = exports.createLanguageSubresourceNames = exports.configFile = exports.compareResourcesByKindDesc = exports.compareResourcesByKindAsc = exports.buildTemplate = exports.buildGenericResource = void 0;
10
10
  exports.sanitizeMetadata = sanitizeMetadata;
11
- exports.writeToFile = exports.writeTemplates = exports.verifyScopeParam = exports.verifyFile = exports.transformSimpleFilters = void 0;
11
+ exports.writeToFile = exports.writeTemplates = exports.wait = exports.verifyScopeParam = exports.verifyFile = exports.transformSimpleFilters = void 0;
12
12
  var _fsExtra = require("fs-extra");
13
13
  var _handlebars = _interopRequireDefault(require("handlebars"));
14
14
  var _jsYaml = require("js-yaml");
@@ -72,7 +72,7 @@ const isValidJson = item => {
72
72
  * @param allowedKinds array of allowed "kind" values
73
73
  */
74
74
  exports.isValidJson = isValidJson;
75
- const loadAndVerifySpecs = async (specFilePath, allowedKinds) => {
75
+ const loadAndVerifySpecs = async (specFilePath, allowedKinds, skipKindCheck) => {
76
76
  // Load the given JSON or YAML file.
77
77
  let docs = [];
78
78
  let isMissingName = false;
@@ -107,12 +107,13 @@ const loadAndVerifySpecs = async (specFilePath, allowedKinds) => {
107
107
  if (!doc.name) {
108
108
  isMissingName = true;
109
109
  }
110
-
111
- // Validate resource kind.
112
- if (!doc.kind) {
113
- errors.push(Error(`${createErrorPrefix(index, doc.kind, doc.name)}: The "kind" field is missing.` + `\nCurrently supported values are (case sensitive): ${[...allowedKinds.values()].join(', ')}`));
114
- } else if (!allowedKinds.has(doc.kind)) {
115
- errors.push(new Error(`${createErrorPrefix(index, doc.kind, doc.name)}: Kind "${doc.kind}" is unsupported.` + `\nCurrently supported values are (case sensitive): ${[...allowedKinds.values()].join(', ')}`));
110
+ if (!skipKindCheck) {
111
+ // Validate resource kind.
112
+ if (!doc.kind) {
113
+ errors.push(Error(`${createErrorPrefix(index, doc.kind, doc.name)}: The "kind" field is missing.` + `\nCurrently supported values are (case sensitive): ${[...allowedKinds.values()].join(', ')}`));
114
+ } else if (!allowedKinds.has(doc.kind)) {
115
+ errors.push(new Error(`${createErrorPrefix(index, doc.kind, doc.name)}: Kind "${doc.kind}" is unsupported.` + `\nCurrently supported values are (case sensitive): ${[...allowedKinds.values()].join(', ')}`));
116
+ }
116
117
  }
117
118
 
118
119
  // TODO: Validate "metadata.scope.kind" if available. Requires DefinitionManager.getSortedKindsMap() result.
@@ -143,23 +144,43 @@ const buildGenericResource = ({
143
144
  resourceName,
144
145
  scopeName
145
146
  }) => {
146
- return {
147
- apiVersion: resourceDef.apiVersion,
148
- group: resourceDef.group,
149
- title: resourceName,
150
- name: resourceName,
151
- kind: resourceDef.spec.kind,
152
- attributes: {},
153
- tags: [],
154
- metadata: resourceDef.spec.scope && scopeName ? {
155
- scope: {
156
- kind: resourceDef.spec.scope.kind,
157
- name: scopeName
158
- }
159
- // note: forced conversion here only because using generated resources for rendering simple text
160
- } : undefined,
161
- spec: {}
162
- };
147
+ if (resourceName) {
148
+ var _resourceDef$spec, _resourceDef$spec2, _resourceDef$spec2$sc;
149
+ return {
150
+ apiVersion: resourceDef === null || resourceDef === void 0 ? void 0 : resourceDef.apiVersion,
151
+ group: resourceDef === null || resourceDef === void 0 ? void 0 : resourceDef.group,
152
+ title: resourceName,
153
+ name: resourceName,
154
+ kind: resourceDef === null || resourceDef === void 0 ? void 0 : resourceDef.spec.kind,
155
+ attributes: {},
156
+ tags: [],
157
+ metadata: resourceDef !== null && resourceDef !== void 0 && (_resourceDef$spec = resourceDef.spec) !== null && _resourceDef$spec !== void 0 && _resourceDef$spec.scope && scopeName ? {
158
+ scope: {
159
+ kind: resourceDef === null || resourceDef === void 0 ? void 0 : (_resourceDef$spec2 = resourceDef.spec) === null || _resourceDef$spec2 === void 0 ? void 0 : (_resourceDef$spec2$sc = _resourceDef$spec2.scope) === null || _resourceDef$spec2$sc === void 0 ? void 0 : _resourceDef$spec2$sc.kind,
160
+ name: scopeName
161
+ }
162
+ // note: forced conversion here only because using generated resources for rendering simple text
163
+ } : undefined,
164
+ spec: {}
165
+ };
166
+ } else {
167
+ var _resourceDef$spec3, _resourceDef$spec4, _resourceDef$spec4$sc;
168
+ return {
169
+ apiVersion: resourceDef === null || resourceDef === void 0 ? void 0 : resourceDef.apiVersion,
170
+ group: resourceDef === null || resourceDef === void 0 ? void 0 : resourceDef.group,
171
+ kind: resourceDef === null || resourceDef === void 0 ? void 0 : resourceDef.spec.kind,
172
+ attributes: {},
173
+ tags: [],
174
+ metadata: resourceDef !== null && resourceDef !== void 0 && (_resourceDef$spec3 = resourceDef.spec) !== null && _resourceDef$spec3 !== void 0 && _resourceDef$spec3.scope && scopeName ? {
175
+ scope: {
176
+ kind: resourceDef === null || resourceDef === void 0 ? void 0 : (_resourceDef$spec4 = resourceDef.spec) === null || _resourceDef$spec4 === void 0 ? void 0 : (_resourceDef$spec4$sc = _resourceDef$spec4.scope) === null || _resourceDef$spec4$sc === void 0 ? void 0 : _resourceDef$spec4$sc.kind,
177
+ name: scopeName
178
+ }
179
+ // note: forced conversion here only because using generated resources for rendering simple text
180
+ } : undefined,
181
+ spec: {}
182
+ };
183
+ }
163
184
  };
164
185
 
165
186
  /**
@@ -429,4 +450,27 @@ const getLatestServedAPIVersion = resourceDef => {
429
450
  // if the apiVersions are not set on the resource definition, fallback to v1alpha1 version
430
451
  return _ApiServerClient.ApiServerVersions.v1alpha1;
431
452
  };
432
- exports.getLatestServedAPIVersion = getLatestServedAPIVersion;
453
+
454
+ /**
455
+ * Wait for the given milliseconds
456
+ * @param {number} ms The given time to wait
457
+ * @returns {Promise} A fulfilled promise after the given time has passed
458
+ */
459
+ exports.getLatestServedAPIVersion = getLatestServedAPIVersion;
460
+ const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
461
+
462
+ /**
463
+ * Fetch resource definition of given kind and scope kind if exists
464
+ * @param {ResourceDefinition[]} sortedDefsArray The given time to wait
465
+ * @param {Kind} kind The kind of the resource
466
+ * @param {Kind} scopeKind The scope kind of the resource
467
+ */
468
+ exports.wait = wait;
469
+ const getResourceDefinition = async (sortedDefsArray, kind, scopeKind) => {
470
+ const resourceDefinition = sortedDefsArray.find(def => {
471
+ var _def$spec$scope5;
472
+ return scopeKind ? def.spec.kind === kind && ((_def$spec$scope5 = def.spec.scope) === null || _def$spec$scope5 === void 0 ? void 0 : _def$spec$scope5.kind) === scopeKind : def.spec.kind === kind;
473
+ });
474
+ return resourceDefinition;
475
+ };
476
+ exports.getResourceDefinition = getResourceDefinition;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axway/axway-central-cli",
3
- "version": "3.14.0-rc.1",
3
+ "version": "3.15.0-rc.0",
4
4
  "description": "Manage APIs, services and publish to the Amplify Marketplace",
5
5
  "homepage": "https://platform.axway.com",
6
6
  "author": {
package/test.json ADDED
@@ -0,0 +1,28 @@
1
+ [
2
+ {
3
+ "metadata": {
4
+ "scope": {
5
+ "kind": "Environment",
6
+ "name": "dkasu-env"
7
+ }
8
+ },
9
+ "spec": {
10
+ "apiService": {
11
+ "name": "amplify-central-api-2"
12
+ }
13
+ }
14
+ },
15
+ {
16
+ "metadata": {
17
+ "scope": {
18
+ "kind": "Environment",
19
+ "name": "dkasu-env-batch"
20
+ }
21
+ },
22
+ "spec": {
23
+ "apiService": {
24
+ "name": "swagger-petstore-openapi-3-0"
25
+ }
26
+ }
27
+ }
28
+ ]