@codiac.io/codiac-cli 1.2.154 → 1.2.155

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +5 -3753
  2. package/lib/commands/csp/logout.js +3 -2
  3. package/lib/commands/csp/logout.js.map +1 -1
  4. package/lib/k8s-command-base.d.ts +15 -25
  5. package/lib/k8s-command-base.js +20 -92
  6. package/lib/k8s-command-base.js.map +1 -1
  7. package/lib/relay/data/aws-regions.d.ts +6 -0
  8. package/lib/relay/data/aws-regions.js +32 -32
  9. package/lib/relay/data/aws-regions.js.map +1 -1
  10. package/lib/uilogic/cloud-resource-configurators/aws-k8s-versions.d.ts +11 -0
  11. package/lib/uilogic/cloud-resource-configurators/aws-k8s-versions.js +14 -13
  12. package/lib/uilogic/cloud-resource-configurators/aws-k8s-versions.js.map +1 -1
  13. package/lib/uilogic/cloud-resource-configurators/aws-node-types.d.ts +1 -33
  14. package/lib/uilogic/cloud-resource-configurators/aws-node-types.js +2 -3712
  15. package/lib/uilogic/cloud-resource-configurators/aws-node-types.js.map +1 -1
  16. package/oclif.manifest.json +1 -1
  17. package/package.json +1 -1
  18. package/lib/api-clients/common/api-user-creds.d.ts +0 -7
  19. package/lib/api-clients/common/api-user-creds.js +0 -19
  20. package/lib/api-clients/common/api-user-creds.js.map +0 -1
  21. package/lib/api-clients/common/config-loader.d.ts +0 -6
  22. package/lib/api-clients/common/config-loader.js +0 -19
  23. package/lib/api-clients/common/config-loader.js.map +0 -1
  24. package/lib/api-clients/common/security/auth-constants.d.ts +0 -15
  25. package/lib/api-clients/common/security/auth-constants.js +0 -22
  26. package/lib/api-clients/common/security/auth-constants.js.map +0 -1
  27. package/lib/api-clients/common/security/i-auth-client.d.ts +0 -44
  28. package/lib/api-clients/common/security/i-auth-client.js +0 -3
  29. package/lib/api-clients/common/security/i-auth-client.js.map +0 -1
  30. package/lib/api-clients/common/security/rest-client-base-with-auth.d.ts +0 -84
  31. package/lib/api-clients/common/security/rest-client-base-with-auth.js +0 -361
  32. package/lib/api-clients/common/security/rest-client-base-with-auth.js.map +0 -1
  33. package/lib/api-clients/common/security/token-holder.d.ts +0 -13
  34. package/lib/api-clients/common/security/token-holder.js +0 -18
  35. package/lib/api-clients/common/security/token-holder.js.map +0 -1
  36. package/lib/api-clients/common/utils.d.ts +0 -23
  37. package/lib/api-clients/common/utils.js +0 -83
  38. package/lib/api-clients/common/utils.js.map +0 -1
  39. package/lib/api-clients/contracts/index.d.ts +0 -1
  40. package/lib/api-clients/contracts/index.js +0 -5
  41. package/lib/api-clients/contracts/index.js.map +0 -1
  42. package/lib/api-clients/gen/client-config.d.ts +0 -10
  43. package/lib/api-clients/gen/client-config.js +0 -29
  44. package/lib/api-clients/gen/client-config.js.map +0 -1
  45. package/lib/api-clients/gen/client.d.ts +0 -45
  46. package/lib/api-clients/gen/client.js +0 -331
  47. package/lib/api-clients/gen/client.js.map +0 -1
  48. package/lib/api-clients/gen/contracts.d.ts +0 -2529
  49. package/lib/api-clients/gen/contracts.js +0 -370
  50. package/lib/api-clients/gen/contracts.js.map +0 -1
  51. package/lib/api-clients/gen/endpoints.d.ts +0 -3
  52. package/lib/api-clients/gen/endpoints.js +0 -3150
  53. package/lib/api-clients/gen/endpoints.js.map +0 -1
  54. package/lib/api-clients/index.d.ts +0 -2
  55. package/lib/api-clients/index.js +0 -6
  56. package/lib/api-clients/index.js.map +0 -1
  57. package/lib/apis/codiac-api/common/security/rest-client-base-with-auth.d.ts +0 -84
  58. package/lib/apis/codiac-api/common/security/rest-client-base-with-auth.js +0 -361
  59. package/lib/apis/codiac-api/common/security/rest-client-base-with-auth.js.map +0 -1
  60. package/lib/apis/codiac-api/gen/endpoints.d.ts +0 -3
  61. package/lib/apis/codiac-api/gen/endpoints.js +0 -3150
  62. package/lib/apis/codiac-api/gen/endpoints.js.map +0 -1
  63. package/lib/apis/over-gen/temp-mods.d.ts +0 -33
  64. package/lib/apis/over-gen/temp-mods.js +0 -91
  65. package/lib/apis/over-gen/temp-mods.js.map +0 -1
  66. package/lib/relay/wsclient/bus-listener.ervice.d.ts +0 -71
  67. package/lib/relay/wsclient/bus-listener.ervice.js +0 -150
  68. package/lib/relay/wsclient/bus-listener.ervice.js.map +0 -1
  69. package/lib/uilogic/enterprise-contextualizer-machine-scope.d.ts +0 -69
  70. package/lib/uilogic/enterprise-contextualizer-machine-scope.js +0 -596
  71. package/lib/uilogic/enterprise-contextualizer-machine-scope.js.map +0 -1
  72. package/lib/uilogic/registry-configurator-factory.d.ts +0 -12
  73. package/lib/uilogic/registry-configurator-factory.js +0 -68
  74. package/lib/uilogic/registry-configurator-factory.js.map +0 -1
  75. package/lib/uilogic/registry-configurator.d.ts +0 -17
  76. package/lib/uilogic/registry-configurator.js +0 -145
  77. package/lib/uilogic/registry-configurator.js.map +0 -1
  78. package/lib/uilogic/registry-configurators/aws-registry-configurator.d.ts +0 -15
  79. package/lib/uilogic/registry-configurators/aws-registry-configurator.js +0 -67
  80. package/lib/uilogic/registry-configurators/aws-registry-configurator.js.map +0 -1
  81. package/lib/uilogic/registry-configurators/azure-registry-configurator.d.ts +0 -25
  82. package/lib/uilogic/registry-configurators/azure-registry-configurator.js +0 -72
  83. package/lib/uilogic/registry-configurators/azure-registry-configurator.js.map +0 -1
  84. package/lib/uilogic/registry-configurators/docker-hub-registry-configurator.d.ts +0 -18
  85. package/lib/uilogic/registry-configurators/docker-hub-registry-configurator.js +0 -55
  86. package/lib/uilogic/registry-configurators/docker-hub-registry-configurator.js.map +0 -1
  87. package/lib/uilogic/registry-configurators/helm-registry-configurator.d.ts +0 -16
  88. package/lib/uilogic/registry-configurators/helm-registry-configurator.js +0 -44
  89. package/lib/uilogic/registry-configurators/helm-registry-configurator.js.map +0 -1
  90. package/lib/uilogic/registry-configurators/unsupported-registry-configurator.d.ts +0 -17
  91. package/lib/uilogic/registry-configurators/unsupported-registry-configurator.js +0 -60
  92. package/lib/uilogic/registry-configurators/unsupported-registry-configurator.js.map +0 -1
