@axway/axway-central-cli 3.7.0 → 3.8.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/commands/apply/index.js +16 -18
- package/dist/common/ApiServerClient.js +166 -202
- package/dist/common/Renderer.js +43 -27
- package/package.json +1 -1
|
@@ -28,7 +28,8 @@ const action = async ({
|
|
|
28
28
|
region,
|
|
29
29
|
cache,
|
|
30
30
|
yes,
|
|
31
|
-
language
|
|
31
|
+
language,
|
|
32
|
+
subresource
|
|
32
33
|
} = argv;
|
|
33
34
|
let isCmdError = false;
|
|
34
35
|
|
|
@@ -38,17 +39,7 @@ const action = async ({
|
|
|
38
39
|
if (!file) throw new Error('File name is required, please provide -f, --file [path] option');
|
|
39
40
|
log(`verifying file: ${file}`);
|
|
40
41
|
(0, _utils.verifyFile)(file);
|
|
41
|
-
let results =
|
|
42
|
-
created: {
|
|
43
|
-
success: [],
|
|
44
|
-
error: [],
|
|
45
|
-
warning: []
|
|
46
|
-
},
|
|
47
|
-
updated: {
|
|
48
|
-
success: [],
|
|
49
|
-
error: []
|
|
50
|
-
}
|
|
51
|
-
};
|
|
42
|
+
let results = [];
|
|
52
43
|
const render = new _Renderer.default(console, output).startSpin('Creating or updating resource(s)');
|
|
53
44
|
const client = new _ApiServerClient.ApiServerClient({
|
|
54
45
|
baseUrl,
|
|
@@ -75,15 +66,18 @@ const action = async ({
|
|
|
75
66
|
render.startSpin('Creating or updating resource(s)');
|
|
76
67
|
}
|
|
77
68
|
const sortedKindsMap = defsManager.getSortedKindsMap();
|
|
78
|
-
results = await client.bulkCreateOrUpdate(docs, sortedKindsMap, language);
|
|
79
|
-
render.bulkCreateOrUpdateResult(results
|
|
80
|
-
isCmdError = results.
|
|
69
|
+
results = await client.bulkCreateOrUpdate(docs, sortedKindsMap, language, subresource);
|
|
70
|
+
render.bulkCreateOrUpdateResult(results);
|
|
71
|
+
isCmdError = results.some(nextResult => {
|
|
72
|
+
var _nextResult$error$len, _nextResult$error;
|
|
73
|
+
return (_nextResult$error$len = (_nextResult$error = nextResult.error) === null || _nextResult$error === void 0 ? void 0 : _nextResult$error.length) !== null && _nextResult$error$len !== void 0 ? _nextResult$error$len : 0 > 0;
|
|
74
|
+
});
|
|
81
75
|
} catch (e) {
|
|
82
76
|
log('command error', e);
|
|
83
77
|
isCmdError = true;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
render.bulkCreateOrUpdateResult(results
|
|
78
|
+
if (results.some(nextResult => nextResult.data)) {
|
|
79
|
+
// Render the results that have completed.
|
|
80
|
+
render.bulkCreateOrUpdateResult(results);
|
|
87
81
|
}
|
|
88
82
|
render.anyError(e);
|
|
89
83
|
} finally {
|
|
@@ -109,6 +103,10 @@ const apply = exports.apply = {
|
|
|
109
103
|
'--language=[langCode]': {
|
|
110
104
|
desc: `Language Codes. One of: Comma Separated values of ${_types.LanguageTypes.French} | ${_types.LanguageTypes.US} | ${_types.LanguageTypes.German} | ${_types.LanguageTypes.Portugese}`,
|
|
111
105
|
type: 'string'
|
|
106
|
+
},
|
|
107
|
+
'--subresource=[name]': {
|
|
108
|
+
desc: 'Name of the 1 subresource to update. Will prevent main resource and all other subresources from being updated.',
|
|
109
|
+
type: 'string'
|
|
112
110
|
}
|
|
113
111
|
}
|
|
114
112
|
};
|
|
@@ -130,6 +130,7 @@ class ApiServerClient {
|
|
|
130
130
|
* @param {Object} args function expects arguments as an object
|
|
131
131
|
* @param {GenericResource} args.resource resource input (not the APIs response)
|
|
132
132
|
* @param {string} args.resourceName resource name
|
|
133
|
+
* @param {string} args.subResourceName subresource name
|
|
133
134
|
* @param {ResourceDefinition} args.resourceDef resource definition
|
|
134
135
|
* @param {string} [args.scopeName] scope name
|
|
135
136
|
* @param {ResourceDefinition} [args.scopeDef] scope definition
|
|
@@ -140,6 +141,7 @@ class ApiServerClient {
|
|
|
140
141
|
async generateSubResourcesRequests({
|
|
141
142
|
resource,
|
|
142
143
|
resourceName,
|
|
144
|
+
subResourceName,
|
|
143
145
|
resourceDef,
|
|
144
146
|
scopeDef,
|
|
145
147
|
scopeName,
|
|
@@ -162,7 +164,12 @@ class ApiServerClient {
|
|
|
162
164
|
version
|
|
163
165
|
});
|
|
164
166
|
const knownSubResourcesNames = (_resourceDef$spec$sub = (_resourceDef$spec$sub2 = resourceDef.spec.subResources) === null || _resourceDef$spec$sub2 === void 0 ? void 0 : _resourceDef$spec$sub2.names) !== null && _resourceDef$spec$sub !== void 0 ? _resourceDef$spec$sub : [];
|
|
165
|
-
const foundSubResources = (0, _pickBy.default)(resource, (_, key) =>
|
|
167
|
+
const foundSubResources = (0, _pickBy.default)(resource, (_, key) => {
|
|
168
|
+
if (key.startsWith('x-') || knownSubResourcesNames.includes(key)) {
|
|
169
|
+
return !subResourceName || subResourceName === key;
|
|
170
|
+
}
|
|
171
|
+
return false;
|
|
172
|
+
});
|
|
166
173
|
if (language) {
|
|
167
174
|
const langSubResourcesNames = (0, _utils.createLanguageSubresourceNames)(language);
|
|
168
175
|
langSubResourcesNames.forEach(name => {
|
|
@@ -186,14 +193,15 @@ class ApiServerClient {
|
|
|
186
193
|
});
|
|
187
194
|
}
|
|
188
195
|
return (0, _isEmpty.default)(foundSubResources) ? null : Object.keys(foundSubResources).map(key => {
|
|
189
|
-
return
|
|
190
|
-
[key]: foundSubResources[key]
|
|
191
|
-
})
|
|
192
|
-
// note: "catch" will not be needed if APIs will return the sub-resource name in error response
|
|
193
|
-
.catch(err => Promise.reject({
|
|
196
|
+
return {
|
|
194
197
|
name: key,
|
|
195
|
-
|
|
196
|
-
|
|
198
|
+
operation: () => service.put(`${baseUrl}/${key}?fields=${key}`, {
|
|
199
|
+
[key]: foundSubResources[key]
|
|
200
|
+
}).catch(err => Promise.reject({
|
|
201
|
+
name: key,
|
|
202
|
+
requestError: err
|
|
203
|
+
}))
|
|
204
|
+
};
|
|
197
205
|
});
|
|
198
206
|
}
|
|
199
207
|
|
|
@@ -207,34 +215,44 @@ class ApiServerClient {
|
|
|
207
215
|
*/
|
|
208
216
|
async resolveSubResourcesRequests(mainResourceResponse, pendingCalls) {
|
|
209
217
|
var _result$error2, _result$error3;
|
|
210
|
-
if (!pendingCalls)
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
218
|
+
if (!pendingCalls) {
|
|
219
|
+
return {
|
|
220
|
+
data: mainResourceResponse,
|
|
221
|
+
error: null
|
|
222
|
+
};
|
|
223
|
+
}
|
|
214
224
|
log(`resolving sub-resources, pending calls = ${pendingCalls.length}.`);
|
|
215
225
|
// note: errors set to an empty array initially, will reset to null if no errors found
|
|
216
226
|
const result = {
|
|
217
227
|
data: null,
|
|
228
|
+
updatedSubResourceNames: [],
|
|
218
229
|
error: []
|
|
219
230
|
};
|
|
220
|
-
const subResourcesCombined = (await Promise.allSettled(pendingCalls.map(
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
231
|
+
const subResourcesCombined = (await Promise.allSettled(pendingCalls.map(async next => {
|
|
232
|
+
var _result$updatedSubRes;
|
|
233
|
+
const opResult = await next.operation();
|
|
234
|
+
(_result$updatedSubRes = result.updatedSubResourceNames) === null || _result$updatedSubRes === void 0 ? void 0 : _result$updatedSubRes.push(next.name);
|
|
235
|
+
return opResult;
|
|
236
|
+
}))).reduce((a, c) => {
|
|
237
|
+
var _c$reason$requestErro;
|
|
238
|
+
if (c.status === 'fulfilled') {
|
|
239
|
+
return {
|
|
240
|
+
...a,
|
|
241
|
+
...c.value
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
// expecting only a valid ApiServer error response here
|
|
245
|
+
// re-throw if something different, so it should be handled by command's catch block.
|
|
246
|
+
if ((_c$reason$requestErro = c.reason.requestError) !== null && _c$reason$requestErro !== void 0 && _c$reason$requestErro.errors && Array.isArray(c.reason.requestError.errors)) {
|
|
247
|
+
var _result$error;
|
|
248
|
+
// note: if APIs are going to return more details this details override will not be needed, just push as in other methods
|
|
249
|
+
(_result$error = result.error) === null || _result$error === void 0 ? void 0 : _result$error.push(...c.reason.requestError.errors.map(e => ({
|
|
250
|
+
...e,
|
|
251
|
+
detail: `sub-resource "${c.reason.name}" ${e.detail}`
|
|
252
|
+
})));
|
|
236
253
|
return a;
|
|
237
254
|
}
|
|
255
|
+
throw c.reason;
|
|
238
256
|
}, {});
|
|
239
257
|
result.data = (0, _assign.default)(mainResourceResponse, subResourcesCombined);
|
|
240
258
|
if (!((_result$error2 = result.error) !== null && _result$error2 !== void 0 && _result$error2.length)) result.error = null; // reset errors to null if none encountered
|
|
@@ -245,8 +263,8 @@ class ApiServerClient {
|
|
|
245
263
|
/**
|
|
246
264
|
* Check if resources are deleted by making a fetch call for the resources
|
|
247
265
|
*/
|
|
248
|
-
checkForResources(
|
|
249
|
-
return Promise.all(
|
|
266
|
+
checkForResources(resources, sortedDefsArray) {
|
|
267
|
+
return Promise.all(resources.map(resource => {
|
|
250
268
|
var _resource$metadata2, _resource$metadata3, _resource$metadata3$s;
|
|
251
269
|
const resourceDef = sortedDefsArray.find(def => {
|
|
252
270
|
var _def$spec$scope, _resource$metadata, _resource$metadata$sc;
|
|
@@ -282,7 +300,7 @@ class ApiServerClient {
|
|
|
282
300
|
withSubResources = true,
|
|
283
301
|
language
|
|
284
302
|
}) {
|
|
285
|
-
log(`createResource, spec.kind = ${resourceDef.spec.kind}, name = ${resource.name}
|
|
303
|
+
log(`createResource, spec.kind = ${resourceDef.spec.kind}, name = ${resource.name}`);
|
|
286
304
|
const result = {
|
|
287
305
|
data: null,
|
|
288
306
|
error: null,
|
|
@@ -337,7 +355,9 @@ class ApiServerClient {
|
|
|
337
355
|
result.error = e.errors;
|
|
338
356
|
} else throw e;
|
|
339
357
|
}
|
|
340
|
-
if (!!result.data)
|
|
358
|
+
if (!!result.data) {
|
|
359
|
+
result.data = (0, _utils.sanitizeMetadata)(result.data);
|
|
360
|
+
}
|
|
341
361
|
return result;
|
|
342
362
|
}
|
|
343
363
|
|
|
@@ -351,7 +371,7 @@ class ApiServerClient {
|
|
|
351
371
|
scopeDef,
|
|
352
372
|
scopeName,
|
|
353
373
|
version = ApiServerVersions.v1alpha1,
|
|
354
|
-
|
|
374
|
+
subResourceName,
|
|
355
375
|
language
|
|
356
376
|
}) {
|
|
357
377
|
log(`updateResource, spec.kind = ${resourceDef.spec.kind}, name = ${resource.name}`);
|
|
@@ -360,32 +380,15 @@ class ApiServerClient {
|
|
|
360
380
|
error: null,
|
|
361
381
|
pending: null
|
|
362
382
|
};
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
if (language) {
|
|
372
|
-
pendingSubResources = await this.generateSubResourcesRequests({
|
|
373
|
-
resource,
|
|
374
|
-
resourceName: resource.name,
|
|
375
|
-
resourceDef,
|
|
376
|
-
scopeDef,
|
|
377
|
-
scopeName,
|
|
378
|
-
version,
|
|
379
|
-
createAction: false,
|
|
380
|
-
language
|
|
381
|
-
});
|
|
382
|
-
result.data = (0, _utils.buildGenericResource)({
|
|
383
|
-
resourceName: resource.name,
|
|
384
|
-
resourceDef: resourceDef,
|
|
385
|
-
scopeName: scopeName
|
|
383
|
+
const canUpdateMainResource = !language && !subResourceName;
|
|
384
|
+
if (canUpdateMainResource) {
|
|
385
|
+
try {
|
|
386
|
+
const service = await (0, _dataService.dataService)({
|
|
387
|
+
baseUrl: this.baseUrl,
|
|
388
|
+
region: this.region,
|
|
389
|
+
account: this.account,
|
|
390
|
+
team: this.team
|
|
386
391
|
});
|
|
387
|
-
result.pending = pendingSubResources;
|
|
388
|
-
} else {
|
|
389
392
|
const url = this.buildResourceBaseUrl({
|
|
390
393
|
resourceDef,
|
|
391
394
|
resourceName: resource.name,
|
|
@@ -393,37 +396,46 @@ class ApiServerClient {
|
|
|
393
396
|
scopeName,
|
|
394
397
|
version
|
|
395
398
|
});
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
createAction: false,
|
|
404
|
-
version
|
|
405
|
-
});
|
|
406
|
-
if (withSubResources) {
|
|
407
|
-
const {
|
|
408
|
-
data: subResData,
|
|
409
|
-
error: subResError
|
|
410
|
-
} = await this.resolveSubResourcesRequests(response, pendingSubResources);
|
|
411
|
-
result.data = subResData;
|
|
412
|
-
result.error = subResError;
|
|
399
|
+
result.data = await service.put(url, (0, _utils.sanitizeMetadata)(resource));
|
|
400
|
+
} catch (e) {
|
|
401
|
+
log('updateResource, error', e);
|
|
402
|
+
// expecting only a valid ApiServer error response here
|
|
403
|
+
// re-throw if something different, so it should be handled by command's catch block.
|
|
404
|
+
if (e.errors && Array.isArray(e.errors)) {
|
|
405
|
+
result.error = e.errors;
|
|
413
406
|
} else {
|
|
414
|
-
|
|
415
|
-
result.pending = pendingSubResources;
|
|
407
|
+
throw e;
|
|
416
408
|
}
|
|
409
|
+
;
|
|
417
410
|
}
|
|
418
|
-
} catch (e) {
|
|
419
|
-
log('updateResource, error', e);
|
|
420
|
-
// expecting only a valid ApiServer error response here
|
|
421
|
-
// re-throw if something different, so it should be handled by command's catch block.
|
|
422
|
-
if (e.errors && Array.isArray(e.errors)) {
|
|
423
|
-
result.error = e.errors;
|
|
424
|
-
} else throw e;
|
|
425
411
|
}
|
|
426
|
-
|
|
412
|
+
result.pending = await this.generateSubResourcesRequests({
|
|
413
|
+
resource,
|
|
414
|
+
resourceName: resource.name,
|
|
415
|
+
subResourceName,
|
|
416
|
+
resourceDef,
|
|
417
|
+
scopeDef,
|
|
418
|
+
scopeName,
|
|
419
|
+
version,
|
|
420
|
+
createAction: false,
|
|
421
|
+
language
|
|
422
|
+
});
|
|
423
|
+
if (!result.data && !result.pending && subResourceName) {
|
|
424
|
+
result.error = [{
|
|
425
|
+
status: 0,
|
|
426
|
+
title: '',
|
|
427
|
+
detail: `sub-resource "${subResourceName}" not found.`,
|
|
428
|
+
meta: {
|
|
429
|
+
instanceId: '',
|
|
430
|
+
tenantId: '',
|
|
431
|
+
authenticatedUserId: '',
|
|
432
|
+
transactionId: ''
|
|
433
|
+
}
|
|
434
|
+
}];
|
|
435
|
+
}
|
|
436
|
+
if (result.data) {
|
|
437
|
+
result.data = (0, _utils.sanitizeMetadata)(result.data);
|
|
438
|
+
}
|
|
427
439
|
return result;
|
|
428
440
|
}
|
|
429
441
|
|
|
@@ -730,16 +742,14 @@ class ApiServerClient {
|
|
|
730
742
|
*/
|
|
731
743
|
async bulkCreate(resources, sortedDefsMap, version) {
|
|
732
744
|
log(`bulk create`);
|
|
733
|
-
// sort() is modifying the existing array so cloning it before use.
|
|
734
745
|
const sortedDefsArray = Array.from(sortedDefsMap.values());
|
|
735
|
-
const sortedResources = [...resources].sort((0, _utils.compareResourcesByKindAsc)(sortedDefsArray));
|
|
736
746
|
const pendingSubResources = [];
|
|
737
747
|
const bulkResult = {
|
|
738
748
|
success: [],
|
|
739
749
|
error: [],
|
|
740
750
|
warning: []
|
|
741
751
|
};
|
|
742
|
-
for (const resource of
|
|
752
|
+
for (const resource of resources) {
|
|
743
753
|
var _resource$metadata7, _resource$metadata8, _resource$metadata8$s;
|
|
744
754
|
const resourceDef = sortedDefsArray.find(def => {
|
|
745
755
|
var _def$spec$scope2, _resource$metadata4, _resource$metadata4$s;
|
|
@@ -768,8 +778,7 @@ class ApiServerClient {
|
|
|
768
778
|
resourceDef,
|
|
769
779
|
scopeDef,
|
|
770
780
|
scopeName,
|
|
771
|
-
version
|
|
772
|
-
withSubResources: false
|
|
781
|
+
version
|
|
773
782
|
});
|
|
774
783
|
if (res.data && !res.error) {
|
|
775
784
|
// note: bulk operation requires creation of sub-resources after all main resources created
|
|
@@ -821,35 +830,19 @@ class ApiServerClient {
|
|
|
821
830
|
* sorting of the array of resources with "compareResourcesByKindAsc".
|
|
822
831
|
* @param resources array of resources to create
|
|
823
832
|
*/
|
|
824
|
-
async bulkCreateOrUpdate(resources, sortedDefsMap, language, version) {
|
|
833
|
+
async bulkCreateOrUpdate(resources, sortedDefsMap, language, subResourceName, version) {
|
|
825
834
|
log(`bulk create or update`);
|
|
826
|
-
// sort() is modifying the existing array so cloning it before use.
|
|
827
835
|
const sortedDefsArray = Array.from(sortedDefsMap.values());
|
|
828
|
-
const
|
|
829
|
-
const
|
|
830
|
-
|
|
831
|
-
success: [],
|
|
832
|
-
error: [],
|
|
833
|
-
warning: []
|
|
834
|
-
},
|
|
835
|
-
updated: {
|
|
836
|
-
success: [],
|
|
837
|
-
error: []
|
|
838
|
-
}
|
|
839
|
-
};
|
|
840
|
-
const pendingSubResources = {
|
|
841
|
-
created: [],
|
|
842
|
-
updated: []
|
|
843
|
-
};
|
|
844
|
-
for (const resource of sortedResources) {
|
|
845
|
-
var _resource$metadata12, _resource$metadata13, _resource$metadata13$;
|
|
836
|
+
const applyResults = [];
|
|
837
|
+
for (const resource of resources) {
|
|
838
|
+
var _resource$metadata12, _resource$metadata13, _resource$metadata13$, _resource$name2, _singleResult$error, _applyResult$error3;
|
|
846
839
|
const resourceDef = sortedDefsArray.find(def => {
|
|
847
840
|
var _def$spec$scope3, _resource$metadata9, _resource$metadata9$s;
|
|
848
841
|
return def.spec.kind === resource.kind && ((_def$spec$scope3 = def.spec.scope) === null || _def$spec$scope3 === void 0 ? void 0 : _def$spec$scope3.kind) === ((_resource$metadata9 = resource.metadata) === null || _resource$metadata9 === void 0 ? void 0 : (_resource$metadata9$s = _resource$metadata9.scope) === null || _resource$metadata9$s === void 0 ? void 0 : _resource$metadata9$s.kind);
|
|
849
842
|
});
|
|
850
843
|
// the check below is already happening when loading the specs but checking again just in case.
|
|
851
844
|
if (!resourceDef) {
|
|
852
|
-
var _resource$metadata10, _resource$metadata10
|
|
845
|
+
var _resource$metadata10, _resource$metadata10$, _resource$name;
|
|
853
846
|
let errorMessage = `No resource definition found for "kind/${resource.kind}"`;
|
|
854
847
|
if (!!((_resource$metadata10 = resource.metadata) !== null && _resource$metadata10 !== void 0 && (_resource$metadata10$ = _resource$metadata10.scope) !== null && _resource$metadata10$ !== void 0 && _resource$metadata10$.kind)) {
|
|
855
848
|
var _resource$metadata11, _resource$metadata11$;
|
|
@@ -857,15 +850,18 @@ class ApiServerClient {
|
|
|
857
850
|
} else {
|
|
858
851
|
errorMessage += ' with no scope.';
|
|
859
852
|
}
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
853
|
+
applyResults.push({
|
|
854
|
+
error: [{
|
|
855
|
+
name: (_resource$name = resource.name) !== null && _resource$name !== void 0 ? _resource$name : 'Unknown name',
|
|
856
|
+
kind: resource.kind,
|
|
857
|
+
error: new Error(errorMessage)
|
|
858
|
+
}]
|
|
864
859
|
});
|
|
865
860
|
continue;
|
|
866
861
|
}
|
|
867
862
|
const scopeDef = !!((_resource$metadata12 = resource.metadata) !== null && _resource$metadata12 !== void 0 && _resource$metadata12.scope) ? sortedDefsArray.find(def => def.spec.kind === resource.metadata.scope.kind && !def.spec.scope) : undefined;
|
|
868
863
|
const scopeName = (_resource$metadata13 = resource.metadata) === null || _resource$metadata13 === void 0 ? void 0 : (_resource$metadata13$ = _resource$metadata13.scope) === null || _resource$metadata13$ === void 0 ? void 0 : _resource$metadata13$.name;
|
|
864
|
+
const resourceName = (_resource$name2 = resource.name) !== null && _resource$name2 !== void 0 ? _resource$name2 : 'Unknown name';
|
|
869
865
|
|
|
870
866
|
// only making getResource call if resource has a name
|
|
871
867
|
let getResult = resource.name ? await this.getResourceByName({
|
|
@@ -876,73 +872,29 @@ class ApiServerClient {
|
|
|
876
872
|
}) : null;
|
|
877
873
|
|
|
878
874
|
// Create new resources first
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
875
|
+
let singleResult;
|
|
876
|
+
const shouldCreate = !getResult || !!(getResult !== null && getResult !== void 0 && getResult.error) && getResult.error[0].status === 404;
|
|
877
|
+
if (shouldCreate) {
|
|
878
|
+
// Resource not found. Create a new resource.
|
|
879
|
+
singleResult = await this.createResource({
|
|
883
880
|
resource,
|
|
884
881
|
resourceDef,
|
|
885
882
|
scopeDef,
|
|
886
883
|
scopeName,
|
|
887
884
|
version,
|
|
888
|
-
withSubResources: false,
|
|
889
885
|
language
|
|
890
886
|
});
|
|
891
|
-
if (res.data && !res.error) {
|
|
892
|
-
// note: bulk operation requires creation of sub-resources after all main resources created
|
|
893
|
-
// since a sub-resource might have a reference to another resource.
|
|
894
|
-
if (!!res.pending) {
|
|
895
|
-
var _res$warning2;
|
|
896
|
-
pendingSubResources.created.push({
|
|
897
|
-
mainResult: res.data,
|
|
898
|
-
pendingCalls: res.pending,
|
|
899
|
-
withWarning: (_res$warning2 = res.warning) !== null && _res$warning2 !== void 0 ? _res$warning2 : false
|
|
900
|
-
});
|
|
901
|
-
} else {
|
|
902
|
-
var _bulkResult$created$w;
|
|
903
|
-
if (res.warning) (_bulkResult$created$w = bulkResult.created.warning) === null || _bulkResult$created$w === void 0 ? void 0 : _bulkResult$created$w.push(res.data);else bulkResult.created.success.push(res.data);
|
|
904
|
-
}
|
|
905
|
-
} else if (res.error) {
|
|
906
|
-
for (const nextError of res.error) {
|
|
907
|
-
bulkResult.created.error.push({
|
|
908
|
-
name: resource.name || 'Unknown name',
|
|
909
|
-
kind: resource.kind,
|
|
910
|
-
error: nextError
|
|
911
|
-
});
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
887
|
} else if (getResult.data) {
|
|
915
|
-
// Resource found
|
|
916
|
-
|
|
888
|
+
// Resource found. Update the existing resource.
|
|
889
|
+
singleResult = await this.updateResource({
|
|
917
890
|
resource: resource,
|
|
918
|
-
//we know that the resource exists and has a name if we've gotten to this point in th control flow
|
|
919
891
|
resourceDef,
|
|
920
892
|
scopeDef,
|
|
921
893
|
scopeName,
|
|
922
894
|
version,
|
|
923
|
-
|
|
924
|
-
|
|
895
|
+
language,
|
|
896
|
+
subResourceName
|
|
925
897
|
});
|
|
926
|
-
if (res.data && !res.error) {
|
|
927
|
-
if (!!res.pending) {
|
|
928
|
-
var _res$warning3;
|
|
929
|
-
pendingSubResources.updated.push({
|
|
930
|
-
mainResult: res.data,
|
|
931
|
-
pendingCalls: res.pending,
|
|
932
|
-
withWarning: (_res$warning3 = res.warning) !== null && _res$warning3 !== void 0 ? _res$warning3 : false
|
|
933
|
-
});
|
|
934
|
-
} else {
|
|
935
|
-
bulkResult.updated.success.push(res.data);
|
|
936
|
-
}
|
|
937
|
-
} else if (res.error) {
|
|
938
|
-
for (const nextError of res.error) {
|
|
939
|
-
bulkResult.updated.error.push({
|
|
940
|
-
name: resource.name,
|
|
941
|
-
kind: resource.kind,
|
|
942
|
-
error: nextError
|
|
943
|
-
});
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
898
|
} else {
|
|
947
899
|
// Something is going wrong - more than one error in api server response, re-throw in the same
|
|
948
900
|
// structure as ApiServerErrorResponse so renderer.anyError can pick this up.
|
|
@@ -950,40 +902,54 @@ class ApiServerClient {
|
|
|
950
902
|
errors: getResult.error
|
|
951
903
|
};
|
|
952
904
|
}
|
|
953
|
-
}
|
|
954
905
|
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
906
|
+
// Store the results of the above create/update.
|
|
907
|
+
const applyResult = {
|
|
908
|
+
data: singleResult.data,
|
|
909
|
+
wasCreated: shouldCreate && !!singleResult.data,
|
|
910
|
+
wasAutoNamed: shouldCreate && singleResult.warning,
|
|
911
|
+
wasMainResourceChanged: !!singleResult.data,
|
|
912
|
+
error: []
|
|
913
|
+
};
|
|
914
|
+
(_singleResult$error = singleResult.error) === null || _singleResult$error === void 0 ? void 0 : _singleResult$error.forEach(nextError => {
|
|
915
|
+
var _applyResult$error;
|
|
916
|
+
return (_applyResult$error = applyResult.error) === null || _applyResult$error === void 0 ? void 0 : _applyResult$error.push({
|
|
917
|
+
name: resourceName,
|
|
918
|
+
kind: resource.kind,
|
|
919
|
+
error: nextError
|
|
920
|
+
});
|
|
921
|
+
});
|
|
922
|
+
applyResults.push(applyResult);
|
|
923
|
+
|
|
924
|
+
// Create or update any pending subresources.
|
|
925
|
+
if (singleResult.pending) {
|
|
926
|
+
var _singleResult$data, _subResResult$error;
|
|
927
|
+
const pendingData = (_singleResult$data = singleResult.data) !== null && _singleResult$data !== void 0 ? _singleResult$data : (0, _utils.sanitizeMetadata)((0, _utils.buildGenericResource)({
|
|
928
|
+
resourceName: resourceName,
|
|
929
|
+
resourceDef: resourceDef,
|
|
930
|
+
scopeName: scopeName
|
|
931
|
+
}));
|
|
932
|
+
const subResResult = await this.resolveSubResourcesRequests(pendingData, singleResult.pending);
|
|
933
|
+
if (subResResult.data) {
|
|
934
|
+
applyResult.data = subResResult.data;
|
|
968
935
|
}
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
} else if (subResResult.error) {
|
|
977
|
-
for (const nextError of subResResult.error) {
|
|
978
|
-
bulkResult.created.error.push({
|
|
979
|
-
name: p.mainResult.name,
|
|
980
|
-
kind: p.mainResult.kind,
|
|
981
|
-
error: nextError
|
|
936
|
+
applyResult.updatedSubResourceNames = subResResult.updatedSubResourceNames;
|
|
937
|
+
(_subResResult$error = subResResult.error) === null || _subResResult$error === void 0 ? void 0 : _subResResult$error.forEach(error => {
|
|
938
|
+
var _applyResult$error2;
|
|
939
|
+
return (_applyResult$error2 = applyResult.error) === null || _applyResult$error2 === void 0 ? void 0 : _applyResult$error2.push({
|
|
940
|
+
name: resourceName,
|
|
941
|
+
kind: resource.kind,
|
|
942
|
+
error: error
|
|
982
943
|
});
|
|
983
|
-
}
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
// Delete the result's error array if it is empty.
|
|
948
|
+
if (!((_applyResult$error3 = applyResult.error) !== null && _applyResult$error3 !== void 0 && _applyResult$error3.length)) {
|
|
949
|
+
delete applyResult.error;
|
|
984
950
|
}
|
|
985
951
|
}
|
|
986
|
-
return
|
|
952
|
+
return applyResults;
|
|
987
953
|
}
|
|
988
954
|
|
|
989
955
|
/**
|
|
@@ -993,14 +959,12 @@ class ApiServerClient {
|
|
|
993
959
|
*/
|
|
994
960
|
async bulkDelete(resources, sortedDefsMap, wait, forceDelete, version) {
|
|
995
961
|
log(`bulk delete`);
|
|
996
|
-
// sort() is modifying the existing array so cloning it before use.
|
|
997
962
|
const sortedDefsArray = Array.from(sortedDefsMap.values());
|
|
998
|
-
const sortedResources = [...resources].sort((0, _utils.compareResourcesByKindDesc)(sortedDefsArray));
|
|
999
963
|
const bulkResult = {
|
|
1000
964
|
success: [],
|
|
1001
965
|
error: []
|
|
1002
966
|
};
|
|
1003
|
-
for (const resource of
|
|
967
|
+
for (const resource of resources) {
|
|
1004
968
|
try {
|
|
1005
969
|
var _resource$metadata15, _resource$metadata16, _resource$metadata16$;
|
|
1006
970
|
const resourceDef = sortedDefsArray.find(def => {
|
|
@@ -1064,11 +1028,11 @@ class ApiServerClient {
|
|
|
1064
1028
|
}
|
|
1065
1029
|
if (wait) {
|
|
1066
1030
|
let pendingResources = [];
|
|
1067
|
-
pendingResources = await this.checkForResources(
|
|
1031
|
+
pendingResources = await this.checkForResources(resources, sortedDefsArray);
|
|
1068
1032
|
const pendingDeletingResource = pendingResources.some(res => res === null || res === void 0 ? void 0 : res.data);
|
|
1069
1033
|
if (pendingDeletingResource) {
|
|
1070
1034
|
setTimeout(async () => {
|
|
1071
|
-
pendingResources = await this.checkForResources(
|
|
1035
|
+
pendingResources = await this.checkForResources(resources, sortedDefsArray);
|
|
1072
1036
|
}, _types.WAIT_TIMEOUT);
|
|
1073
1037
|
const stillPending = pendingResources.some(res => res === null || res === void 0 ? void 0 : res.data);
|
|
1074
1038
|
if (stillPending) {
|
package/dist/common/Renderer.js
CHANGED
|
@@ -118,6 +118,22 @@ class Renderer {
|
|
|
118
118
|
return `"${resource.kind}/${resource.name}"${!!((_resource$metadata = resource.metadata) !== null && _resource$metadata !== void 0 && _resource$metadata.scope) ? ` in the scope "${resource.metadata.scope.kind}/${resource.metadata.scope.name}"` : ``}`;
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
/**
|
|
122
|
+
* A helper returning `"<kind>/<name>" subresource "<subResourceNaem>" in the scope "<scopeKind>/<scopeName>"`
|
|
123
|
+
* string used to print bulk results (in "bulkResult" or "bulkCreateOrUpdateResult") or individually (see the "delete" cmd)
|
|
124
|
+
* @param {GenericResource} resource resource for witch the string should be created
|
|
125
|
+
* @param {string} subResourceName of the subresource that was updated
|
|
126
|
+
* @returns {string}
|
|
127
|
+
*/
|
|
128
|
+
subResourceAndScopeKinds(resource, subResourceName) {
|
|
129
|
+
var _resource$metadata2;
|
|
130
|
+
let message = `"${resource.kind}/${resource.name}" subresource "${subResourceName}"`;
|
|
131
|
+
if ((_resource$metadata2 = resource.metadata) !== null && _resource$metadata2 !== void 0 && _resource$metadata2.scope) {
|
|
132
|
+
message += ` in the scope "${resource.metadata.scope.kind}/${resource.metadata.scope.name}"`;
|
|
133
|
+
}
|
|
134
|
+
return message;
|
|
135
|
+
}
|
|
136
|
+
|
|
121
137
|
/**
|
|
122
138
|
* Render bulk call result.
|
|
123
139
|
* If error is happening - render as simple output (even if "output" param has been provided)
|
|
@@ -147,35 +163,35 @@ class Renderer {
|
|
|
147
163
|
/**
|
|
148
164
|
* Render bulk "apply" result (with different success messages).
|
|
149
165
|
* If error is happening - render as simple output (even if "output" param has been provided)
|
|
150
|
-
* @param
|
|
151
|
-
* @param createSuccessMsg message to display for each created "kind/name"
|
|
152
|
-
* @param updateSuccessMsg message to display for each updated "kind/name"
|
|
166
|
+
* @param results array of responses from createOrUpdate ApiServerClient
|
|
153
167
|
*/
|
|
154
|
-
bulkCreateOrUpdateResult(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
var _bulkResult$created$w;
|
|
163
|
-
(_bulkResult$created$w = bulkResult.created.warning) === null || _bulkResult$created$w === void 0 ? void 0 : _bulkResult$created$w.forEach(r => this.warning(`${this.resourceAndScopeKinds(r)} ${createWarningMsg}`));
|
|
164
|
-
bulkResult.created.success.forEach(r => this.success(`${this.resourceAndScopeKinds(r)} ${createSuccessMsg}`));
|
|
165
|
-
bulkResult.updated.success.forEach(r => this.success(`${this.resourceAndScopeKinds(r)} ${updateSuccessMsg}`));
|
|
166
|
-
bulkResultCombined.error.forEach(r => this.anyError(r.error, `"${r.kind}/${r.name}" `, true));
|
|
167
|
-
} else if (this.output) {
|
|
168
|
-
var _bulkResult$created$w2;
|
|
169
|
-
let results = bulkResultCombined.success;
|
|
170
|
-
if ((_bulkResult$created$w2 = bulkResult.created.warning) !== null && _bulkResult$created$w2 !== void 0 && _bulkResult$created$w2.length) {
|
|
171
|
-
results = bulkResult.created.warning.concat(results);
|
|
172
|
-
}
|
|
173
|
-
(0, _resultsRenderers.renderResponse)(this._console, results, this.output);
|
|
168
|
+
bulkCreateOrUpdateResult(results) {
|
|
169
|
+
if (results.every(r => {
|
|
170
|
+
var _r$error$length, _r$error;
|
|
171
|
+
return ((_r$error$length = (_r$error = r.error) === null || _r$error === void 0 ? void 0 : _r$error.length) !== null && _r$error$length !== void 0 ? _r$error$length : 0) === 0;
|
|
172
|
+
}) && this.output) {
|
|
173
|
+
// Output responses as JSON/YAML, but only if no error responses were received.
|
|
174
|
+
const dataArray = results.map(r => r.data).filter(r => r != null);
|
|
175
|
+
(0, _resultsRenderers.renderResponse)(this._console, dataArray, this.output);
|
|
174
176
|
} else {
|
|
175
|
-
|
|
176
|
-
(
|
|
177
|
-
|
|
178
|
-
|
|
177
|
+
// Log results.
|
|
178
|
+
for (const result of results) {
|
|
179
|
+
var _result$error;
|
|
180
|
+
if (result.data) {
|
|
181
|
+
if (result.wasAutoNamed) {
|
|
182
|
+
this.warning(this.resourceAndScopeKinds(result.data) + ' was created with an autogenerated logical name.');
|
|
183
|
+
} else if (result.wasCreated) {
|
|
184
|
+
this.success(this.resourceAndScopeKinds(result.data) + ' has successfully been created.');
|
|
185
|
+
} else if (result.wasMainResourceChanged) {
|
|
186
|
+
this.success(this.resourceAndScopeKinds(result.data) + ' has successfully been updated.');
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
(_result$error = result.error) === null || _result$error === void 0 ? void 0 : _result$error.forEach(r => this.anyError(r.error, `"${r.kind}/${r.name}" `, true));
|
|
190
|
+
if (!result.wasMainResourceChanged && result.data) {
|
|
191
|
+
var _result$updatedSubRes;
|
|
192
|
+
(_result$updatedSubRes = result.updatedSubResourceNames) === null || _result$updatedSubRes === void 0 ? void 0 : _result$updatedSubRes.forEach(name => this.success(this.subResourceAndScopeKinds(result.data, name) + ' has successfully been updated.'));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
179
195
|
}
|
|
180
196
|
}
|
|
181
197
|
renderGetResults(bulkResultsArray, successMsg, langDef) {
|