@@ -1,596 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EnterpriseContextualizerMachineScope = void 0;
4
- const tslib_1 = require("tslib");
5
- const asset_binding_1 = require("../codiac-entities/asset-binding");
6
- const _ = require("lodash");
7
- const codiac_domain_1 = require("@codiac.io/codiac-domain");
8
- const codiac_relay_contracts_1 = require("@codiac.io/codiac-relay-contracts");
9
- const codiac_relay_contracts_2 = require("@codiac.io/codiac-relay-contracts");
10
- const contracts_1 = require("@codiac.io/codiac-common/contracts");
11
- // export declare type EnterpriseContext = { enterpriseCode: string, assetBindings?: AssetContext[]|undefined };
12
- // export declare type AssetContext = { image: ImageExport, incarnation: AssetBinding };
13
- /** Establishes a single Enterprise Asset as which to deploy an ImageExport. */
14
- class EnterpriseContextualizerMachineScope {
15
- constructor(_tenantCode, _ops, _codiacApi, _projUserCfg, _projCfgRepo, userContext, userContextManager, regClientFactory, ui, styler, exitCli, logger) {
16
- this._tenantCode = _tenantCode;
17
- this._ops = _ops;
18
- this._codiacApi = _codiacApi;
19
- this._projUserCfg = _projUserCfg;
20
- this._projCfgRepo = _projCfgRepo;
21
- this.userContext = userContext;
22
- this.userContextManager = userContextManager;
23
- this.regClientFactory = regClientFactory;
24
- this.ui = ui;
25
- this.styler = styler;
26
- this.exitCli = exitCli;
27
- this.logger = logger;
28
- }
29
- /** Interacts with user to select an existing enterprise (or create one if none exist),
30
- * and persists it in the project user config.
31
- * NOTE: Clears Asset context if the user switches enterprises,
32
- * or keeps original with orignal asset context if user selects it. */
33
- establishEnterprise(requestedEnterpriseCode) {
34
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
35
- return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
36
- var _a, _b, _c, _d, _e;
37
- try {
38
- let eResult = yield this._codiacApi.tryReadMany(codiac_domain_1.Enterprise, codiac_domain_1.EnterpriseCriteria, { all: true });
39
- if (eResult.error)
40
- throw new contracts_1.CodiacError(`Error reading enterprises: ${eResult.message}; ${eResult.error.message}`, eResult.error);
41
- if (!eResult.output || eResult.output.length == 0) {
42
- throw new contracts_1.CodiacError(`This tenant [${this._tenantCode}] does not have any enterprises defined. You need to create one to continue.`);
43
- // TODO: The contextualizer should walk them thru the enterprise setup.
44
- // eCode = await cli.prompt(`Enter a code for the enterprise (${eCode})`);
45
- // eCode = eCode.toLowercase().replace(/[^A-Za-z0-9-_]/g, "");
46
- // // TODO: We might use one more conf here to let em check for stray keystrokes (we enterprise codes are immutable)
47
- // let ep = new Enterprise(eCode);
48
- // let createResult = await this._codiacApi.tryCreate(Enterprise, ep);
49
- // if (createResult.Error) throw new CodiacError(`Error creating new enterprise [${ep.code}]: ${createResult.message||""}; ${createResult.error.message}`, createResult.error);
50
- }
51
- // -------------------------------------------------------------------
52
- // !!!! HELP !!!!
53
- // We're drowning in IF statments here!!
54
- //
55
- // It's the end of a looong day of a LOT of coding solutions,
56
- // and I cant summon an elegant path thru this...
57
- //
58
- // TODO: REFACTOR THIS INTO SOMETHING THAT LOOKS PROFESSIONAL.
59
- // -------------------------------------------------------------------
60
- // GET: proj THEN user
61
- let originalCode = (_c = (_b = (_a = this._projUserCfg) === null || _a === void 0 ? void 0 : _a.enterprise) === null || _b === void 0 ? void 0 : _b.enterpriseCode) !== null && _c !== void 0 ? _c : (_e = (_d = this.userContext) === null || _d === void 0 ? void 0 : _d.currentEnterprise) === null || _e === void 0 ? void 0 : _e.enterprise;
62
- // Validate the requested enterprise
63
- let enterprise;
64
- if (requestedEnterpriseCode) {
65
- enterprise = eResult.output.find(e => e.code == requestedEnterpriseCode);
66
- }
67
- // Validate the enterprise set in the current project user context
68
- if (!enterprise) {
69
- if (originalCode !== undefined && originalCode !== "") {
70
- enterprise = eResult.output.find(e => e.code == originalCode);
71
- }
72
- }
73
- // Prompt the user to select from the list of enterprises (for this tenant)
74
- let attempts = 4;
75
- while (!enterprise && attempts > 0) {
76
- let eCode = yield this.ui.promptSelect("enterpriseCode", "Select a target enterprise:", eResult.output.map(e => e.code));
77
- if (eCode)
78
- enterprise = eResult.output.find(e => e.code == eCode);
79
- attempts--;
80
- }
81
- if (!enterprise)
82
- throw new Error("Failed to select a target enterprise.");
83
- // We've got one now.
84
- if (originalCode !== undefined && originalCode !== "" && enterprise.code == originalCode) {
85
- // same as original. Do nothing
86
- }
87
- else {
88
- // new enterprise context
89
- this.userContext.currentEnterprise = { enterprise: enterprise.code };
90
- this.userContext.enterpriseContexts[this._tenantCode] = this.userContext.currentEnterprise;
91
- yield this.userContextManager.writeUserContext(this.userContext);
92
- // SET: user THEN proj
93
- if (this._projUserCfg) {
94
- this._projUserCfg.enterprise = new codiac_relay_contracts_1.ProjectEnterpriseBinding(this.userContext.currentEnterprise.enterprise);
95
- yield this._projCfgRepo.writeProjectUserConfig(this._projUserCfg);
96
- }
97
- }
98
- resolve(enterprise);
99
- }
100
- catch (err) {
101
- reject(err);
102
- }
103
- }));
104
- });
105
- }
106
- establishEnterpriseAsset(enterprise, projCfg, suppressConfirmations) {
107
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
108
- return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
109
- var _a, _b;
110
- try {
111
- let assetName;
112
- // TODO: Consider using asset.code instead.
113
- // assetName = this._projUserCfg?.enterprise?.assetBindings ? this._projUserCfg?.enterprise?.assetBindings[0].incarnation?.assetName ?? this.userContext.currentEnterprise?.asset : this.userContext.currentEnterprise?.asset;
114
- // WITH PROJECT CONTEXT
115
- if (projCfg) {
116
- let assetContext = yield this.establishProjectAssetBinding(enterprise.code, enterprise.assets, projCfg, suppressConfirmations, (_a = this.userContext.currentEnterprise) === null || _a === void 0 ? void 0 : _a.asset);
117
- assetName = assetContext.incarnation.assetName;
118
- yield this.validateImageOs(assetContext, enterprise.assets);
119
- // TODO: This should come BEFORE establishBinding. This will require the new assetContextSwitching.
120
- // TODO: validate that requested assets exist. Dont auto-create them.
121
- // await this.validateAssetBinding(assetContext); // <---- BUT THIS SHD BE PART OF this.establishBinding()
122
- // which should include:
123
- // throw new CodiacError(`Requested Asset [${req.incarnation.assetName}] does not exist in the enterprise [${req.incarnation.enterprise}].`)
124
- let assets = yield this.createMissingAssets(enterprise.code, [assetContext]);
125
- }
126
- // WITH USER CONTEXT
127
- if (assetName === undefined || assetName === "") {
128
- if (this.userContext.currentEnterprise == undefined || this.userContext.currentEnterprise.enterprise !== enterprise.code) {
129
- // Make sure we are pointed to the given enterprise
130
- this.userContext.currentEnterprise = new codiac_relay_contracts_1.EnterprisePointer(enterprise.code);
131
- }
132
- if (this.userContext.currentEnterprise.asset !== undefined && this.userContext.currentEnterprise.asset !== "") {
133
- // Make sure current asset still exists in the enterprise record.
134
- assetName = (_b = enterprise.assets.find(a => a.name === this.userContext.currentEnterprise.asset)) === null || _b === void 0 ? void 0 : _b.name;
135
- }
136
- if (assetName === undefined || assetName === "") {
137
- // Prompt the user directly
138
- let choices = enterprise.assets.map(a => { return { name: a.name, value: a.name }; });
139
- assetName = (yield this.ui.promptSelect("assetName", "Asset: ", choices));
140
- }
141
- }
142
- else {
143
- // Save whatever was selected in the prject context
144
- }
145
- resolve(assetName);
146
- }
147
- catch (err) {
148
- reject(err);
149
- }
150
- }));
151
- });
152
- }
153
- /** Throws when the image os does not match that of the image in the remote enterprise asset record.
154
- *
155
- * Throws any errors. */
156
- validateImageOs(localBinding, enterpriseAssets) {
157
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
158
- return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
159
- var _a, _b, _c;
160
- try {
161
- let assetRecord = enterpriseAssets.find(a => a.name == localBinding.incarnation.assetName);
162
- if ((assetRecord === null || assetRecord === void 0 ? void 0 : assetRecord.image) && assetRecord.image.os && (((_a = localBinding.image.os) === null || _a === void 0 ? void 0 : _a.toLowerCase()) != assetRecord.image.os.toLowerCase())) {
163
- throw new Error(`The image callout in the official enterprise asset record [asset: ${assetRecord.name}, enterprise: ${assetRecord.enterprise}] is showing a different OS [${(_b = assetRecord.image.os) !== null && _b !== void 0 ? _b : "undefined"}] than the one in this project of [${(_c = localBinding.image.os) !== null && _c !== void 0 ? _c : "undefined"}]. Please reconcile this issue.`);
164
- }
165
- resolve();
166
- }
167
- catch (err) {
168
- reject(err);
169
- }
170
- }));
171
- });
172
- }
173
- /** TODO: Ensures that the given assets exist in the api. */
174
- createMissingAssets(enterpriseCode, requestedAssets) {
175
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
176
- return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
177
- try {
178
- let assets = [];
179
- let crit = { code: enterpriseCode };
180
- let assetResult = yield this._codiacApi.tryReadMany(codiac_domain_1.Enterprise, codiac_domain_1.EnterpriseCriteria, crit);
181
- if (assetResult.error) {
182
- throw new contracts_1.CodiacError(`Error querying enterprise to check for existing assets: ${assetResult.message || ""}; ${assetResult.error.message || ""}`, assetResult.error);
183
- }
184
- else if (!assetResult.success || !assetResult.output) {
185
- throw new contracts_1.CodiacError(`Unable to verify assets: enterprise [${crit.code}] was not found.`);
186
- }
187
- else {
188
- let enterprise = assetResult.output[0];
189
- let assets = enterprise.assets; // Deploy all of em unless the caller requested specific ones.
190
- if (requestedAssets && requestedAssets.length > 0) {
191
- // Get only the requested ones...
192
- // assets = enterprise.assets.filter(a => requestedAssets.find(ac => a.name == ac.incarnation.assetName));
193
- assets = [];
194
- let newAssets = [];
195
- for (let req of requestedAssets) {
196
- let epAsset = enterprise.assets.find(a => a.name == req.incarnation.assetName);
197
- if (epAsset) {
198
- assets.push(epAsset);
199
- }
200
- else {
201
- let newAsset = yield this.hackBuildAsset(req, enterprise);
202
- newAssets.push(newAsset);
203
- enterprise.assets.push(...newAssets);
204
- }
205
- }
206
- if (newAssets.length > 0) {
207
- let saveResult = yield this._codiacApi.tryCreateMany(codiac_domain_1.Asset, newAssets);
208
- if (saveResult.error) {
209
- throw new contracts_1.CodiacError(`Error inserting missing enterprise assets [${newAssets.map(a => a.name).join(',')}]: ${saveResult.error.message || saveResult.message || ""}`, saveResult.error);
210
- }
211
- else if (!saveResult.success || !saveResult.successes || saveResult.successes.length == 0) {
212
- if (saveResult.failures && saveResult.failures.length > 0 && saveResult.failures.length < newAssets.length) {
213
- this.logger.debug(`Saving new assets yielded a partial failure.`);
214
- }
215
- throw new contracts_1.CodiacError(`Unable to save missing enterprise assets [${newAssets.map(a => a.name).join(',')}]: Returned failure without error. ${saveResult.message}`);
216
- }
217
- else {
218
- this.logger.debug(`Created missing assets: [${saveResult.successes.map(a => a.name).join(',')}]`);
219
- assets.push(...saveResult.successes);
220
- }
221
- }
222
- }
223
- }
224
- resolve(assets);
225
- }
226
- catch (err) {
227
- reject(err);
228
- }
229
- }));
230
- });
231
- }
232
- /** This is backwards - it should be impossible to have an asset binding to an asset that doesnt exist.
233
- * If somehow the project was still pointed to a since-deleted asset,
234
- * then it should still throw an error and allow the user to select an existing asset to bind/switch to.
235
- */
236
- hackBuildAsset(localDef, enterprise) {
237
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
238
- return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
239
- try {
240
- let newAsset;
241
- let target;
242
- // no record for this asset in the enterprise yet.
243
- if (localDef.image.targets.length == 0) {
244
- // TODO: Use the default image target registry.
245
- // imgRegistry = new ImageRegistry("dockerhub", "https://index.docker.io/v1");
246
- target = new codiac_relay_contracts_1.RegistryTarget("default", EnterpriseContextualizerMachineScope.DEFAULT_REGISTRY_URL);
247
- this.logger.detail(`No target image registry declared for image [${localDef.image.name}], using default at ${target.registryUrl}`);
248
- localDef.image.targets.push(target);
249
- }
250
- else {
251
- target = localDef.image.targets[0]; // <-- HACK!!! taking the first one. Confirm?
252
- }
253
- // COMMENTED OUT BECUASE let's just get it in there as a compositional entity
254
- // Go fetch the registry obj from the api
255
- // TODO: Consider making this a get-sert
256
- // let regCrit = <ImageRegistryCriteria>{ url: localDef.image.targets[0].registryUrl };
257
- // let imageRegResult = await this._codiacApi.tryReadMany(ImageRegistry, ImageRegistryCriteria, regCrit);
258
- // if (imageRegResult.error) {
259
- // throw new CodiacError(`Error retrieving ImageRegistry [${localDef.image.targets[0].registryUrl}] for image [${localDef.image.name}]: ${imageRegResult.error.message||imageRegResult.message||""}`, imageRegResult.error);
260
- // } else if (!imageRegResult.success || imageRegResult.output == undefined || imageRegResult.output.length == 0) {
261
- // throw new Error(`No registry currently exists with url: [${regCrit.url||""}] ${imageRegResult.message||""}`)
262
- // } else {
263
- // imgRegistry = imageRegResult.output[0];
264
- let imgRegistry = new codiac_domain_1.ImageRegistry(`${this._tenantCode}-${codiac_domain_1.CloudProviderEnum}`, target.registryUrl, codiac_domain_1.CloudProviderEnum.dockerHub, codiac_domain_1.ImageRegistryTypes.DockerHub);
265
- newAsset = {
266
- code: localDef.incarnation.assetName,
267
- name: localDef.incarnation.assetName,
268
- enterprise: enterprise.code,
269
- image: new codiac_domain_1.Image(localDef.image.name, imgRegistry),
270
- port: localDef.incarnation.port || localDef.image.port || 0
271
- };
272
- // TODO: Write to the enterprise? or throw? or ask?
273
- // }
274
- resolve(newAsset);
275
- }
276
- catch (err) {
277
- reject(err);
278
- }
279
- }));
280
- });
281
- }
282
- /** Selects a single ImageExport and a single incarnation of that image (aka: AssetBinding).
283
- * @param suppressConfirmations (Optional: defaults to false) Prevents confirmations of user-values that are remembered from prior runs.
284
- * @param preferredAssetName (Optional) Asset name to select if it applies to the given image and is currently remembered. User prompts will default to this if valid.
285
- */
286
- establishProjectAssetBinding(enterpriseCode, assets, _projCfg, suppressConfirmations, preferredAssetName) {
287
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
288
- return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
289
- var _a, _b, _c, _d;
290
- try {
291
- let allowAddingNewAssets = true;
292
- // STEP 1: Establish the ImageExport to use.
293
- let image;
294
- if (_projCfg.images && !_.isEmpty(_projCfg.images)) {
295
- let images = _.keysIn(_projCfg.images);
296
- if (images.length == 1) {
297
- image = _projCfg.images[images[0]];
298
- }
299
- else if (images.length > 0) {
300
- // Prompt the user to select one.
301
- // TODO: Default to the one selected in a previous execution,
302
- // and remember the selection for next time.
303
- let selection = yield this.ui.promptSelect('imageName', 'Image you are executing this command for...', images);
304
- if (!selection)
305
- throw new Error(`No image selected`);
306
- image = _projCfg.images[selection];
307
- }
308
- else {
309
- // This clause is impossible to reach (bc we already did a _.isEmpty check).
310
- throw new Error(`No image exports have been declared for this project; use "codiac images:add" to declare an image for export from this project.`);
311
- }
312
- }
313
- else { // No image exports defined for the project
314
- throw new Error(`No image exports have been declared for this project; use "codiac images:add" to declare an image for export from this project.`);
315
- }
316
- let validBindings = assets
317
- .filter(a => a.image.name == image.name)
318
- .map(a => new asset_binding_1.AssetBinding(enterpriseCode, a.name, a.port));
319
- // STEP 2: Establish the AssetBinding
320
- let binding;
321
- // a: See if we've already got one selected (via the project user config)
322
- let remembered;
323
- let found = (_c = (_b = (_a = this._projUserCfg) === null || _a === void 0 ? void 0 : _a.enterprise) === null || _b === void 0 ? void 0 : _b.assetBindings) === null || _c === void 0 ? void 0 : _c.filter(ab => ab.image.name == image.name);
324
- if (found && found.length > 0) {
325
- // Try to use preferred...
326
- if (preferredAssetName !== undefined && preferredAssetName !== "") {
327
- remembered = (_d = found.find(a => a.incarnation.assetName === preferredAssetName)) === null || _d === void 0 ? void 0 : _d.incarnation;
328
- }
329
- if (!remembered) {
330
- // Otherwise, just take the first valid binding we've remembered for that image
331
- remembered = found[0].incarnation;
332
- }
333
- }
334
- // a: Select and validate an existing binding
335
- if (remembered) {
336
- // We only care about the existing bindings we know are still valid in this enterprise
337
- // let existings = image.incarnations.filter(i => validBindings.find(v => v.enterprise == i.enterprise && v.assetName == i.assetName));
338
- if (validBindings.find(v => v.enterprise == remembered.enterprise && v.assetName == remembered.assetName)) {
339
- // confirm the remembered one only if they requested a selection
340
- if (!suppressConfirmations) {
341
- if (yield this.ui.promptConfirm("assetBinding", `Targeting asset: ${this.styler.bold(this.styler.hilite(remembered.enterprise + '/' + remembered.assetName))} ?`)) {
342
- binding = remembered;
343
- }
344
- }
345
- else {
346
- binding = remembered;
347
- }
348
- }
349
- // if (existings.length == 1) {
350
- // } else if (existings.length > 1) {
351
- // // select from existing
352
- // let choices = existings.map(e => e.assetName);
353
- // let selection = await this.ui.promptSelect("assetBinding", `Target asset (in enterprise: ${enterprise.code})...`, choices);
354
- // if (selection) binding = existings.find(a => a.assetName == selection);
355
- // }
356
- }
357
- // use preferred if it's valid (even tho it's not currently in proj user cfg)
358
- if (!binding) {
359
- binding = validBindings.find(b => b.assetName === preferredAssetName);
360
- }
361
- // b: Create a new Asset binding
362
- if (!binding) {
363
- let choices = validBindings.map((e, idx) => { return { name: e.assetName, value: idx }; });
364
- if (allowAddingNewAssets)
365
- choices.push({ name: EnterpriseContextualizerMachineScope.CHOICE_VALUE_FOR_NEW, value: -1 });
366
- let selection = yield this.ui.promptSelect("assetBinding", `Target asset (in enterprise: ${enterpriseCode})...`, choices);
367
- if (!selection)
368
- throw new Error("Failed to select a target asset.");
369
- if (selection >= 0) {
370
- binding = validBindings[selection];
371
- }
372
- else {
373
- // Create a new Asset
374
- // TODO: Use the same UX code as asset:create
375
- let assetName = yield this.ui.prompt("asset", "Name for the Asset to be made from this image:", true, image.name);
376
- let assetCode = assetName; // TODO: Prompt with this default
377
- let assetPort = image.port || this.selectAvailableAssetPort(assets); // TODO: Prompt with this default
378
- let assetImg = this.createAssetImageRef(image);
379
- let newAsset = new codiac_domain_1.Asset(enterpriseCode, assetCode, assetName, assetImg, assetPort);
380
- let createResult = yield this._codiacApi.tryCreate(codiac_domain_1.Asset, newAsset);
381
- if (createResult.error)
382
- throw createResult.error;
383
- else if (!createResult.success || !createResult.output)
384
- throw new Error(`Failed creating new asset ${newAsset.name} in enterprise: ${newAsset.enterprise}: ${createResult.message}`);
385
- newAsset = createResult.output;
386
- this.logger.detail(`New Asset [${createResult.output.name}] Successfully created from image: [${createResult.output.image.name}] in enterprise [${createResult.output.enterprise}].`);
387
- binding = new asset_binding_1.AssetBinding(enterpriseCode, newAsset.name, newAsset.port);
388
- }
389
- }
390
- if (!binding)
391
- throw new Error("No asset binding was established.");
392
- // Write this selection to the proj user config
393
- if (!this._projUserCfg) {
394
- this._projUserCfg = new codiac_relay_contracts_1.ProjectUserConfig();
395
- }
396
- if (!this._projUserCfg.enterprise) {
397
- this._projUserCfg.enterprise = new codiac_relay_contracts_1.ProjectEnterpriseBinding(enterpriseCode);
398
- }
399
- if (!this._projUserCfg.enterprise.assetBindings)
400
- this._projUserCfg.enterprise.assetBindings = [];
401
- _.remove(this._projUserCfg.enterprise.assetBindings, ac => ac.image.name == image.name);
402
- this._projUserCfg.enterprise.assetBindings.push(new codiac_relay_contracts_1.AssetContext(image, binding));
403
- this._projCfgRepo.writeProjectUserConfig(this._projUserCfg);
404
- resolve({ image: image, incarnation: binding });
405
- }
406
- catch (err) {
407
- reject(err);
408
- }
409
- }));
410
- });
411
- }
412
- /** provdes a randpm port number that is not currently owned by any asset in the enterprise. */
413
- selectAvailableAssetPort(existingAssets) {
414
- let port = EnterpriseContextualizerMachineScope.DEFAULT_ASSET_PORT_NUMBER;
415
- while (!port || existingAssets.find(a => a.port == port)) {
416
- port = _.random(1024, 65535, false);
417
- }
418
- return port;
419
- }
420
- /** Factory method for the image reference object on which an Asset is based. */
421
- createAssetImageRef(projectImage, targetEnvironment) {
422
- let registryEnv = targetEnvironment || "default";
423
- let registryTarget = projectImage.targets.find(t => t.environment == registryEnv);
424
- if (!registryTarget) {
425
- throw new Error(`The image export [${projectImage.name}] in the local project does not have a target registry declared for the [${registryEnv}] environment.`);
426
- }
427
- let regClient = this.regClientFactory.createForDomain(registryTarget.registryUrl);
428
- let regCode = "TODO-DERIVE-THE-IMAGE-REGISTRY-CODE"; // <----- HEY!!! We need to provide proper support of image registries by code name (eg: "dockerhub", "acr", "google", "amazon-ecr" etc)
429
- let reg = new codiac_domain_1.ImageRegistry(regCode, registryTarget.registryUrl, regClient.cloudProvider, regClient.registryType);
430
- let scope = (projectImage.name.indexOf("/") >= 0) ? projectImage.name.split("/")[0] : undefined;
431
- let img = new codiac_domain_1.Image(projectImage.name, reg, scope);
432
- return img;
433
- }
434
- /** Simply wraps establishCabinet() to return a CabinetScope.
435
- * TODO: EITHER get rid of this method altogether and use Cabinet instead of CabinetScope
436
- * OR Add ClusterName to CabinetScope (it's redundant, but it's important for gathering k8s cluster context without requerying the api)
437
- * @param suppressConfirmations (Optional: defaults to false) Prevents confirmations of user-values that are remembered from prior runs.
438
- */
439
- establishCabinetContext(requestedCabinet, suppressConfirmations) {
440
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
441
- return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
442
- try {
443
- let cabinet = yield this.establishCabinet(requestedCabinet, suppressConfirmations);
444
- let cabCntx = new codiac_relay_contracts_1.CabinetScope(cabinet.enterpriseCode, cabinet.environment, cabinet.name);
445
- this.logger.trace(`Cabinet context`, cabCntx);
446
- resolve(cabCntx);
447
- }
448
- catch (err) {
449
- reject(err);
450
- }
451
- }));
452
- });
453
- }
454
- /** Selects from existing cabinets.
455
- * Defaults to the cabinet declared in the project user config.
456
- * DOES NOT lazily create new cabinets OR build cabinet infrastructure!
457
- * This method only selects an existing cabinet
458
- * (because cabinet scope - eg: enterprises, environments, and cabinets -
459
- * should only be created deliberately and explicitly by their respective cli commands).
460
- * @param suppressConfirmations (Optional: defaults to false) Prevents confirmations of user-values that are remembered from prior runs.
461
- */
462
- establishCabinet(requestedCabinet, suppressConfirmations, projCfg) {
463
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
464
- return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
465
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
466
- try {
467
- let enterpriseCode = (_c = (_b = (_a = this._projUserCfg) === null || _a === void 0 ? void 0 : _a.enterprise) === null || _b === void 0 ? void 0 : _b.enterpriseCode) !== null && _c !== void 0 ? _c : (_d = this.userContext.currentEnterprise) === null || _d === void 0 ? void 0 : _d.enterprise;
468
- if (enterpriseCode === undefined) {
469
- throw new contracts_1.CodiacError(`Cannot establish cabinet context: no enterprise is in context for the current user.`);
470
- }
471
- let current = (_h = (_g = (_f = (_e = this._projUserCfg) === null || _e === void 0 ? void 0 : _e.enterprise) === null || _f === void 0 ? void 0 : _f.cabinet) === null || _g === void 0 ? void 0 : _g.cabinet) !== null && _h !== void 0 ? _h : (_j = this.userContext.currentEnterprise) === null || _j === void 0 ? void 0 : _j.cabinet;
472
- let cabName = requestedCabinet !== null && requestedCabinet !== void 0 ? requestedCabinet : current;
473
- // -----------
474
- // let eCntx = this._projUserCfg?.enterprise ?? this.userContext.currentEnterprise;
475
- // if (eCntx == undefined || (<ProjectEnterpriseBinding>eCntx).enterpriseCode == undefined || (<EnterprisePointer>eCntx).enterprise == undefined) {
476
- // throw new CodiacError(`Cannot establish cabinet context: no enterprise is in context for the current user.`);
477
- // }
478
- // // Remember any existing context...
479
- // let enterpriseCode = eCntx.enterpriseCode;
480
- // let current = eCntx.cabinet?.cabinet;
481
- // let cabName: string | undefined = requestedCabinet;
482
- // if (!cabName) { // THIS because we dont have the nullish operator...
483
- // cabName = current;
484
- // }
485
- // -----------
486
- // let env: Environment;
487
- // let crit: EnvironmentCriteria = { all: true };
488
- // let envResult = await this._codiacApi.tryReadMany(Environment, EnvironmentCriteria, crit);
489
- // if (envResult.error) {
490
- // throw new CodiacError(`Error attempting to retrieve environments: ${envResult.error.message||envResult.message||""}`, envResult.error);
491
- // } else if (envResult.count == 0 || !envResult.output || envResult.output.length == 0) {
492
- // throw new CodiacError(`No environments found: ${envResult.message||""}`);
493
- // } else if (envResult.output.length == 1) {
494
- // env = envResult.output[0];
495
- // } else {
496
- // // TODO: Let the user select which one, and remember his choice as a default for next time.
497
- // env = envResult.output[0]; // <--- HACK!!!!
498
- // }
499
- // if (env.cabinets.length == 0) {
500
- // throw new CodiacError(`No cabinets found for environment [${env.code}]. Use 'cod cabinet:create' to create one.`);
501
- // } else if (env.cabinets.length == 1) {
502
- // cab = env.cabinets[0].name; // TODO: Consider a confirmation here that the -y attrib will skip
503
- // } else {
504
- // // TODO: Let the user select which one, and remember his choice as a default for next time.
505
- // cab = env.cabinets[0].name; // <--- HACK!!!!
506
- // }
507
- let cabinet;
508
- let crit = { enterpriseCode: enterpriseCode };
509
- let cabResult = yield this._codiacApi.tryReadMany(codiac_domain_1.Cabinet, codiac_domain_1.CabinetCriteria, crit); // <--- TODO: Consider injecting a RootMap instance instead of making api hits.
510
- if (cabResult.error) {
511
- throw new contracts_1.CodiacError(`Error checking for cabinets in enterprise [${enterpriseCode}]: ${cabResult.message || ""}; ${cabResult.error.message || cabResult.error.stack}`, cabResult.error);
512
- }
513
- else if (!cabResult.output || cabResult.output.length == 0) {
514
- throw new contracts_1.CodiacError(`No cabinets found for enterprise [${enterpriseCode}]. Use 'cod cabinet:create' to create a new cabinet. ${cabResult.message || ""}`);
515
- }
516
- else {
517
- let cabs = cabResult.output;
518
- // HERE'S THE UX GAUNTLET...
519
- let selection;
520
- if (cabName) {
521
- // This is where we validate that the requested/remembered cabinet is indeed/still in the current enterprise.
522
- // let found = cabs.find(c => c.name == cabName);
523
- // let found = cabs.findIndex(c => c.name == cabName);
524
- selection = cabs.findIndex(c => c.name == cabName);
525
- if (selection < 0) {
526
- this.logger.notice(`Cabinet [${cabName}] was not found in enterprise [${enterpriseCode}].`);
527
- }
528
- }
529
- let choices;
530
- while (!cabinet) {
531
- if (!selection || selection < 0) {
532
- if (cabs.length == 1) { // We're adding this to prevent two steps
533
- selection = 0;
534
- }
535
- else { // Let them choose
536
- choices = choices || cabs.map((c, index) => { return { name: `${c.name}${(cabs[index].name == current) ? " (current)" : ""}`, value: index }; });
537
- selection = (yield this.ui.promptSelect('cabIndex', `Select a cabinet [enterprise: ${this.styler.hilite(enterpriseCode)}]`, choices));
538
- }
539
- }
540
- if (suppressConfirmations) {
541
- cabinet = cabs[selection];
542
- }
543
- else {
544
- let confResult = yield this.ui.promptConfirm('confirm', `Target cabinet: ${this.styler.hilite(enterpriseCode + "/" + cabs[selection].name)}`);
545
- if (confResult === true) { // TODO: Refactor these 3 confirms into 1
546
- // if (await this._ui.promptConfirm("targetCab", `Target cabinet (y/n): ${inOrange(cabs[selection].name)}`)) { // TODO: Refactor these 3 confirms into 1
547
- cabinet = cabs[selection];
548
- }
549
- else if (cabs.length == 1) { // We're adding this so we can avoid what would be two steps
550
- this.logger.notice(`Operation cancelled. That was the only cabinet available in enterprise [${enterpriseCode}].`);
551
- this.exitCli(0);
552
- }
553
- else {
554
- selection = undefined;
555
- }
556
- }
557
- }
558
- }
559
- // PROJECT CONTEXT
560
- if (projCfg) {
561
- if (!this._projUserCfg)
562
- this._projUserCfg = new codiac_relay_contracts_1.ProjectUserConfig();
563
- if (this._projUserCfg.enterprise === undefined || this._projUserCfg.enterprise.enterpriseCode !== enterpriseCode) {
564
- this._projUserCfg.enterprise = new codiac_relay_contracts_1.ProjectEnterpriseBinding(enterpriseCode);
565
- }
566
- // Are we sure we wanna set the exact current branch? what if we're inheriting this cabinet from our branch lineage?
567
- let branch = yield this._ops.gitCurrentBranchNameFor(this._ops.getConfigRoot());
568
- this._projUserCfg.enterprise.cabinet = new codiac_relay_contracts_2.BranchBinding(branch, enterpriseCode, cabinet.name);
569
- this._projCfgRepo.writeProjectUserConfig(this._projUserCfg);
570
- }
571
- // USER CONTEXT
572
- if (this.userContext.currentEnterprise === undefined || this.userContext.currentEnterprise.enterprise !== enterpriseCode) {
573
- this.userContext.currentEnterprise = new codiac_relay_contracts_1.EnterprisePointer(enterpriseCode);
574
- }
575
- this.userContext.currentEnterprise.cabinet = cabinet.name;
576
- this.userContext.enterpriseContexts[this._tenantCode] = this.userContext.currentEnterprise;
577
- this.userContextManager.writeUserContext(this.userContext);
578
- this.logger.trace(`Cabinet`, cabinet);
579
- // let cabCntx = new CabinetScope(cabinet.enterpriseCode, cabinet.environment, cabinet.name)
580
- // this.logger.trace(`Cabinet context`, cabCntx)
581
- resolve(cabinet);
582
- }
583
- catch (err) {
584
- reject(err);
585
- }
586
- }));
587
- });
588
- }
589
- }
590
- exports.EnterpriseContextualizerMachineScope = EnterpriseContextualizerMachineScope;
591
- /** The value in a select list prompt designating the user's choice
592
- * to create a new record instead of selecting from the existing choices. */
593
- EnterpriseContextualizerMachineScope.CHOICE_VALUE_FOR_NEW = "** create new **";
594
- EnterpriseContextualizerMachineScope.DEFAULT_REGISTRY_URL = "https://index.docker.io/v1";
595
- EnterpriseContextualizerMachineScope.DEFAULT_ASSET_PORT_NUMBER = 1787;
596
- //# sourceMappingURL=enterprise-contextualizer-machine-scope.js.map