@codiac.io/codiac-cli 1.2.168 → 1.2.169

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 (522) hide show
  1. package/README.md +3328 -47
  2. package/bin/dev +16 -16
  3. package/bin/dev.cmd +2 -2
  4. package/bin/run +3 -3
  5. package/bin/run.cmd +3 -3
  6. package/codiac.json +9 -9
  7. package/lib/api-command-base.d.ts +0 -0
  8. package/lib/api-command-base.js +52 -0
  9. package/lib/api-command-base.js.map +1 -0
  10. package/lib/apis/codiac-api/common/api-client-base.d.ts +165 -165
  11. package/lib/apis/codiac-api/common/api-client-base.js +547 -547
  12. package/lib/apis/codiac-api/common/api-user-creds.d.ts +7 -7
  13. package/lib/apis/codiac-api/common/api-user-creds.js +18 -18
  14. package/lib/apis/codiac-api/common/config-loader.d.ts +6 -6
  15. package/lib/apis/codiac-api/common/config-loader.js +18 -18
  16. package/lib/apis/codiac-api/common/endpoint-spec.d.ts +17 -17
  17. package/lib/apis/codiac-api/common/endpoint-spec.js +27 -27
  18. package/lib/apis/codiac-api/common/security/api-auth-methods-legacy.d.ts +87 -87
  19. package/lib/apis/codiac-api/common/security/api-auth-methods-legacy.js +367 -367
  20. package/lib/apis/codiac-api/common/security/auth-constants.d.ts +15 -15
  21. package/lib/apis/codiac-api/common/security/auth-constants.js +21 -21
  22. package/lib/apis/codiac-api/common/security/i-auth-client.d.ts +44 -44
  23. package/lib/apis/codiac-api/common/security/i-auth-client.js +2 -2
  24. package/lib/apis/codiac-api/common/security/token-holder.d.ts +13 -13
  25. package/lib/apis/codiac-api/common/security/token-holder.js +17 -17
  26. package/lib/apis/codiac-api/common/utils.d.ts +23 -23
  27. package/lib/apis/codiac-api/common/utils.js +82 -82
  28. package/lib/apis/codiac-api/contracts/index.d.ts +1 -1
  29. package/lib/apis/codiac-api/contracts/index.js +4 -4
  30. package/lib/apis/codiac-api/gen/client-config.d.ts +10 -10
  31. package/lib/apis/codiac-api/gen/client-config.js +28 -28
  32. package/lib/apis/codiac-api/gen/client.d.ts +1663 -1663
  33. package/lib/apis/codiac-api/gen/client.js +15629 -15629
  34. package/lib/apis/codiac-api/gen/contracts.d.ts +2722 -2722
  35. package/lib/apis/codiac-api/gen/contracts.js +402 -402
  36. package/lib/apis/codiac-api/index.d.ts +3 -3
  37. package/lib/apis/codiac-api/index.js +8 -8
  38. package/lib/apis/codiac-relay/common/api-client-base.d.ts +165 -165
  39. package/lib/apis/codiac-relay/common/api-client-base.js +547 -547
  40. package/lib/apis/codiac-relay/common/api-user-creds.d.ts +7 -7
  41. package/lib/apis/codiac-relay/common/api-user-creds.js +18 -18
  42. package/lib/apis/codiac-relay/common/config-loader.d.ts +6 -6
  43. package/lib/apis/codiac-relay/common/config-loader.js +18 -18
  44. package/lib/apis/codiac-relay/common/endpoint-spec.d.ts +17 -17
  45. package/lib/apis/codiac-relay/common/endpoint-spec.js +27 -27
  46. package/lib/apis/codiac-relay/common/security/api-auth-methods-legacy.d.ts +87 -87
  47. package/lib/apis/codiac-relay/common/security/api-auth-methods-legacy.js +367 -367
  48. package/lib/apis/codiac-relay/common/security/auth-constants.d.ts +15 -15
  49. package/lib/apis/codiac-relay/common/security/auth-constants.js +21 -21
  50. package/lib/apis/codiac-relay/common/security/i-auth-client.d.ts +44 -44
  51. package/lib/apis/codiac-relay/common/security/i-auth-client.js +2 -2
  52. package/lib/apis/codiac-relay/common/security/token-holder.d.ts +13 -13
  53. package/lib/apis/codiac-relay/common/security/token-holder.js +17 -17
  54. package/lib/apis/codiac-relay/common/utils.d.ts +23 -23
  55. package/lib/apis/codiac-relay/common/utils.js +82 -82
  56. package/lib/apis/codiac-relay/contracts/index.d.ts +1 -1
  57. package/lib/apis/codiac-relay/contracts/index.js +4 -4
  58. package/lib/apis/codiac-relay/gen/client-config.d.ts +10 -10
  59. package/lib/apis/codiac-relay/gen/client-config.js +28 -28
  60. package/lib/apis/codiac-relay/gen/client.d.ts +244 -244
  61. package/lib/apis/codiac-relay/gen/client.js +1862 -1862
  62. package/lib/apis/codiac-relay/gen/contracts.d.ts +3111 -3111
  63. package/lib/apis/codiac-relay/gen/contracts.js +434 -434
  64. package/lib/apis/codiac-relay/index.d.ts +3 -3
  65. package/lib/apis/codiac-relay/index.js +8 -8
  66. package/lib/azure-rest-client.d.ts +6 -0
  67. package/lib/azure-rest-client.js +36 -0
  68. package/lib/azure-rest-client.js.map +1 -0
  69. package/lib/cli-common/ImagesList.js +66 -66
  70. package/lib/cli-common/argument-manager.d.ts +28 -28
  71. package/lib/cli-common/argument-manager.js +194 -194
  72. package/lib/cli-common/built-in-cli-user-input.d.ts +18 -18
  73. package/lib/cli-common/built-in-cli-user-input.js +309 -309
  74. package/lib/cli-common/cli-interfaces.js +6 -6
  75. package/lib/cli-common/command-base.d.ts +72 -72
  76. package/lib/cli-common/command-base.js +181 -181
  77. package/lib/cli-common/entities/index.d.ts +1 -1
  78. package/lib/cli-common/entities/index.js +4 -4
  79. package/lib/cli-common/entities/prompt-choice.d.ts +7 -7
  80. package/lib/cli-common/entities/prompt-choice.js +2 -2
  81. package/lib/cli-common/file-selector.d.ts +48 -48
  82. package/lib/cli-common/file-selector.js +186 -186
  83. package/lib/cli-common/i-user-input-provider.js +18 -18
  84. package/lib/cli-common/index.d.ts +4 -4
  85. package/lib/cli-common/index.js +10 -10
  86. package/lib/cli-common/mock-ui.d.ts +27 -27
  87. package/lib/cli-common/mock-ui.js +82 -82
  88. package/lib/cli-common/prompt-select-fuzzy.d.ts +19 -19
  89. package/lib/cli-common/prompt-select-fuzzy.js +118 -118
  90. package/lib/cli-common/tenant-contextualizer.js +435 -435
  91. package/lib/cli-common/test/tenant-contextualizer.spec.js +142 -142
  92. package/lib/cli-entities/output-format-enum.d.ts +7 -7
  93. package/lib/cli-entities/output-format-enum.js +11 -11
  94. package/lib/cli-entities/prompt-choice.js +5 -5
  95. package/lib/codiac-constants.d.ts +35 -35
  96. package/lib/codiac-constants.js +40 -40
  97. package/lib/codiac-entities/asset-binding.d.ts +12 -12
  98. package/lib/codiac-entities/asset-binding.js +17 -17
  99. package/lib/codiac-entities/azure-container-registry.d.ts +4 -4
  100. package/lib/codiac-entities/azure-container-registry.js +2 -2
  101. package/lib/codiac-entities/azure-service-principal.d.ts +23 -23
  102. package/lib/codiac-entities/azure-service-principal.js +23 -23
  103. package/lib/codiac-entities/cloud-account-ref.d.ts +28 -28
  104. package/lib/codiac-entities/cloud-account-ref.js +36 -36
  105. package/lib/codiac-entities/deployment-temp.js +132 -132
  106. package/lib/codiac-entities/i-cloud-account-ref.d.ts +5 -5
  107. package/lib/codiac-entities/i-cloud-account-ref.js +2 -2
  108. package/lib/command-base-enterprise.d.ts +121 -121
  109. package/lib/command-base-enterprise.js +523 -523
  110. package/lib/command-base-tenantless.d.ts +44 -44
  111. package/lib/command-base-tenantless.js +172 -172
  112. package/lib/commands/asset/create.d.ts +42 -42
  113. package/lib/commands/asset/create.js +466 -466
  114. package/lib/commands/asset/destroy.d.ts +20 -20
  115. package/lib/commands/asset/destroy.js +128 -128
  116. package/lib/commands/asset/helm.d.ts +23 -23
  117. package/lib/commands/asset/helm.js +152 -152
  118. package/lib/commands/asset/list.d.ts +28 -28
  119. package/lib/commands/asset/list.js +171 -171
  120. package/lib/commands/asset/probe/create.d.ts +38 -38
  121. package/lib/commands/asset/probe/create.js +186 -186
  122. package/lib/commands/asset/recycle.d.ts +23 -23
  123. package/lib/commands/asset/recycle.js +174 -174
  124. package/lib/commands/asset/view.d.ts +188 -188
  125. package/lib/commands/asset/view.js +1364 -1364
  126. package/lib/commands/asset/volume/create.d.ts +23 -23
  127. package/lib/commands/asset/volume/create.js +175 -175
  128. package/lib/commands/asset/volume/delete.d.ts +19 -19
  129. package/lib/commands/asset/volume/delete.js +111 -111
  130. package/lib/commands/asset/volume/list.d.ts +19 -19
  131. package/lib/commands/asset/volume/list.js +69 -69
  132. package/lib/commands/branch/current.d.ts +10 -10
  133. package/lib/commands/branch/current.js +33 -33
  134. package/lib/commands/branch/list.d.ts +15 -15
  135. package/lib/commands/branch/list.js +55 -55
  136. package/lib/commands/branch.d.ts +12 -12
  137. package/lib/commands/branch.js +41 -41
  138. package/lib/commands/build.d.ts +37 -37
  139. package/lib/commands/build.js +118 -118
  140. package/lib/commands/cabinet/create.d.ts +21 -21
  141. package/lib/commands/cabinet/create.js +107 -107
  142. package/lib/commands/cabinet/list.d.ts +23 -23
  143. package/lib/commands/cabinet/list.js +133 -133
  144. package/lib/commands/cabinet/obliterate.d.ts +20 -20
  145. package/lib/commands/cabinet/obliterate.js +82 -82
  146. package/lib/commands/cli.d.ts +10 -10
  147. package/lib/commands/cli.js +99 -99
  148. package/lib/commands/commit.d.ts +11 -11
  149. package/lib/commands/commit.js +39 -39
  150. package/lib/commands/config/add.d.ts +78 -78
  151. package/lib/commands/config/add.js +559 -559
  152. package/lib/commands/config/delete.d.ts +18 -18
  153. package/lib/commands/config/delete.js +118 -118
  154. package/lib/commands/config/deploy.d.ts +22 -22
  155. package/lib/commands/config/deploy.js +124 -124
  156. package/lib/commands/config/import.d.ts +27 -27
  157. package/lib/commands/config/import.js +195 -195
  158. package/lib/commands/config/view.d.ts +25 -25
  159. package/lib/commands/config/view.js +120 -120
  160. package/lib/commands/csp/login.d.ts +18 -18
  161. package/lib/commands/csp/login.js +108 -108
  162. package/lib/commands/csp/logout.d.ts +15 -15
  163. package/lib/commands/csp/logout.js +73 -73
  164. package/lib/commands/dep/create.d.ts +13 -13
  165. package/lib/commands/dep/create.js +40 -40
  166. package/lib/commands/dep/install.d.ts +9 -9
  167. package/lib/commands/dep/install.js +29 -29
  168. package/lib/commands/dep/list.d.ts +55 -55
  169. package/lib/commands/dep/list.js +97 -97
  170. package/lib/commands/dep/remove.d.ts +12 -12
  171. package/lib/commands/dep/remove.js +61 -61
  172. package/lib/commands/dep/source.d.ts +13 -13
  173. package/lib/commands/dep/source.js +82 -82
  174. package/lib/commands/dep/syncup.d.ts +11 -11
  175. package/lib/commands/dep/syncup.js +53 -53
  176. package/lib/commands/dep/unsource.d.ts +14 -14
  177. package/lib/commands/dep/unsource.js +67 -67
  178. package/lib/commands/dep/upgrade.d.ts +44 -44
  179. package/lib/commands/dep/upgrade.js +243 -243
  180. package/lib/commands/dep.d.ts +12 -12
  181. package/lib/commands/dep.js +50 -50
  182. package/lib/commands/deploy.d.ts +38 -38
  183. package/lib/commands/deploy.js +382 -382
  184. package/lib/commands/enterprise/create.d.ts +20 -20
  185. package/lib/commands/enterprise/create.js +97 -97
  186. package/lib/commands/enterprise/list.d.ts +14 -14
  187. package/lib/commands/enterprise/list.js +83 -83
  188. package/lib/commands/env/add.d.ts +22 -22
  189. package/lib/commands/env/add.js +199 -199
  190. package/lib/commands/environment/create.d.ts +19 -19
  191. package/lib/commands/environment/create.js +88 -88
  192. package/lib/commands/environment/list.d.ts +25 -25
  193. package/lib/commands/environment/list.js +157 -157
  194. package/lib/commands/filestore/capture.d.ts +31 -31
  195. package/lib/commands/filestore/capture.js +341 -341
  196. package/lib/commands/host/map.d.ts +33 -33
  197. package/lib/commands/host/map.js +346 -346
  198. package/lib/commands/identity/delete.d.ts +15 -15
  199. package/lib/commands/identity/delete.js +82 -82
  200. package/lib/commands/identity/list.d.ts +11 -11
  201. package/lib/commands/identity/list.js +42 -42
  202. package/lib/commands/identity.d.ts +22 -22
  203. package/lib/commands/identity.js +76 -76
  204. package/lib/commands/imageRegistry/capture.d.ts +27 -27
  205. package/lib/commands/imageRegistry/capture.js +159 -159
  206. package/lib/commands/imageRegistry/forget.d.ts +23 -23
  207. package/lib/commands/imageRegistry/forget.js +160 -160
  208. package/lib/commands/imageRegistry/pullSecret/set.d.ts +27 -27
  209. package/lib/commands/imageRegistry/pullSecret/set.js +299 -299
  210. package/lib/commands/imageRegistry/pullSecret/unset.d.ts +24 -24
  211. package/lib/commands/imageRegistry/pullSecret/unset.js +242 -242
  212. package/lib/commands/images/add.d.ts +25 -25
  213. package/lib/commands/images/add.js +75 -75
  214. package/lib/commands/images/list.d.ts +14 -14
  215. package/lib/commands/images/list.js +71 -71
  216. package/lib/commands/images/patch.d.ts +14 -14
  217. package/lib/commands/images/patch.js +92 -92
  218. package/lib/commands/images/remove.d.ts +12 -12
  219. package/lib/commands/images/remove.js +37 -37
  220. package/lib/commands/images/version.d.ts +16 -16
  221. package/lib/commands/images/version.js +64 -64
  222. package/lib/commands/init.d.ts +17 -17
  223. package/lib/commands/init.js +130 -130
  224. package/lib/commands/kit/create.d.ts +25 -25
  225. package/lib/commands/kit/create.js +141 -141
  226. package/lib/commands/login.d.ts +22 -22
  227. package/lib/commands/login.js +92 -92
  228. package/lib/commands/logout.d.ts +8 -8
  229. package/lib/commands/logout.js +36 -36
  230. package/lib/commands/merge.d.ts +12 -12
  231. package/lib/commands/merge.js +42 -42
  232. package/lib/commands/noc/cluster/create.d.ts +28 -28
  233. package/lib/commands/noc/cluster/create.js +132 -132
  234. package/lib/commands/noc/cluster/deinit.d.ts +17 -17
  235. package/lib/commands/noc/cluster/deinit.js +116 -116
  236. package/lib/commands/noc/cluster/destroy.d.ts +20 -20
  237. package/lib/commands/noc/cluster/destroy.js +137 -137
  238. package/lib/commands/noc/cluster/forget.d.ts +16 -16
  239. package/lib/commands/noc/cluster/forget.js +136 -136
  240. package/lib/commands/noc/cluster/grant.d.ts +24 -24
  241. package/lib/commands/noc/cluster/grant.js +159 -159
  242. package/lib/commands/noc/cluster/init.d.ts +17 -17
  243. package/lib/commands/noc/cluster/init.js +116 -116
  244. package/lib/commands/noc/cluster/list.d.ts +21 -21
  245. package/lib/commands/noc/cluster/list.js +83 -83
  246. package/lib/commands/noc/cluster/recreate.d.ts +28 -28
  247. package/lib/commands/noc/cluster/recreate.js +185 -185
  248. package/lib/commands/pkg/add.d.ts +15 -15
  249. package/lib/commands/pkg/add.js +42 -42
  250. package/lib/commands/pkg/list.d.ts +9 -9
  251. package/lib/commands/pkg/list.js +32 -32
  252. package/lib/commands/pkg/patch.d.ts +13 -13
  253. package/lib/commands/pkg/patch.js +78 -78
  254. package/lib/commands/pkg/remove.d.ts +12 -12
  255. package/lib/commands/pkg/remove.js +69 -69
  256. package/lib/commands/portal.d.ts +11 -11
  257. package/lib/commands/portal.js +81 -81
  258. package/lib/commands/publish.d.ts +21 -21
  259. package/lib/commands/publish.js +51 -51
  260. package/lib/commands/pull.d.ts +13 -13
  261. package/lib/commands/pull.js +29 -29
  262. package/lib/commands/push.d.ts +13 -13
  263. package/lib/commands/push.js +29 -29
  264. package/lib/commands/run.d.ts +35 -35
  265. package/lib/commands/run.js +193 -193
  266. package/lib/commands/secretStore/capture.d.ts +27 -27
  267. package/lib/commands/secretStore/capture.js +174 -174
  268. package/lib/commands/secretStore/forget.d.ts +20 -20
  269. package/lib/commands/secretStore/forget.js +146 -146
  270. package/lib/commands/stage.d.ts +13 -13
  271. package/lib/commands/stage.js +64 -64
  272. package/lib/commands/stash.d.ts +13 -13
  273. package/lib/commands/stash.js +30 -30
  274. package/lib/commands/status.d.ts +12 -12
  275. package/lib/commands/status.js +48 -48
  276. package/lib/commands/stop.d.ts +10 -10
  277. package/lib/commands/stop.js +51 -51
  278. package/lib/commands/switch.d.ts +11 -11
  279. package/lib/commands/switch.js +41 -41
  280. package/lib/commands/sync.d.ts +14 -14
  281. package/lib/commands/sync.js +20 -20
  282. package/lib/commands/tenant/create.d.ts +27 -27
  283. package/lib/commands/tenant/create.js +119 -119
  284. package/lib/commands/tenant/switch.d.ts +24 -24
  285. package/lib/commands/tenant/switch.js +108 -108
  286. package/lib/commands/unstage.d.ts +12 -12
  287. package/lib/commands/unstage.js +57 -57
  288. package/lib/commands/view/dashboard.d.ts +17 -0
  289. package/lib/commands/view/dashboard.js +88 -0
  290. package/lib/commands/view/dashboard.js.map +1 -0
  291. package/lib/commands/view/pods.d.ts +14 -0
  292. package/lib/commands/view/pods.js +88 -0
  293. package/lib/commands/view/pods.js.map +1 -0
  294. package/lib/commands/whereami.d.ts +15 -15
  295. package/lib/commands/whereami.js +122 -122
  296. package/lib/commands/whoami.d.ts +8 -8
  297. package/lib/commands/whoami.js +39 -39
  298. package/lib/deployment.d.ts +2 -0
  299. package/lib/deployment.js +7 -0
  300. package/lib/deployment.js.map +1 -0
  301. package/lib/errors/NoMembershipError.d.ts +8 -8
  302. package/lib/errors/NoMembershipError.js +14 -14
  303. package/lib/index.d.ts +1 -1
  304. package/lib/index.js +16 -16
  305. package/lib/k8s-command-base.d.ts +60 -0
  306. package/lib/k8s-command-base.js +204 -0
  307. package/lib/k8s-command-base.js.map +1 -0
  308. package/lib/log-update-wrapper.d.ts +24 -24
  309. package/lib/log-update-wrapper.js +28 -28
  310. package/lib/log4js-logger.d.ts +26 -26
  311. package/lib/log4js-logger.js +137 -137
  312. package/lib/ops/INTERFACES_CLI.d.ts +3 -3
  313. package/lib/ops/INTERFACES_CLI.js +7 -7
  314. package/lib/ops/LocalOps.d.ts +444 -444
  315. package/lib/ops/LocalOps.js +3183 -3183
  316. package/lib/ops/azure-container-registry-client/azure-container-registry-client.js +147 -147
  317. package/lib/ops/cli-path-walker.js +54 -54
  318. package/lib/ops/codiac-entities/dependency.d.ts +5 -5
  319. package/lib/ops/codiac-entities/dependency.js +10 -10
  320. package/lib/ops/codiac-entities/index.d.ts +1 -1
  321. package/lib/ops/codiac-entities/index.js +4 -4
  322. package/lib/ops/composite-image-registry-client.js +73 -73
  323. package/lib/ops/data/cli-context-repo.d.ts +61 -61
  324. package/lib/ops/data/cli-context-repo.js +269 -269
  325. package/lib/ops/data/index.d.ts +2 -2
  326. package/lib/ops/data/index.js +5 -5
  327. package/lib/ops/data/npm-config-repo.d.ts +13 -13
  328. package/lib/ops/data/npm-config-repo.js +64 -64
  329. package/lib/ops/docker-config.js +130 -130
  330. package/lib/ops/docker-constants.js +21 -21
  331. package/lib/ops/docker-credentials-store.js +237 -237
  332. package/lib/ops/docker-registry-api-client/docker-registry-api-client.js +288 -288
  333. package/lib/ops/docker-registry-api-client/entities/blob-sum.d.ts +7 -7
  334. package/lib/ops/docker-registry-api-client/entities/blob-sum.js +12 -12
  335. package/lib/ops/docker-registry-api-client/entities/docker-access-actions-enum.d.ts +5 -5
  336. package/lib/ops/docker-registry-api-client/entities/docker-access-actions-enum.js +9 -9
  337. package/lib/ops/docker-registry-api-client/entities/docker-auth-token-criteria.d.ts +30 -30
  338. package/lib/ops/docker-registry-api-client/entities/docker-auth-token-criteria.js +35 -35
  339. package/lib/ops/docker-registry-api-client/entities/i-docker-error-response.d.ts +55 -55
  340. package/lib/ops/docker-registry-api-client/entities/i-docker-error-response.js +51 -51
  341. package/lib/ops/docker-registry-api-client/entities/i-docker-list-response.d.ts +7 -7
  342. package/lib/ops/docker-registry-api-client/entities/i-docker-list-response.js +2 -2
  343. package/lib/ops/docker-registry-api-client/entities/image-repository.d.ts +31 -31
  344. package/lib/ops/docker-registry-api-client/entities/image-repository.js +29 -29
  345. package/lib/ops/docker-registry-api-client/entities/image-tag-criteria.d.ts +8 -8
  346. package/lib/ops/docker-registry-api-client/entities/image-tag-criteria.js +13 -13
  347. package/lib/ops/docker-registry-api-client/entities/image-tag-list.d.ts +7 -7
  348. package/lib/ops/docker-registry-api-client/entities/image-tag-list.js +12 -12
  349. package/lib/ops/docker-registry-api-client/entities/manifest-criteria.d.ts +9 -9
  350. package/lib/ops/docker-registry-api-client/entities/manifest-criteria.js +14 -14
  351. package/lib/ops/docker-registry-api-client/entities/manifest.d.ts +15 -15
  352. package/lib/ops/docker-registry-api-client/entities/manifest.js +20 -20
  353. package/lib/ops/docker-registry-api-client/entities/repository-criteria.d.ts +16 -16
  354. package/lib/ops/docker-registry-api-client/entities/repository-criteria.js +23 -23
  355. package/lib/ops/docker-registry-api-client/entities/token-response.d.ts +15 -15
  356. package/lib/ops/docker-registry-api-client/entities/token-response.js +14 -14
  357. package/lib/ops/docker-registry-api-client/entities/token.d.ts +17 -17
  358. package/lib/ops/docker-registry-api-client/entities/token.js +21 -21
  359. package/lib/ops/docker-registry-api-client/entities/version-check-criteria.d.ts +4 -4
  360. package/lib/ops/docker-registry-api-client/entities/version-check-criteria.js +9 -9
  361. package/lib/ops/dx-constants.d.ts +26 -26
  362. package/lib/ops/dx-constants.js +42 -42
  363. package/lib/ops/entities/ImageBuildContext.d.ts +12 -12
  364. package/lib/ops/entities/ImageBuildContext.js +18 -18
  365. package/lib/ops/entities/PipelineContext.d.ts +21 -21
  366. package/lib/ops/entities/PipelineContext.js +22 -22
  367. package/lib/ops/entities/TenantContext.d.ts +10 -10
  368. package/lib/ops/entities/TenantContext.js +15 -15
  369. package/lib/ops/entities/ThaulConfig.js +29 -29
  370. package/lib/ops/entities/azure-service-principal.d.ts +23 -23
  371. package/lib/ops/entities/azure-service-principal.js +23 -23
  372. package/lib/ops/entities/better-logger.js +1 -1
  373. package/lib/ops/entities/branch.d.ts +13 -13
  374. package/lib/ops/entities/branch.js +15 -15
  375. package/lib/ops/entities/cli-config.d.ts +48 -48
  376. package/lib/ops/entities/cli-config.js +60 -60
  377. package/lib/ops/entities/docker-image.d.ts +60 -60
  378. package/lib/ops/entities/docker-image.js +2 -2
  379. package/lib/ops/entities/helm-spec.d.ts +15 -15
  380. package/lib/ops/entities/helm-spec.js +22 -22
  381. package/lib/ops/entities/index.d.ts +4 -4
  382. package/lib/ops/entities/index.js +11 -11
  383. package/lib/ops/entities/operation-meta.d.ts +8 -8
  384. package/lib/ops/entities/operation-meta.js +18 -18
  385. package/lib/ops/entities/scaffolding.d.ts +19 -19
  386. package/lib/ops/entities/scaffolding.js +20 -20
  387. package/lib/ops/extensions/azart-identity-adapter.d.ts +19 -19
  388. package/lib/ops/extensions/azart-identity-adapter.js +96 -96
  389. package/lib/ops/extensions/npm-identity-adapter-base.d.ts +13 -13
  390. package/lib/ops/extensions/npm-identity-adapter-base.js +2 -2
  391. package/lib/ops/extensions/npmjs-identity-adapter.d.ts +13 -13
  392. package/lib/ops/extensions/npmjs-identity-adapter.js +63 -63
  393. package/lib/ops/git-ops.d.ts +8 -8
  394. package/lib/ops/git-ops.js +13 -13
  395. package/lib/ops/i-client-for-image-registry.js +16 -16
  396. package/lib/ops/i-identity-handler.d.ts +33 -33
  397. package/lib/ops/i-identity-handler.js +164 -164
  398. package/lib/ops/i-output-styler.js +16 -16
  399. package/lib/ops/index.d.ts +12 -12
  400. package/lib/ops/index.js +14 -14
  401. package/lib/ops/json-utils.js +58 -58
  402. package/lib/ops/no-style-output-styler.js +29 -29
  403. package/lib/ops/oauth2-client.ts/oauth2-client.d.ts +23 -23
  404. package/lib/ops/oauth2-client.ts/oauth2-client.js +63 -63
  405. package/lib/ops/project-initializer.d.ts +36 -36
  406. package/lib/ops/project-initializer.js +218 -218
  407. package/lib/ops/scaffolding/base-scaffolding.d.ts +7 -7
  408. package/lib/ops/scaffolding/base-scaffolding.js +20 -20
  409. package/lib/ops/scaffolding/codiac-api-scaffolding.d.ts +7 -7
  410. package/lib/ops/scaffolding/codiac-api-scaffolding.js +63 -63
  411. package/lib/ops/scaffolding/typescript-scaffolding.d.ts +15 -15
  412. package/lib/ops/scaffolding/typescript-scaffolding.js +162 -162
  413. package/lib/ops/test/mock-ui.d.ts +26 -26
  414. package/lib/ops/test/mock-ui.js +87 -87
  415. package/lib/ops/test/test-extensions.d.ts +13 -13
  416. package/lib/ops/test/test-extensions.js +70 -70
  417. package/lib/ops/test/when-a-recursive-file-search-is-run.spec.d.ts +2 -2
  418. package/lib/ops/test/when-a-recursive-file-search-is-run.spec.js +54 -54
  419. package/lib/ops/test/when-git-branchline-is-attempted.spec.d.ts +2 -2
  420. package/lib/ops/test/when-git-branchline-is-attempted.spec.js +37 -37
  421. package/lib/ops/test/when-versions-are-parsed.spec.d.ts +2 -2
  422. package/lib/ops/test/when-versions-are-parsed.spec.js +59 -59
  423. package/lib/ops/throwing-user-input-provider.js +36 -36
  424. package/lib/prettify.d.ts +7 -7
  425. package/lib/prettify.js +23 -23
  426. package/lib/read-stdin.d.ts +2 -2
  427. package/lib/read-stdin.js +28 -28
  428. package/lib/relay/contracts/contracts.d.ts +207 -207
  429. package/lib/relay/contracts/contracts.js +229 -229
  430. package/lib/relay/data/aws-k8s-versions.d.ts +6 -0
  431. package/lib/relay/data/aws-k8s-versions.js +16 -0
  432. package/lib/relay/data/aws-k8s-versions.js.map +1 -0
  433. package/lib/relay/data/aws-node-types.d.ts +37 -0
  434. package/lib/relay/data/aws-node-types.js +4246 -0
  435. package/lib/relay/data/aws-node-types.js.map +1 -0
  436. package/lib/relay/data/aws-regions.d.ts +6 -0
  437. package/lib/relay/data/aws-regions.js +34 -0
  438. package/lib/relay/data/aws-regions.js.map +1 -0
  439. package/lib/relay/extended-relay-client.d.ts +27 -27
  440. package/lib/relay/extended-relay-client.js +27 -27
  441. package/lib/relay/relay-container.d.ts +41 -41
  442. package/lib/relay/relay-container.js +297 -297
  443. package/lib/relay/wsclient/relay-socket-listener.d.ts +68 -68
  444. package/lib/relay/wsclient/relay-socket-listener.js +164 -164
  445. package/lib/relay/wsclient/relay-websocket-client.d.ts +33 -33
  446. package/lib/relay/wsclient/relay-websocket-client.js +178 -178
  447. package/lib/relay/wsclient/rx-websocket-subject.d.ts +25 -25
  448. package/lib/relay/wsclient/rx-websocket-subject.js +133 -133
  449. package/lib/relay/wsclient/socket-contracts.d.ts +22 -22
  450. package/lib/relay/wsclient/socket-contracts.js +2 -2
  451. package/lib/standard-probes.d.ts +5 -5
  452. package/lib/standard-probes.js +21 -21
  453. package/lib/uilogic/build-configurator.d.ts +21 -21
  454. package/lib/uilogic/build-configurator.js +110 -110
  455. package/lib/uilogic/cloud-provider-contextualizer.d.ts +46 -46
  456. package/lib/uilogic/cloud-provider-contextualizer.js +193 -193
  457. package/lib/uilogic/cloud-resource-configurator-factory.d.ts +41 -41
  458. package/lib/uilogic/cloud-resource-configurator-factory.js +157 -157
  459. package/lib/uilogic/cloud-resource-configurators/aws-k8s-versions.d.ts +11 -0
  460. package/lib/uilogic/cloud-resource-configurators/aws-k8s-versions.js +16 -0
  461. package/lib/uilogic/cloud-resource-configurators/aws-k8s-versions.js.map +1 -0
  462. package/lib/uilogic/cloud-resource-configurators/aws-node-types.d.ts +5 -0
  463. package/lib/uilogic/cloud-resource-configurators/aws-node-types.js +536 -0
  464. package/lib/uilogic/cloud-resource-configurators/aws-node-types.js.map +1 -0
  465. package/lib/uilogic/cloud-resource-configurators/aws-regions.d.ts +10 -0
  466. package/lib/uilogic/cloud-resource-configurators/aws-regions.js +34 -0
  467. package/lib/uilogic/cloud-resource-configurators/aws-regions.js.map +1 -0
  468. package/lib/uilogic/cloud-resource-configurators/aws-resource-configurator.d.ts +38 -38
  469. package/lib/uilogic/cloud-resource-configurators/aws-resource-configurator.js +347 -347
  470. package/lib/uilogic/cloud-resource-configurators/az-acr-cli-authenticator.js +77 -77
  471. package/lib/uilogic/cloud-resource-configurators/az-interactive-login-configurator.d.ts +42 -42
  472. package/lib/uilogic/cloud-resource-configurators/az-interactive-login-configurator.js +247 -247
  473. package/lib/uilogic/cloud-resource-configurators/azure-resource-configurator.d.ts +110 -110
  474. package/lib/uilogic/cloud-resource-configurators/azure-resource-configurator.js +781 -781
  475. package/lib/uilogic/cloud-resource-configurators/azure-types.js +9 -9
  476. package/lib/uilogic/cloud-resource-configurators/docker-hub-resource-configurator.d.ts +24 -24
  477. package/lib/uilogic/cloud-resource-configurators/docker-hub-resource-configurator.js +105 -105
  478. package/lib/uilogic/cloud-resource-configurators/helm-resource-configurator.d.ts +16 -16
  479. package/lib/uilogic/cloud-resource-configurators/helm-resource-configurator.js +44 -44
  480. package/lib/uilogic/cloud-resource-configurators/unsupported-resource-configurator.d.ts +18 -18
  481. package/lib/uilogic/cloud-resource-configurators/unsupported-resource-configurator.js +61 -61
  482. package/lib/uilogic/enterprise-contextualizer.d.ts +76 -76
  483. package/lib/uilogic/enterprise-contextualizer.js +670 -670
  484. package/lib/uilogic/environment-contextualizer.d.ts +15 -15
  485. package/lib/uilogic/environment-contextualizer.js +42 -42
  486. package/lib/uilogic/i-cluster-configurator.d.ts +9 -9
  487. package/lib/uilogic/i-cluster-configurator.js +2 -2
  488. package/lib/uilogic/i-login-configurator.d.ts +6 -6
  489. package/lib/uilogic/i-login-configurator.js +2 -2
  490. package/lib/uilogic/i-registry-configurator.d.ts +6 -6
  491. package/lib/uilogic/i-registry-configurator.js +2 -2
  492. package/lib/uilogic/i-secret-store-configurator.d.ts +7 -7
  493. package/lib/uilogic/i-secret-store-configurator.js +2 -2
  494. package/lib/uilogic/image-configurator.d.ts +133 -133
  495. package/lib/uilogic/image-configurator.js +577 -577
  496. package/lib/uilogic/image-contextualizer.d.ts +24 -24
  497. package/lib/uilogic/image-contextualizer.js +89 -89
  498. package/lib/uilogic/image-registry-contextualizer.d.ts +28 -28
  499. package/lib/uilogic/image-registry-contextualizer.js +126 -126
  500. package/lib/uilogic/index.d.ts +9 -9
  501. package/lib/uilogic/index.js +13 -13
  502. package/lib/uilogic/prompt-select-fuzzy.js +138 -138
  503. package/lib/uilogic/render-methods.d.ts +12 -12
  504. package/lib/uilogic/render-methods.js +64 -64
  505. package/lib/uilogic/tenant-contextualizer.d.ts +79 -79
  506. package/lib/uilogic/tenant-contextualizer.js +573 -573
  507. package/lib/user-context-loader.d.ts +60 -60
  508. package/lib/user-context-loader.js +183 -183
  509. package/oclif.manifest.json +45 -1
  510. package/package.json +150 -150
  511. package/scaffolding/api/.gitignore-scaffolding +68 -68
  512. package/scaffolding/api/.vscode/launch.json +16 -16
  513. package/scaffolding/api/.vscode/settings.json +7 -7
  514. package/scaffolding/api/.vscode/tasks.json +15 -15
  515. package/scaffolding/api/src/app-config.json +2 -2
  516. package/scaffolding/api/src/index.ts-scaffolding +13 -13
  517. package/scaffolding/api/src/myApiDef.ts-scaffolding +25 -25
  518. package/scaffolding/default/.gitignore-scaffolding +2 -2
  519. package/scaffolding/typescript/.gitignore-scaffolding +69 -69
  520. package/scaffolding/typescript/.vscode/launch.json +16 -16
  521. package/scaffolding/typescript/.vscode/settings.json +7 -7
  522. package/scaffolding/typescript/.vscode/tasks.json +15 -15
@@ -1,671 +1,671 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EnterpriseContextualizer = void 0;
4
- const tslib_1 = require("tslib");
5
- const asset_binding_1 = require("../codiac-entities/asset-binding");
6
- const _ = require("lodash");
7
- const contracts_1 = require("../apis/codiac-api/contracts");
8
- // import { Enterprise, Asset, Image, ImageRegistry, AssetCriteria, EnterpriseCriteria, Cabinet, CabinetCriteria, ImageOSTypesEnum, CloudProviderEnum, ImageRegistryTypes } from '@codiac.io/codiac-domain';
9
- const codiac_relay_contracts_1 = require("@codiac.io/codiac-relay-contracts");
10
- const codiac_relay_contracts_2 = require("@codiac.io/codiac-relay-contracts");
11
- const contracts_2 = require("@codiac.io/codiac-common/contracts");
12
- // export declare type EnterpriseContext = { enterpriseCode: string, assetBindings?: AssetContext[]|undefined };
13
- // export declare type AssetContext = { image: ImageExport, incarnation: AssetBinding };
14
- /** Establishes a single Enterprise Asset as which to deploy an ImageExport. */
15
- class EnterpriseContextualizer {
16
- constructor(_tenantCode, _ops, relayClient, _codiacApi, _projCfg, _projUserCfg, _projCfgRepo, userContext, userContextManager, ui, styler, exitCli, logger) {
17
- this._tenantCode = _tenantCode;
18
- this._ops = _ops;
19
- this.relayClient = relayClient;
20
- this._codiacApi = _codiacApi;
21
- this._projCfg = _projCfg;
22
- this._projUserCfg = _projUserCfg;
23
- this._projCfgRepo = _projCfgRepo;
24
- this.userContext = userContext;
25
- this.userContextManager = userContextManager;
26
- this.ui = ui;
27
- this.styler = styler;
28
- this.exitCli = exitCli;
29
- this.logger = logger;
30
- this.takeDefaults = false;
31
- }
32
- /** Interacts with user to select an existing enterprise (or create one if none exist),
33
- * and persists it in the project user config.
34
- * NOTE: Clears Asset context if the user switches enterprises,
35
- * or keeps original with orignal asset context if user selects it. */
36
- establishEnterprise(requestedEnterpriseCode) {
37
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
38
- return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
39
- var _a, _b, _c, _d, _e;
40
- try {
41
- let eResult = yield this._codiacApi.Enterprise.tryReadMany({ all: true });
42
- if (eResult.error)
43
- throw new contracts_2.CodiacError(`Error reading enterprises: ${eResult.message}; ${eResult.error.message}`, eResult.error);
44
- if (!eResult.output || eResult.output.length == 0) {
45
- throw new contracts_2.CodiacError(`This tenant [${this._tenantCode}] does not have any enterprises defined. You need to create one to continue.`);
46
- // TODO: The contextualizer should walk them thru the enterprise setup.
47
- // eCode = await cli.prompt(`Enter a code for the enterprise (${eCode})`);
48
- // eCode = eCode.toLowercase().replace(/[^A-Za-z0-9-_]/g, "");
49
- // // TODO: We might use one more conf here to let em check for stray keystrokes (we enterprise codes are immutable)
50
- // let ep = new Enterprise(eCode);
51
- // let createResult = await this._codiacApi.Enterprise.tryCreate(ep);
52
- // if (createResult.Error) throw new CodiacError(`Error creating new enterprise [${ep.code}]: ${createResult.message||""}; ${createResult.error.message}`, createResult.error);
53
- }
54
- // -------------------------------------------------------------------
55
- // !!!! HELP !!!!
56
- // We're drowning in IF statments here!!
57
- //
58
- // It's the end of a looong day of a LOT of coding solutions,
59
- // and I cant summon an elegant path thru this...
60
- //
61
- // TODO: REFACTOR THIS INTO SOMETHING THAT LOOKS PROFESSIONAL.
62
- // -------------------------------------------------------------------
63
- // GET: proj THEN user
64
- 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;
65
- // Validate the requested enterprise
66
- let enterprise;
67
- if (requestedEnterpriseCode) {
68
- enterprise = eResult.output.find(e => e.code == requestedEnterpriseCode);
69
- }
70
- // Validate the enterprise set in the current project user context
71
- if (!enterprise) {
72
- if (originalCode !== undefined && originalCode !== "") {
73
- enterprise = eResult.output.find(e => e.code == originalCode);
74
- }
75
- }
76
- // Select the one and only
77
- if (!enterprise && eResult.output.length === 1) {
78
- enterprise = eResult.output[0];
79
- }
80
- // Prompt the user to select from the list of enterprises (for this tenant)
81
- let attempts = 4;
82
- while (!enterprise && attempts > 0) {
83
- let eCode = yield this.ui.promptSelect("enterpriseCode", "Select a target enterprise:", eResult.output.map(e => e.code));
84
- if (eCode)
85
- enterprise = eResult.output.find(e => e.code == eCode);
86
- attempts--;
87
- }
88
- if (!enterprise)
89
- throw new Error("Failed to select a target enterprise.");
90
- // We've got one now.
91
- if (originalCode !== undefined && originalCode !== "" && enterprise.code == originalCode) {
92
- // same as original. Do nothing
93
- }
94
- else {
95
- // new enterprise context
96
- this.userContext.currentEnterprise = { enterprise: enterprise.code };
97
- this.userContext.enterpriseContexts[this._tenantCode] = this.userContext.currentEnterprise;
98
- yield this.userContextManager.writeUserContext(this.userContext);
99
- // SET: user THEN proj
100
- if (this._projUserCfg && this._projCfgRepo) {
101
- this._projUserCfg.enterprise = new codiac_relay_contracts_1.ProjectEnterpriseBinding(this.userContext.currentEnterprise.enterprise);
102
- yield this._projCfgRepo.writeProjectUserConfig(this._projUserCfg);
103
- }
104
- }
105
- resolve(enterprise);
106
- }
107
- catch (err) {
108
- reject(err);
109
- }
110
- }));
111
- });
112
- }
113
- establishEnterpriseAsset(enterprise, suppressConfirmations) {
114
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
115
- return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
116
- var _a, _b;
117
- try {
118
- let assetName;
119
- // TODO: Consider using asset.code instead.
120
- // assetName = this._projUserCfg?.enterprise?.assetBindings ? this._projUserCfg?.enterprise?.assetBindings[0].incarnation?.assetName ?? this.userContext.currentEnterprise?.asset : this.userContext.currentEnterprise?.asset;
121
- // WITH PROJECT CONTEXT
122
- if (this._projCfg && this._projCfgRepo && (this._projCfg.images !== undefined && Object.keys(this._projCfg.images).length > 0)) {
123
- let assetContext = yield this.establishProjectAssetBinding(enterprise.code, enterprise.assets, this._projCfg, this._projCfgRepo, suppressConfirmations, (_a = this.userContext.currentEnterprise) === null || _a === void 0 ? void 0 : _a.asset);
124
- assetName = assetContext.incarnation.assetName;
125
- yield this.validateImageOs(assetContext, enterprise.assets);
126
- // TODO: This should come BEFORE establishBinding. This will require the new assetContextSwitching.
127
- // TODO: validate that requested assets exist. Dont auto-create them.
128
- // await this.validateAssetBinding(assetContext); // <---- BUT THIS SHD BE PART OF this.establishBinding()
129
- // which should include:
130
- // throw new CodiacError(`Requested Asset [${req.incarnation.assetName}] does not exist in the enterprise [${req.incarnation.enterprise}].`)
131
- let assets = yield this.createMissingAssets(enterprise.code, [assetContext]);
132
- }
133
- // WITH USER CONTEXT
134
- if (assetName === undefined || assetName === "") {
135
- if (this.userContext.currentEnterprise == undefined || this.userContext.currentEnterprise.enterprise !== enterprise.code) {
136
- // Make sure we are pointed to the given enterprise
137
- this.userContext.currentEnterprise = new codiac_relay_contracts_1.EnterprisePointer(enterprise.code);
138
- }
139
- if (this.userContext.currentEnterprise.asset !== undefined && this.userContext.currentEnterprise.asset !== "") {
140
- // Make sure current asset still exists in the enterprise record.
141
- assetName = (_b = enterprise.assets.find(a => a.name === this.userContext.currentEnterprise.asset)) === null || _b === void 0 ? void 0 : _b.name;
142
- }
143
- if (assetName === undefined || assetName === "") {
144
- // Prompt the user directly
145
- let choices = enterprise.assets.map(a => { return { name: a.name, value: a.name }; });
146
- assetName = (yield this.ui.promptSelect("assetName", "Asset: ", choices));
147
- }
148
- }
149
- else {
150
- // Save whatever was selected in the prject context
151
- }
152
- resolve(assetName);
153
- }
154
- catch (err) {
155
- reject(err);
156
- }
157
- }));
158
- });
159
- }
160
- /** This method WAS a copy from config:add */
161
- promptForTargetFile(enterprise, asset, defaultValue) {
162
- var _a;
163
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
164
- try {
165
- // 1. Build choices
166
- let crit = {
167
- asset: asset,
168
- enterprise: enterprise,
169
- type: contracts_1.ConfigDefTypesEnum.file
170
- };
171
- // let configs = await this._codiacApi.ConfigDef.readMany(crit, { throwNotFound: false, projection: { pathsExcluded: [], pathsIncluded: ["settings", "targetFile", "format"] } })
172
- let cfgResult = yield this._codiacApi.Call.getConfigDefs(crit, { projection: { pathsExcluded: [], pathsIncluded: ["settings", "targetFile", "format"] } });
173
- if (cfgResult.error)
174
- throw cfgResult.error;
175
- let configs = (_a = cfgResult.output) !== null && _a !== void 0 ? _a : [];
176
- if (configs.length === 0) {
177
- throw new Error(`The asset ${asset} has no config files defined.`);
178
- }
179
- let choices = configs.map(c => { return { name: c.targetFile, value: c.targetFile }; });
180
- // 2. Select the one-and-only
181
- /** If we changed the input they provided, we need their confirmation (whether or not they said takeDefaults) */
182
- let changedUserInput = false;
183
- if (choices.length === 1) {
184
- if (defaultValue != choices[0].value) {
185
- changedUserInput = !_.isEmpty(defaultValue);
186
- defaultValue = choices[0].value;
187
- this.ui.userMessage(`1 config file found: ${this.styler.hilite(defaultValue)}`);
188
- }
189
- }
190
- // 3. Confirm and/or Select
191
- let targetFile;
192
- let keep = this.takeDefaults;
193
- if (defaultValue && choices.find(x => x.value == defaultValue) && (changedUserInput || !this.takeDefaults)) {
194
- keep = yield this.ui.promptConfirm("keepTargetFile", `File: ${this.styler.hilite(defaultValue)}`, true);
195
- }
196
- targetFile = (defaultValue && keep === true) ? defaultValue : (yield this.ui.promptSelect("fileExisting", "File: ", choices));
197
- return targetFile;
198
- }
199
- catch (err) {
200
- throw err;
201
- }
202
- });
203
- }
204
- /** Throws when the image os does not match that of the image in the remote enterprise asset record.
205
- *
206
- * Throws any errors. */
207
- validateImageOs(localBinding, enterpriseAssets) {
208
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
209
- return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
210
- var _a, _b, _c;
211
- try {
212
- let assetRecord = enterpriseAssets.find(a => a.name == localBinding.incarnation.assetName);
213
- 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())) {
214
- 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.`);
215
- }
216
- resolve();
217
- }
218
- catch (err) {
219
- reject(err);
220
- }
221
- }));
222
- });
223
- }
224
- /** TODO: Ensures that the given assets exist in the api. */
225
- createMissingAssets(enterpriseCode, requestedAssets) {
226
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
227
- return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
228
- try {
229
- let assets = [];
230
- let crit = { code: enterpriseCode };
231
- let assetResult = yield this._codiacApi.Enterprise.tryReadMany(crit);
232
- if (assetResult.error) {
233
- throw new contracts_2.CodiacError(`Error querying enterprise to check for existing assets: ${assetResult.message || ""}; ${assetResult.error.message || ""}`, assetResult.error);
234
- }
235
- else if (!assetResult.success || !assetResult.output) {
236
- throw new contracts_2.CodiacError(`Unable to verify assets: enterprise [${crit.code}] was not found.`);
237
- }
238
- else {
239
- let enterprise = assetResult.output[0];
240
- let assets = enterprise.assets; // Deploy all of em unless the caller requested specific ones.
241
- if (requestedAssets && requestedAssets.length > 0) {
242
- // Get only the requested ones...
243
- // assets = enterprise.assets.filter(a => requestedAssets.find(ac => a.name == ac.incarnation.assetName));
244
- assets = [];
245
- let newAssets = [];
246
- for (let req of requestedAssets) {
247
- let epAsset = enterprise.assets.find(a => a.name == req.incarnation.assetName);
248
- if (epAsset) {
249
- assets.push(epAsset);
250
- }
251
- else {
252
- let newAsset = yield this.hackBuildAsset(req, enterprise);
253
- newAssets.push(newAsset);
254
- enterprise.assets.push(...newAssets);
255
- }
256
- }
257
- if (newAssets.length > 0) {
258
- let saveResult = yield this._codiacApi.Asset.tryCreateMany(newAssets);
259
- if (saveResult.error) {
260
- throw new contracts_2.CodiacError(`Error inserting missing enterprise assets [${newAssets.map(a => a.name).join(',')}]: ${saveResult.error.message || saveResult.message || ""}`, saveResult.error);
261
- }
262
- else if (!saveResult.success || !saveResult.successes || saveResult.successes.length == 0) {
263
- if (saveResult.failures && saveResult.failures.length > 0 && saveResult.failures.length < newAssets.length) {
264
- this.logger.debug(`Saving new assets yielded a partial failure.`);
265
- }
266
- throw new contracts_2.CodiacError(`Unable to save missing enterprise assets [${newAssets.map(a => a.name).join(',')}]: Returned failure without error. ${saveResult.message}`);
267
- }
268
- else {
269
- this.logger.debug(`Created missing assets: [${saveResult.successes.map(a => a.name).join(',')}]`);
270
- assets.push(...saveResult.successes);
271
- }
272
- }
273
- }
274
- }
275
- resolve(assets);
276
- }
277
- catch (err) {
278
- reject(err);
279
- }
280
- }));
281
- });
282
- }
283
- /** This is backwards - it should be impossible to have an asset binding to an asset that doesnt exist.
284
- * If somehow the project was still pointed to a since-deleted asset,
285
- * then it should still throw an error and allow the user to select an existing asset to bind/switch to.
286
- */
287
- hackBuildAsset(localDef, enterprise) {
288
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
289
- return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
290
- var _a, _b;
291
- try {
292
- let newAsset;
293
- let target;
294
- // no record for this asset in the enterprise yet.
295
- if (localDef.image.targets.length == 0) {
296
- // TODO: Use the default image target registry.
297
- // imgRegistry = new ImageRegistry("dockerhub", "https://index.docker.io/v1");
298
- target = new codiac_relay_contracts_1.RegistryTarget("default", EnterpriseContextualizer.DEFAULT_REGISTRY_URL);
299
- this.logger.detail(`No target image registry declared for image [${localDef.image.name}], using default at ${target.registryUrl}`);
300
- localDef.image.targets.push(target);
301
- }
302
- else {
303
- target = localDef.image.targets[0]; // <-- HACK!!! taking the first one. Confirm?
304
- }
305
- // COMMENTED OUT BECUASE let's just get it in there as a compositional entity
306
- // Go fetch the registry obj from the api
307
- // TODO: Consider making this a get-sert
308
- // let regCrit = <ImageRegistryCriteria>{ url: localDef.image.targets[0].registryUrl };
309
- // let imageRegResult = await this._codiacApi.ImageRegistry.tryReadMany(regCrit);
310
- // if (imageRegResult.error) {
311
- // throw new CodiacError(`Error retrieving ImageRegistry [${localDef.image.targets[0].registryUrl}] for image [${localDef.image.name}]: ${imageRegResult.error.message||imageRegResult.message||""}`, imageRegResult.error);
312
- // } else if (!imageRegResult.success || imageRegResult.output == undefined || imageRegResult.output.length == 0) {
313
- // throw new Error(`No registry currently exists with url: [${regCrit.url||""}] ${imageRegResult.message||""}`)
314
- // } else {
315
- // imgRegistry = imageRegResult.output[0];
316
- // let imgRegistry = new ImageRegistry(`${this._tenantCode}-${CloudProviderEnum}`, target.registryUrl, CloudProviderEnum.dockerHub, ImageRegistryTypes.DockerHub);
317
- let imgRegistry = {
318
- code: `${this._tenantCode}-${contracts_1.CloudProviderEnum}`,
319
- url: target.registryUrl,
320
- provider: contracts_1.CloudProviderEnum.dockerHub,
321
- type: contracts_1.ImageRegistryTypes.DockerHub
322
- };
323
- let audits = this.createAuditable();
324
- let img = Object.assign({ name: localDef.image.name, registry: imgRegistry }, audits);
325
- newAsset = Object.assign({ code: localDef.incarnation.assetName, name: localDef.incarnation.assetName, enterprise: enterprise.code, image: img, port: (_b = (_a = localDef.incarnation.port) !== null && _a !== void 0 ? _a : localDef.image.port) !== null && _b !== void 0 ? _b : 0, hasIngress: false, routedWithoutName: false }, audits);
326
- // TODO: Write to the enterprise? or throw? or ask?
327
- // }
328
- resolve(newAsset);
329
- }
330
- catch (err) {
331
- reject(err);
332
- }
333
- }));
334
- });
335
- }
336
- /** Selects a single ImageExport and a single incarnation of that image (aka: AssetBinding).
337
- * @param suppressConfirmations (Optional: defaults to false) Prevents confirmations of user-values that are remembered from prior runs.
338
- * @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.
339
- */
340
- establishProjectAssetBinding(enterpriseCode, assets, projCfg, projCfgRepo, suppressConfirmations, preferredAssetName) {
341
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
342
- return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
343
- var _a, _b, _c, _d;
344
- try {
345
- let allowAddingNewAssets = true;
346
- // STEP 1: Establish the ImageExport to use.
347
- let image;
348
- if (projCfg.images && !_.isEmpty(projCfg.images)) {
349
- let images = _.keysIn(projCfg.images);
350
- if (images.length == 1) {
351
- image = projCfg.images[images[0]];
352
- }
353
- else if (images.length > 0) {
354
- // Prompt the user to select one.
355
- // TODO: Default to the one selected in a previous execution,
356
- // and remember the selection for next time.
357
- let selection = yield this.ui.promptSelect('imageName', 'Image you are executing this command for...', images);
358
- if (!selection)
359
- throw new Error(`No image selected`);
360
- image = projCfg.images[selection];
361
- }
362
- else {
363
- // This clause is impossible to reach (bc we already did a _.isEmpty check).
364
- 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.`);
365
- }
366
- }
367
- else { // No image exports defined for the project
368
- 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.`);
369
- }
370
- let validBindings = assets
371
- .filter(a => a.image.name == image.name)
372
- .map(a => new asset_binding_1.AssetBinding(enterpriseCode, a.name, a.port));
373
- // STEP 2: Establish the AssetBinding
374
- let binding;
375
- // a: See if we've already got one selected (via the project user config)
376
- let remembered;
377
- 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);
378
- if (found && found.length > 0) {
379
- // Try to use preferred...
380
- if (preferredAssetName !== undefined && preferredAssetName !== "") {
381
- remembered = (_d = found.find(a => a.incarnation.assetName === preferredAssetName)) === null || _d === void 0 ? void 0 : _d.incarnation;
382
- }
383
- if (!remembered) {
384
- // Otherwise, just take the first valid binding we've remembered for that image
385
- remembered = found[0].incarnation;
386
- }
387
- }
388
- // a: Select and validate an existing binding
389
- if (remembered) {
390
- // We only care about the existing bindings we know are still valid in this enterprise
391
- // let existings = image.incarnations.filter(i => validBindings.find(v => v.enterprise == i.enterprise && v.assetName == i.assetName));
392
- if (validBindings.find(v => v.enterprise == remembered.enterprise && v.assetName == remembered.assetName)) {
393
- // confirm the remembered one only if they requested a selection
394
- if (!suppressConfirmations) {
395
- if (yield this.ui.promptConfirm("assetBinding", `Targeting asset: ${this.styler.bold(this.styler.hilite(remembered.enterprise + '/' + remembered.assetName))} ?`)) {
396
- binding = remembered;
397
- }
398
- }
399
- else {
400
- binding = remembered;
401
- }
402
- }
403
- // if (existings.length == 1) {
404
- // } else if (existings.length > 1) {
405
- // // select from existing
406
- // let choices = existings.map(e => e.assetName);
407
- // let selection = await this.ui.promptSelect("assetBinding", `Target asset (in enterprise: ${enterprise.code})...`, choices);
408
- // if (selection) binding = existings.find(a => a.assetName == selection);
409
- // }
410
- }
411
- // use preferred if it's valid (even tho it's not currently in proj user cfg)
412
- if (!binding) {
413
- binding = validBindings.find(b => b.assetName === preferredAssetName);
414
- }
415
- // b: Create a new Asset binding
416
- if (!binding) {
417
- let choices = validBindings.map((e, idx) => { return { name: e.assetName, value: idx }; });
418
- if (allowAddingNewAssets)
419
- choices.push({ name: EnterpriseContextualizer.CHOICE_VALUE_FOR_NEW, value: -1 });
420
- let selection = yield this.ui.promptSelect("assetBinding", `Target asset (in enterprise: ${enterpriseCode})...`, choices);
421
- if (!selection)
422
- throw new Error("Failed to select a target asset.");
423
- if (selection >= 0) {
424
- binding = validBindings[selection];
425
- }
426
- else {
427
- // Create a new Asset
428
- // TODO: Use the same UX code as asset:create
429
- let assetName = yield this.ui.prompt("asset", "Name for the Asset to be made from this image:", true, image.name);
430
- let assetCode = assetName; // TODO: Prompt with this default
431
- let assetPort = image.port || this.selectAvailableAssetPort(assets); // TODO: Prompt with this default
432
- let assetImg = yield this.createAssetImageRef(image);
433
- let newAsset = Object.assign({ enterprise: enterpriseCode, code: assetCode, name: assetName, image: assetImg, port: assetPort }, this.createAuditable());
434
- let createResult = yield this._codiacApi.Asset.tryCreate(newAsset);
435
- if (createResult.error)
436
- throw createResult.error;
437
- else if (!createResult.success || !createResult.output)
438
- throw new Error(`Failed creating new asset ${newAsset.name} in enterprise: ${newAsset.enterprise}: ${createResult.message}`);
439
- newAsset = createResult.output;
440
- this.logger.detail(`New Asset [${createResult.output.name}] Successfully created from image: [${createResult.output.image.name}] in enterprise [${createResult.output.enterprise}].`);
441
- binding = new asset_binding_1.AssetBinding(enterpriseCode, newAsset.name, newAsset.port);
442
- }
443
- }
444
- if (!binding)
445
- throw new Error("No asset binding was established.");
446
- // Write this selection to the proj user config
447
- if (!this._projUserCfg) {
448
- this._projUserCfg = new codiac_relay_contracts_1.ProjectUserConfig();
449
- }
450
- if (!this._projUserCfg.enterprise) {
451
- this._projUserCfg.enterprise = new codiac_relay_contracts_1.ProjectEnterpriseBinding(enterpriseCode);
452
- }
453
- if (!this._projUserCfg.enterprise.assetBindings)
454
- this._projUserCfg.enterprise.assetBindings = [];
455
- _.remove(this._projUserCfg.enterprise.assetBindings, ac => ac.image.name == image.name);
456
- this._projUserCfg.enterprise.assetBindings.push(new codiac_relay_contracts_1.AssetContext(image, binding));
457
- projCfgRepo.writeProjectUserConfig(this._projUserCfg);
458
- resolve({ image: image, incarnation: binding });
459
- }
460
- catch (err) {
461
- reject(err);
462
- }
463
- }));
464
- });
465
- }
466
- /** provdes a randpm port number that is not currently owned by any asset in the enterprise. */
467
- selectAvailableAssetPort(existingAssets) {
468
- let port = EnterpriseContextualizer.DEFAULT_ASSET_PORT_NUMBER;
469
- while (!port || existingAssets.find(a => a.port == port)) {
470
- port = _.random(1024, 65535, false);
471
- }
472
- return port;
473
- }
474
- /** Factory method for the image reference object on which an Asset is based. */
475
- createAssetImageRef(projectImage, targetEnvironment) {
476
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
477
- let registryEnv = targetEnvironment || "default";
478
- let registryTarget = projectImage.targets.find(t => t.environment == registryEnv);
479
- if (!registryTarget) {
480
- throw new Error(`The image export [${projectImage.name}] in the local project does not have a target registry declared for the [${registryEnv}] environment.`);
481
- }
482
- let pvdResult = yield this.relayClient.Call.getRegistryType({ registryUrl: registryTarget.registryUrl });
483
- if (pvdResult.error)
484
- throw pvdResult.error;
485
- if (pvdResult.output == undefined)
486
- throw new Error(`Did not recogize registry domain [${registryTarget.registryUrl}].`);
487
- let regInfo = pvdResult.output;
488
- // let regClient = this.regClientFactory.createForDomain(registryTarget.registryUrl);
489
- 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)
490
- let reg = Object.assign({ code: regCode, url: registryTarget.registryUrl, provider: regInfo.provider, type: regInfo.type }, this.createAuditable());
491
- let scope = (projectImage.name.indexOf("/") >= 0) ? projectImage.name.split("/")[0] : undefined;
492
- let img = Object.assign({ name: projectImage.name, registry: reg, scope: scope }, this.createAuditable());
493
- return img;
494
- });
495
- }
496
- /** Simply wraps establishCabinet() to return a CabinetScope.
497
- * TODO: EITHER get rid of this method altogether and use Cabinet instead of CabinetScope
498
- * OR Add ClusterName to CabinetScope (it's redundant, but it's important for gathering k8s cluster context without requerying the api)
499
- * @param suppressConfirmations (Optional: defaults to false) Prevents confirmations of user-values that are remembered from prior runs.
500
- */
501
- establishCabinetContext(requestedCabinet, suppressConfirmations, requestedEnviro) {
502
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
503
- return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
504
- try {
505
- let cabinet = yield this.establishCabinet(requestedCabinet, suppressConfirmations, requestedEnviro);
506
- let cabCntx = new codiac_relay_contracts_1.CabinetScope(cabinet.enterpriseCode, cabinet.environment, cabinet.name);
507
- this.logger.trace(`Cabinet context`, cabCntx);
508
- resolve(cabCntx);
509
- }
510
- catch (err) {
511
- reject(err);
512
- }
513
- }));
514
- });
515
- }
516
- /** Selects from existing cabinets.
517
- * Defaults to the cabinet declared in the project user config.
518
- * DOES NOT lazily create new cabinets OR build cabinet infrastructure!
519
- * This method only selects an existing cabinet
520
- * (because cabinet scope - eg: enterprises, environments, and cabinets -
521
- * should only be created deliberately and explicitly by their respective cli commands).
522
- * @param suppressConfirmations (Optional: defaults to false) Prevents confirmations of user-values that are remembered from prior runs.
523
- */
524
- establishCabinet(requestedCabinet, suppressConfirmations, requestedEnviro) {
525
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
526
- return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
527
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
528
- try {
529
- 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;
530
- if (enterpriseCode === undefined) {
531
- throw new contracts_2.CodiacError(`Cannot establish cabinet context: no enterprise is in context for the current user.`);
532
- }
533
- 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;
534
- let cabName = requestedCabinet !== null && requestedCabinet !== void 0 ? requestedCabinet : current;
535
- // -----------
536
- // let eCntx = this._projUserCfg?.enterprise ?? this.userContext.currentEnterprise;
537
- // if (eCntx == undefined || (<ProjectEnterpriseBinding>eCntx).enterpriseCode == undefined || (<EnterprisePointer>eCntx).enterprise == undefined) {
538
- // throw new CodiacError(`Cannot establish cabinet context: no enterprise is in context for the current user.`);
539
- // }
540
- // // Remember any existing context...
541
- // let enterpriseCode = eCntx.enterpriseCode;
542
- // let current = eCntx.cabinet?.cabinet;
543
- // let cabName: string | undefined = requestedCabinet;
544
- // if (!cabName) { // THIS because we dont have the nullish operator...
545
- // cabName = current;
546
- // }
547
- // -----------
548
- // let env: Environment;
549
- // let crit: EnvironmentCriteria = { all: true };
550
- // let envResult = await this._codiacApi.Environment.tryReadMany(crit);
551
- // if (envResult.error) {
552
- // throw new CodiacError(`Error attempting to retrieve environments: ${envResult.error.message||envResult.message||""}`, envResult.error);
553
- // } else if (envResult.count == 0 || !envResult.output || envResult.output.length == 0) {
554
- // throw new CodiacError(`No environments found: ${envResult.message||""}`);
555
- // } else if (envResult.output.length == 1) {
556
- // env = envResult.output[0];
557
- // } else {
558
- // // TODO: Let the user select which one, and remember his choice as a default for next time.
559
- // env = envResult.output[0]; // <--- HACK!!!!
560
- // }
561
- // if (env.cabinets.length == 0) {
562
- // throw new CodiacError(`No cabinets found for environment [${env.code}]. Use 'cod cabinet:create' to create one.`);
563
- // } else if (env.cabinets.length == 1) {
564
- // cab = env.cabinets[0].name; // TODO: Consider a confirmation here that the -y attrib will skip
565
- // } else {
566
- // // TODO: Let the user select which one, and remember his choice as a default for next time.
567
- // cab = env.cabinets[0].name; // <--- HACK!!!!
568
- // }
569
- let cabinet;
570
- let crit = { enterpriseCode: enterpriseCode };
571
- if (requestedEnviro !== undefined && requestedEnviro !== "") {
572
- crit.environment = requestedEnviro;
573
- }
574
- let cabResult = yield this._codiacApi.Cabinet.tryReadMany(crit); // <--- TODO: Consider injecting a RootMap instance instead of making api hits.
575
- if (cabResult.error) {
576
- throw new contracts_2.CodiacError(`Error checking for cabinets in enterprise [${enterpriseCode}]: ${cabResult.message || ""}; ${cabResult.error.message || cabResult.error.stack}`, cabResult.error);
577
- }
578
- else if (!cabResult.output || cabResult.output.length == 0) {
579
- throw new contracts_2.CodiacError(`No cabinets found for enterprise [${enterpriseCode}]. Use 'cod cabinet:create' to create a new cabinet. ${cabResult.message || ""}`);
580
- }
581
- else {
582
- let cabs = cabResult.output;
583
- // HERE'S THE UX GAUNTLET...
584
- let selection;
585
- if (cabName) {
586
- // This is where we validate that the requested/remembered cabinet is indeed/still in the current enterprise.
587
- // let found = cabs.find(c => c.name == cabName);
588
- // let found = cabs.findIndex(c => c.name == cabName);
589
- selection = cabs.findIndex(c => c.name == cabName);
590
- if (selection < 0) {
591
- this.logger.notice(`Cabinet [${cabName}] was not found in enterprise [${enterpriseCode}].`);
592
- this.ui.userMessage(`Cabinet [${cabName}] was not found in enterprise [${enterpriseCode}].`);
593
- }
594
- }
595
- // CI/CD support here
596
- if (suppressConfirmations && cabName) {
597
- cabinet = cabs.find(f => f.name == cabName);
598
- }
599
- let choices;
600
- while (!cabinet) {
601
- if (!selection || selection < 0) {
602
- if (cabs.length == 1) { // We're adding this to prevent two steps
603
- selection = 0;
604
- }
605
- else { // Let them choose
606
- choices = choices || cabs.map((c, index) => { return { name: `${c.name}${(cabs[index].name == current) ? " (current)" : ""}`, value: index }; });
607
- selection = (yield this.ui.promptSelect('cabIndex', `Select a cabinet [enterprise: ${this.styler.hilite(enterpriseCode)}]`, choices));
608
- }
609
- }
610
- let confResult = yield this.ui.promptConfirm('confirm', `Target cabinet: ${this.styler.hilite(enterpriseCode + "/" + cabs[selection].name)}`);
611
- if (confResult === true) { // TODO: Refactor these 3 confirms into 1
612
- // if (await this._ui.promptConfirm("targetCab", `Target cabinet (y/n): ${inOrange(cabs[selection].name)}`)) { // TODO: Refactor these 3 confirms into 1
613
- cabinet = cabs[selection];
614
- }
615
- else if (cabs.length == 1) { // We're adding this so we can avoid what would be two steps
616
- this.logger.notice(`Operation cancelled. That was the only cabinet available in enterprise [${enterpriseCode}].`);
617
- this.ui.userMessage(`Operation cancelled. That was the only cabinet available in enterprise [${enterpriseCode}].`);
618
- this.exitCli(0);
619
- }
620
- else {
621
- selection = undefined;
622
- }
623
- }
624
- }
625
- // PROJECT CONTEXT
626
- if (this._projCfg && this._projCfgRepo) {
627
- if (!this._projUserCfg)
628
- this._projUserCfg = new codiac_relay_contracts_1.ProjectUserConfig();
629
- if (this._projUserCfg.enterprise === undefined || this._projUserCfg.enterprise.enterpriseCode !== enterpriseCode) {
630
- this._projUserCfg.enterprise = new codiac_relay_contracts_1.ProjectEnterpriseBinding(enterpriseCode);
631
- }
632
- // Are we sure we wanna set the exact current branch? what if we're inheriting this cabinet from our branch lineage?
633
- let branch = yield this._ops.gitCurrentBranchNameFor(this._ops.getConfigRoot());
634
- this._projUserCfg.enterprise.cabinet = new codiac_relay_contracts_2.BranchBinding(branch, enterpriseCode, cabinet.name);
635
- this._projCfgRepo.writeProjectUserConfig(this._projUserCfg);
636
- }
637
- // USER CONTEXT
638
- if (this.userContext.currentEnterprise === undefined || this.userContext.currentEnterprise.enterprise !== enterpriseCode) {
639
- this.userContext.currentEnterprise = new codiac_relay_contracts_1.EnterprisePointer(enterpriseCode);
640
- }
641
- this.userContext.currentEnterprise.cabinet = cabinet.name;
642
- this.userContext.enterpriseContexts[this._tenantCode] = this.userContext.currentEnterprise;
643
- this.userContextManager.writeUserContext(this.userContext);
644
- this.logger.trace(`Cabinet`, cabinet);
645
- // let cabCntx = new CabinetScope(cabinet.enterpriseCode, cabinet.environment, cabinet.name)
646
- // this.logger.trace(`Cabinet context`, cabCntx)
647
- resolve(cabinet);
648
- }
649
- catch (err) {
650
- reject(err);
651
- }
652
- }));
653
- });
654
- }
655
- createAuditable() {
656
- let stamp = new Date(Date.now());
657
- return {
658
- created: stamp,
659
- createdBy: this.userContext.userName,
660
- modified: stamp,
661
- modifiedBy: this.userContext.userName
662
- };
663
- }
664
- }
665
- exports.EnterpriseContextualizer = EnterpriseContextualizer;
666
- /** The value in a select list prompt designating the user's choice
667
- * to create a new record instead of selecting from the existing choices. */
668
- EnterpriseContextualizer.CHOICE_VALUE_FOR_NEW = "** create new **";
669
- EnterpriseContextualizer.DEFAULT_REGISTRY_URL = "https://index.docker.io/v1";
670
- EnterpriseContextualizer.DEFAULT_ASSET_PORT_NUMBER = 1787;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EnterpriseContextualizer = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const asset_binding_1 = require("../codiac-entities/asset-binding");
6
+ const _ = require("lodash");
7
+ const contracts_1 = require("../apis/codiac-api/contracts");
8
+ // import { Enterprise, Asset, Image, ImageRegistry, AssetCriteria, EnterpriseCriteria, Cabinet, CabinetCriteria, ImageOSTypesEnum, CloudProviderEnum, ImageRegistryTypes } from '@codiac.io/codiac-domain';
9
+ const codiac_relay_contracts_1 = require("@codiac.io/codiac-relay-contracts");
10
+ const codiac_relay_contracts_2 = require("@codiac.io/codiac-relay-contracts");
11
+ const contracts_2 = require("@codiac.io/codiac-common/contracts");
12
+ // export declare type EnterpriseContext = { enterpriseCode: string, assetBindings?: AssetContext[]|undefined };
13
+ // export declare type AssetContext = { image: ImageExport, incarnation: AssetBinding };
14
+ /** Establishes a single Enterprise Asset as which to deploy an ImageExport. */
15
+ class EnterpriseContextualizer {
16
+ constructor(_tenantCode, _ops, relayClient, _codiacApi, _projCfg, _projUserCfg, _projCfgRepo, userContext, userContextManager, ui, styler, exitCli, logger) {
17
+ this._tenantCode = _tenantCode;
18
+ this._ops = _ops;
19
+ this.relayClient = relayClient;
20
+ this._codiacApi = _codiacApi;
21
+ this._projCfg = _projCfg;
22
+ this._projUserCfg = _projUserCfg;
23
+ this._projCfgRepo = _projCfgRepo;
24
+ this.userContext = userContext;
25
+ this.userContextManager = userContextManager;
26
+ this.ui = ui;
27
+ this.styler = styler;
28
+ this.exitCli = exitCli;
29
+ this.logger = logger;
30
+ this.takeDefaults = false;
31
+ }
32
+ /** Interacts with user to select an existing enterprise (or create one if none exist),
33
+ * and persists it in the project user config.
34
+ * NOTE: Clears Asset context if the user switches enterprises,
35
+ * or keeps original with orignal asset context if user selects it. */
36
+ establishEnterprise(requestedEnterpriseCode) {
37
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
38
+ return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
39
+ var _a, _b, _c, _d, _e;
40
+ try {
41
+ let eResult = yield this._codiacApi.Enterprise.tryReadMany({ all: true });
42
+ if (eResult.error)
43
+ throw new contracts_2.CodiacError(`Error reading enterprises: ${eResult.message}; ${eResult.error.message}`, eResult.error);
44
+ if (!eResult.output || eResult.output.length == 0) {
45
+ throw new contracts_2.CodiacError(`This tenant [${this._tenantCode}] does not have any enterprises defined. You need to create one to continue.`);
46
+ // TODO: The contextualizer should walk them thru the enterprise setup.
47
+ // eCode = await cli.prompt(`Enter a code for the enterprise (${eCode})`);
48
+ // eCode = eCode.toLowercase().replace(/[^A-Za-z0-9-_]/g, "");
49
+ // // TODO: We might use one more conf here to let em check for stray keystrokes (we enterprise codes are immutable)
50
+ // let ep = new Enterprise(eCode);
51
+ // let createResult = await this._codiacApi.Enterprise.tryCreate(ep);
52
+ // if (createResult.Error) throw new CodiacError(`Error creating new enterprise [${ep.code}]: ${createResult.message||""}; ${createResult.error.message}`, createResult.error);
53
+ }
54
+ // -------------------------------------------------------------------
55
+ // !!!! HELP !!!!
56
+ // We're drowning in IF statments here!!
57
+ //
58
+ // It's the end of a looong day of a LOT of coding solutions,
59
+ // and I cant summon an elegant path thru this...
60
+ //
61
+ // TODO: REFACTOR THIS INTO SOMETHING THAT LOOKS PROFESSIONAL.
62
+ // -------------------------------------------------------------------
63
+ // GET: proj THEN user
64
+ 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;
65
+ // Validate the requested enterprise
66
+ let enterprise;
67
+ if (requestedEnterpriseCode) {
68
+ enterprise = eResult.output.find(e => e.code == requestedEnterpriseCode);
69
+ }
70
+ // Validate the enterprise set in the current project user context
71
+ if (!enterprise) {
72
+ if (originalCode !== undefined && originalCode !== "") {
73
+ enterprise = eResult.output.find(e => e.code == originalCode);
74
+ }
75
+ }
76
+ // Select the one and only
77
+ if (!enterprise && eResult.output.length === 1) {
78
+ enterprise = eResult.output[0];
79
+ }
80
+ // Prompt the user to select from the list of enterprises (for this tenant)
81
+ let attempts = 4;
82
+ while (!enterprise && attempts > 0) {
83
+ let eCode = yield this.ui.promptSelect("enterpriseCode", "Select a target enterprise:", eResult.output.map(e => e.code));
84
+ if (eCode)
85
+ enterprise = eResult.output.find(e => e.code == eCode);
86
+ attempts--;
87
+ }
88
+ if (!enterprise)
89
+ throw new Error("Failed to select a target enterprise.");
90
+ // We've got one now.
91
+ if (originalCode !== undefined && originalCode !== "" && enterprise.code == originalCode) {
92
+ // same as original. Do nothing
93
+ }
94
+ else {
95
+ // new enterprise context
96
+ this.userContext.currentEnterprise = { enterprise: enterprise.code };
97
+ this.userContext.enterpriseContexts[this._tenantCode] = this.userContext.currentEnterprise;
98
+ yield this.userContextManager.writeUserContext(this.userContext);
99
+ // SET: user THEN proj
100
+ if (this._projUserCfg && this._projCfgRepo) {
101
+ this._projUserCfg.enterprise = new codiac_relay_contracts_1.ProjectEnterpriseBinding(this.userContext.currentEnterprise.enterprise);
102
+ yield this._projCfgRepo.writeProjectUserConfig(this._projUserCfg);
103
+ }
104
+ }
105
+ resolve(enterprise);
106
+ }
107
+ catch (err) {
108
+ reject(err);
109
+ }
110
+ }));
111
+ });
112
+ }
113
+ establishEnterpriseAsset(enterprise, suppressConfirmations) {
114
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
115
+ return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
116
+ var _a, _b;
117
+ try {
118
+ let assetName;
119
+ // TODO: Consider using asset.code instead.
120
+ // assetName = this._projUserCfg?.enterprise?.assetBindings ? this._projUserCfg?.enterprise?.assetBindings[0].incarnation?.assetName ?? this.userContext.currentEnterprise?.asset : this.userContext.currentEnterprise?.asset;
121
+ // WITH PROJECT CONTEXT
122
+ if (this._projCfg && this._projCfgRepo && (this._projCfg.images !== undefined && Object.keys(this._projCfg.images).length > 0)) {
123
+ let assetContext = yield this.establishProjectAssetBinding(enterprise.code, enterprise.assets, this._projCfg, this._projCfgRepo, suppressConfirmations, (_a = this.userContext.currentEnterprise) === null || _a === void 0 ? void 0 : _a.asset);
124
+ assetName = assetContext.incarnation.assetName;
125
+ yield this.validateImageOs(assetContext, enterprise.assets);
126
+ // TODO: This should come BEFORE establishBinding. This will require the new assetContextSwitching.
127
+ // TODO: validate that requested assets exist. Dont auto-create them.
128
+ // await this.validateAssetBinding(assetContext); // <---- BUT THIS SHD BE PART OF this.establishBinding()
129
+ // which should include:
130
+ // throw new CodiacError(`Requested Asset [${req.incarnation.assetName}] does not exist in the enterprise [${req.incarnation.enterprise}].`)
131
+ let assets = yield this.createMissingAssets(enterprise.code, [assetContext]);
132
+ }
133
+ // WITH USER CONTEXT
134
+ if (assetName === undefined || assetName === "") {
135
+ if (this.userContext.currentEnterprise == undefined || this.userContext.currentEnterprise.enterprise !== enterprise.code) {
136
+ // Make sure we are pointed to the given enterprise
137
+ this.userContext.currentEnterprise = new codiac_relay_contracts_1.EnterprisePointer(enterprise.code);
138
+ }
139
+ if (this.userContext.currentEnterprise.asset !== undefined && this.userContext.currentEnterprise.asset !== "") {
140
+ // Make sure current asset still exists in the enterprise record.
141
+ assetName = (_b = enterprise.assets.find(a => a.name === this.userContext.currentEnterprise.asset)) === null || _b === void 0 ? void 0 : _b.name;
142
+ }
143
+ if (assetName === undefined || assetName === "") {
144
+ // Prompt the user directly
145
+ let choices = enterprise.assets.map(a => { return { name: a.name, value: a.name }; });
146
+ assetName = (yield this.ui.promptSelect("assetName", "Asset: ", choices));
147
+ }
148
+ }
149
+ else {
150
+ // Save whatever was selected in the prject context
151
+ }
152
+ resolve(assetName);
153
+ }
154
+ catch (err) {
155
+ reject(err);
156
+ }
157
+ }));
158
+ });
159
+ }
160
+ /** This method WAS a copy from config:add */
161
+ promptForTargetFile(enterprise, asset, defaultValue) {
162
+ var _a;
163
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
164
+ try {
165
+ // 1. Build choices
166
+ let crit = {
167
+ asset: asset,
168
+ enterprise: enterprise,
169
+ type: contracts_1.ConfigDefTypesEnum.file
170
+ };
171
+ // let configs = await this._codiacApi.ConfigDef.readMany(crit, { throwNotFound: false, projection: { pathsExcluded: [], pathsIncluded: ["settings", "targetFile", "format"] } })
172
+ let cfgResult = yield this._codiacApi.Call.getConfigDefs(crit, { projection: { pathsExcluded: [], pathsIncluded: ["settings", "targetFile", "format"] } });
173
+ if (cfgResult.error)
174
+ throw cfgResult.error;
175
+ let configs = (_a = cfgResult.output) !== null && _a !== void 0 ? _a : [];
176
+ if (configs.length === 0) {
177
+ throw new Error(`The asset ${asset} has no config files defined.`);
178
+ }
179
+ let choices = configs.map(c => { return { name: c.targetFile, value: c.targetFile }; });
180
+ // 2. Select the one-and-only
181
+ /** If we changed the input they provided, we need their confirmation (whether or not they said takeDefaults) */
182
+ let changedUserInput = false;
183
+ if (choices.length === 1) {
184
+ if (defaultValue != choices[0].value) {
185
+ changedUserInput = !_.isEmpty(defaultValue);
186
+ defaultValue = choices[0].value;
187
+ this.ui.userMessage(`1 config file found: ${this.styler.hilite(defaultValue)}`);
188
+ }
189
+ }
190
+ // 3. Confirm and/or Select
191
+ let targetFile;
192
+ let keep = this.takeDefaults;
193
+ if (defaultValue && choices.find(x => x.value == defaultValue) && (changedUserInput || !this.takeDefaults)) {
194
+ keep = yield this.ui.promptConfirm("keepTargetFile", `File: ${this.styler.hilite(defaultValue)}`, true);
195
+ }
196
+ targetFile = (defaultValue && keep === true) ? defaultValue : (yield this.ui.promptSelect("fileExisting", "File: ", choices));
197
+ return targetFile;
198
+ }
199
+ catch (err) {
200
+ throw err;
201
+ }
202
+ });
203
+ }
204
+ /** Throws when the image os does not match that of the image in the remote enterprise asset record.
205
+ *
206
+ * Throws any errors. */
207
+ validateImageOs(localBinding, enterpriseAssets) {
208
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
209
+ return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
210
+ var _a, _b, _c;
211
+ try {
212
+ let assetRecord = enterpriseAssets.find(a => a.name == localBinding.incarnation.assetName);
213
+ 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())) {
214
+ 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.`);
215
+ }
216
+ resolve();
217
+ }
218
+ catch (err) {
219
+ reject(err);
220
+ }
221
+ }));
222
+ });
223
+ }
224
+ /** TODO: Ensures that the given assets exist in the api. */
225
+ createMissingAssets(enterpriseCode, requestedAssets) {
226
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
227
+ return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
228
+ try {
229
+ let assets = [];
230
+ let crit = { code: enterpriseCode };
231
+ let assetResult = yield this._codiacApi.Enterprise.tryReadMany(crit);
232
+ if (assetResult.error) {
233
+ throw new contracts_2.CodiacError(`Error querying enterprise to check for existing assets: ${assetResult.message || ""}; ${assetResult.error.message || ""}`, assetResult.error);
234
+ }
235
+ else if (!assetResult.success || !assetResult.output) {
236
+ throw new contracts_2.CodiacError(`Unable to verify assets: enterprise [${crit.code}] was not found.`);
237
+ }
238
+ else {
239
+ let enterprise = assetResult.output[0];
240
+ let assets = enterprise.assets; // Deploy all of em unless the caller requested specific ones.
241
+ if (requestedAssets && requestedAssets.length > 0) {
242
+ // Get only the requested ones...
243
+ // assets = enterprise.assets.filter(a => requestedAssets.find(ac => a.name == ac.incarnation.assetName));
244
+ assets = [];
245
+ let newAssets = [];
246
+ for (let req of requestedAssets) {
247
+ let epAsset = enterprise.assets.find(a => a.name == req.incarnation.assetName);
248
+ if (epAsset) {
249
+ assets.push(epAsset);
250
+ }
251
+ else {
252
+ let newAsset = yield this.hackBuildAsset(req, enterprise);
253
+ newAssets.push(newAsset);
254
+ enterprise.assets.push(...newAssets);
255
+ }
256
+ }
257
+ if (newAssets.length > 0) {
258
+ let saveResult = yield this._codiacApi.Asset.tryCreateMany(newAssets);
259
+ if (saveResult.error) {
260
+ throw new contracts_2.CodiacError(`Error inserting missing enterprise assets [${newAssets.map(a => a.name).join(',')}]: ${saveResult.error.message || saveResult.message || ""}`, saveResult.error);
261
+ }
262
+ else if (!saveResult.success || !saveResult.successes || saveResult.successes.length == 0) {
263
+ if (saveResult.failures && saveResult.failures.length > 0 && saveResult.failures.length < newAssets.length) {
264
+ this.logger.debug(`Saving new assets yielded a partial failure.`);
265
+ }
266
+ throw new contracts_2.CodiacError(`Unable to save missing enterprise assets [${newAssets.map(a => a.name).join(',')}]: Returned failure without error. ${saveResult.message}`);
267
+ }
268
+ else {
269
+ this.logger.debug(`Created missing assets: [${saveResult.successes.map(a => a.name).join(',')}]`);
270
+ assets.push(...saveResult.successes);
271
+ }
272
+ }
273
+ }
274
+ }
275
+ resolve(assets);
276
+ }
277
+ catch (err) {
278
+ reject(err);
279
+ }
280
+ }));
281
+ });
282
+ }
283
+ /** This is backwards - it should be impossible to have an asset binding to an asset that doesnt exist.
284
+ * If somehow the project was still pointed to a since-deleted asset,
285
+ * then it should still throw an error and allow the user to select an existing asset to bind/switch to.
286
+ */
287
+ hackBuildAsset(localDef, enterprise) {
288
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
289
+ return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
290
+ var _a, _b;
291
+ try {
292
+ let newAsset;
293
+ let target;
294
+ // no record for this asset in the enterprise yet.
295
+ if (localDef.image.targets.length == 0) {
296
+ // TODO: Use the default image target registry.
297
+ // imgRegistry = new ImageRegistry("dockerhub", "https://index.docker.io/v1");
298
+ target = new codiac_relay_contracts_1.RegistryTarget("default", EnterpriseContextualizer.DEFAULT_REGISTRY_URL);
299
+ this.logger.detail(`No target image registry declared for image [${localDef.image.name}], using default at ${target.registryUrl}`);
300
+ localDef.image.targets.push(target);
301
+ }
302
+ else {
303
+ target = localDef.image.targets[0]; // <-- HACK!!! taking the first one. Confirm?
304
+ }
305
+ // COMMENTED OUT BECUASE let's just get it in there as a compositional entity
306
+ // Go fetch the registry obj from the api
307
+ // TODO: Consider making this a get-sert
308
+ // let regCrit = <ImageRegistryCriteria>{ url: localDef.image.targets[0].registryUrl };
309
+ // let imageRegResult = await this._codiacApi.ImageRegistry.tryReadMany(regCrit);
310
+ // if (imageRegResult.error) {
311
+ // throw new CodiacError(`Error retrieving ImageRegistry [${localDef.image.targets[0].registryUrl}] for image [${localDef.image.name}]: ${imageRegResult.error.message||imageRegResult.message||""}`, imageRegResult.error);
312
+ // } else if (!imageRegResult.success || imageRegResult.output == undefined || imageRegResult.output.length == 0) {
313
+ // throw new Error(`No registry currently exists with url: [${regCrit.url||""}] ${imageRegResult.message||""}`)
314
+ // } else {
315
+ // imgRegistry = imageRegResult.output[0];
316
+ // let imgRegistry = new ImageRegistry(`${this._tenantCode}-${CloudProviderEnum}`, target.registryUrl, CloudProviderEnum.dockerHub, ImageRegistryTypes.DockerHub);
317
+ let imgRegistry = {
318
+ code: `${this._tenantCode}-${contracts_1.CloudProviderEnum}`,
319
+ url: target.registryUrl,
320
+ provider: contracts_1.CloudProviderEnum.dockerHub,
321
+ type: contracts_1.ImageRegistryTypes.DockerHub
322
+ };
323
+ let audits = this.createAuditable();
324
+ let img = Object.assign({ name: localDef.image.name, registry: imgRegistry }, audits);
325
+ newAsset = Object.assign({ code: localDef.incarnation.assetName, name: localDef.incarnation.assetName, enterprise: enterprise.code, image: img, port: (_b = (_a = localDef.incarnation.port) !== null && _a !== void 0 ? _a : localDef.image.port) !== null && _b !== void 0 ? _b : 0, hasIngress: false, routedWithoutName: false }, audits);
326
+ // TODO: Write to the enterprise? or throw? or ask?
327
+ // }
328
+ resolve(newAsset);
329
+ }
330
+ catch (err) {
331
+ reject(err);
332
+ }
333
+ }));
334
+ });
335
+ }
336
+ /** Selects a single ImageExport and a single incarnation of that image (aka: AssetBinding).
337
+ * @param suppressConfirmations (Optional: defaults to false) Prevents confirmations of user-values that are remembered from prior runs.
338
+ * @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.
339
+ */
340
+ establishProjectAssetBinding(enterpriseCode, assets, projCfg, projCfgRepo, suppressConfirmations, preferredAssetName) {
341
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
342
+ return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
343
+ var _a, _b, _c, _d;
344
+ try {
345
+ let allowAddingNewAssets = true;
346
+ // STEP 1: Establish the ImageExport to use.
347
+ let image;
348
+ if (projCfg.images && !_.isEmpty(projCfg.images)) {
349
+ let images = _.keysIn(projCfg.images);
350
+ if (images.length == 1) {
351
+ image = projCfg.images[images[0]];
352
+ }
353
+ else if (images.length > 0) {
354
+ // Prompt the user to select one.
355
+ // TODO: Default to the one selected in a previous execution,
356
+ // and remember the selection for next time.
357
+ let selection = yield this.ui.promptSelect('imageName', 'Image you are executing this command for...', images);
358
+ if (!selection)
359
+ throw new Error(`No image selected`);
360
+ image = projCfg.images[selection];
361
+ }
362
+ else {
363
+ // This clause is impossible to reach (bc we already did a _.isEmpty check).
364
+ 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.`);
365
+ }
366
+ }
367
+ else { // No image exports defined for the project
368
+ 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.`);
369
+ }
370
+ let validBindings = assets
371
+ .filter(a => a.image.name == image.name)
372
+ .map(a => new asset_binding_1.AssetBinding(enterpriseCode, a.name, a.port));
373
+ // STEP 2: Establish the AssetBinding
374
+ let binding;
375
+ // a: See if we've already got one selected (via the project user config)
376
+ let remembered;
377
+ 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);
378
+ if (found && found.length > 0) {
379
+ // Try to use preferred...
380
+ if (preferredAssetName !== undefined && preferredAssetName !== "") {
381
+ remembered = (_d = found.find(a => a.incarnation.assetName === preferredAssetName)) === null || _d === void 0 ? void 0 : _d.incarnation;
382
+ }
383
+ if (!remembered) {
384
+ // Otherwise, just take the first valid binding we've remembered for that image
385
+ remembered = found[0].incarnation;
386
+ }
387
+ }
388
+ // a: Select and validate an existing binding
389
+ if (remembered) {
390
+ // We only care about the existing bindings we know are still valid in this enterprise
391
+ // let existings = image.incarnations.filter(i => validBindings.find(v => v.enterprise == i.enterprise && v.assetName == i.assetName));
392
+ if (validBindings.find(v => v.enterprise == remembered.enterprise && v.assetName == remembered.assetName)) {
393
+ // confirm the remembered one only if they requested a selection
394
+ if (!suppressConfirmations) {
395
+ if (yield this.ui.promptConfirm("assetBinding", `Targeting asset: ${this.styler.bold(this.styler.hilite(remembered.enterprise + '/' + remembered.assetName))} ?`)) {
396
+ binding = remembered;
397
+ }
398
+ }
399
+ else {
400
+ binding = remembered;
401
+ }
402
+ }
403
+ // if (existings.length == 1) {
404
+ // } else if (existings.length > 1) {
405
+ // // select from existing
406
+ // let choices = existings.map(e => e.assetName);
407
+ // let selection = await this.ui.promptSelect("assetBinding", `Target asset (in enterprise: ${enterprise.code})...`, choices);
408
+ // if (selection) binding = existings.find(a => a.assetName == selection);
409
+ // }
410
+ }
411
+ // use preferred if it's valid (even tho it's not currently in proj user cfg)
412
+ if (!binding) {
413
+ binding = validBindings.find(b => b.assetName === preferredAssetName);
414
+ }
415
+ // b: Create a new Asset binding
416
+ if (!binding) {
417
+ let choices = validBindings.map((e, idx) => { return { name: e.assetName, value: idx }; });
418
+ if (allowAddingNewAssets)
419
+ choices.push({ name: EnterpriseContextualizer.CHOICE_VALUE_FOR_NEW, value: -1 });
420
+ let selection = yield this.ui.promptSelect("assetBinding", `Target asset (in enterprise: ${enterpriseCode})...`, choices);
421
+ if (!selection)
422
+ throw new Error("Failed to select a target asset.");
423
+ if (selection >= 0) {
424
+ binding = validBindings[selection];
425
+ }
426
+ else {
427
+ // Create a new Asset
428
+ // TODO: Use the same UX code as asset:create
429
+ let assetName = yield this.ui.prompt("asset", "Name for the Asset to be made from this image:", true, image.name);
430
+ let assetCode = assetName; // TODO: Prompt with this default
431
+ let assetPort = image.port || this.selectAvailableAssetPort(assets); // TODO: Prompt with this default
432
+ let assetImg = yield this.createAssetImageRef(image);
433
+ let newAsset = Object.assign({ enterprise: enterpriseCode, code: assetCode, name: assetName, image: assetImg, port: assetPort }, this.createAuditable());
434
+ let createResult = yield this._codiacApi.Asset.tryCreate(newAsset);
435
+ if (createResult.error)
436
+ throw createResult.error;
437
+ else if (!createResult.success || !createResult.output)
438
+ throw new Error(`Failed creating new asset ${newAsset.name} in enterprise: ${newAsset.enterprise}: ${createResult.message}`);
439
+ newAsset = createResult.output;
440
+ this.logger.detail(`New Asset [${createResult.output.name}] Successfully created from image: [${createResult.output.image.name}] in enterprise [${createResult.output.enterprise}].`);
441
+ binding = new asset_binding_1.AssetBinding(enterpriseCode, newAsset.name, newAsset.port);
442
+ }
443
+ }
444
+ if (!binding)
445
+ throw new Error("No asset binding was established.");
446
+ // Write this selection to the proj user config
447
+ if (!this._projUserCfg) {
448
+ this._projUserCfg = new codiac_relay_contracts_1.ProjectUserConfig();
449
+ }
450
+ if (!this._projUserCfg.enterprise) {
451
+ this._projUserCfg.enterprise = new codiac_relay_contracts_1.ProjectEnterpriseBinding(enterpriseCode);
452
+ }
453
+ if (!this._projUserCfg.enterprise.assetBindings)
454
+ this._projUserCfg.enterprise.assetBindings = [];
455
+ _.remove(this._projUserCfg.enterprise.assetBindings, ac => ac.image.name == image.name);
456
+ this._projUserCfg.enterprise.assetBindings.push(new codiac_relay_contracts_1.AssetContext(image, binding));
457
+ projCfgRepo.writeProjectUserConfig(this._projUserCfg);
458
+ resolve({ image: image, incarnation: binding });
459
+ }
460
+ catch (err) {
461
+ reject(err);
462
+ }
463
+ }));
464
+ });
465
+ }
466
+ /** provdes a randpm port number that is not currently owned by any asset in the enterprise. */
467
+ selectAvailableAssetPort(existingAssets) {
468
+ let port = EnterpriseContextualizer.DEFAULT_ASSET_PORT_NUMBER;
469
+ while (!port || existingAssets.find(a => a.port == port)) {
470
+ port = _.random(1024, 65535, false);
471
+ }
472
+ return port;
473
+ }
474
+ /** Factory method for the image reference object on which an Asset is based. */
475
+ createAssetImageRef(projectImage, targetEnvironment) {
476
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
477
+ let registryEnv = targetEnvironment || "default";
478
+ let registryTarget = projectImage.targets.find(t => t.environment == registryEnv);
479
+ if (!registryTarget) {
480
+ throw new Error(`The image export [${projectImage.name}] in the local project does not have a target registry declared for the [${registryEnv}] environment.`);
481
+ }
482
+ let pvdResult = yield this.relayClient.Call.getRegistryType({ registryUrl: registryTarget.registryUrl });
483
+ if (pvdResult.error)
484
+ throw pvdResult.error;
485
+ if (pvdResult.output == undefined)
486
+ throw new Error(`Did not recogize registry domain [${registryTarget.registryUrl}].`);
487
+ let regInfo = pvdResult.output;
488
+ // let regClient = this.regClientFactory.createForDomain(registryTarget.registryUrl);
489
+ 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)
490
+ let reg = Object.assign({ code: regCode, url: registryTarget.registryUrl, provider: regInfo.provider, type: regInfo.type }, this.createAuditable());
491
+ let scope = (projectImage.name.indexOf("/") >= 0) ? projectImage.name.split("/")[0] : undefined;
492
+ let img = Object.assign({ name: projectImage.name, registry: reg, scope: scope }, this.createAuditable());
493
+ return img;
494
+ });
495
+ }
496
+ /** Simply wraps establishCabinet() to return a CabinetScope.
497
+ * TODO: EITHER get rid of this method altogether and use Cabinet instead of CabinetScope
498
+ * OR Add ClusterName to CabinetScope (it's redundant, but it's important for gathering k8s cluster context without requerying the api)
499
+ * @param suppressConfirmations (Optional: defaults to false) Prevents confirmations of user-values that are remembered from prior runs.
500
+ */
501
+ establishCabinetContext(requestedCabinet, suppressConfirmations, requestedEnviro) {
502
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
503
+ return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
504
+ try {
505
+ let cabinet = yield this.establishCabinet(requestedCabinet, suppressConfirmations, requestedEnviro);
506
+ let cabCntx = new codiac_relay_contracts_1.CabinetScope(cabinet.enterpriseCode, cabinet.environment, cabinet.name);
507
+ this.logger.trace(`Cabinet context`, cabCntx);
508
+ resolve(cabCntx);
509
+ }
510
+ catch (err) {
511
+ reject(err);
512
+ }
513
+ }));
514
+ });
515
+ }
516
+ /** Selects from existing cabinets.
517
+ * Defaults to the cabinet declared in the project user config.
518
+ * DOES NOT lazily create new cabinets OR build cabinet infrastructure!
519
+ * This method only selects an existing cabinet
520
+ * (because cabinet scope - eg: enterprises, environments, and cabinets -
521
+ * should only be created deliberately and explicitly by their respective cli commands).
522
+ * @param suppressConfirmations (Optional: defaults to false) Prevents confirmations of user-values that are remembered from prior runs.
523
+ */
524
+ establishCabinet(requestedCabinet, suppressConfirmations, requestedEnviro) {
525
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
526
+ return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
527
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
528
+ try {
529
+ 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;
530
+ if (enterpriseCode === undefined) {
531
+ throw new contracts_2.CodiacError(`Cannot establish cabinet context: no enterprise is in context for the current user.`);
532
+ }
533
+ 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;
534
+ let cabName = requestedCabinet !== null && requestedCabinet !== void 0 ? requestedCabinet : current;
535
+ // -----------
536
+ // let eCntx = this._projUserCfg?.enterprise ?? this.userContext.currentEnterprise;
537
+ // if (eCntx == undefined || (<ProjectEnterpriseBinding>eCntx).enterpriseCode == undefined || (<EnterprisePointer>eCntx).enterprise == undefined) {
538
+ // throw new CodiacError(`Cannot establish cabinet context: no enterprise is in context for the current user.`);
539
+ // }
540
+ // // Remember any existing context...
541
+ // let enterpriseCode = eCntx.enterpriseCode;
542
+ // let current = eCntx.cabinet?.cabinet;
543
+ // let cabName: string | undefined = requestedCabinet;
544
+ // if (!cabName) { // THIS because we dont have the nullish operator...
545
+ // cabName = current;
546
+ // }
547
+ // -----------
548
+ // let env: Environment;
549
+ // let crit: EnvironmentCriteria = { all: true };
550
+ // let envResult = await this._codiacApi.Environment.tryReadMany(crit);
551
+ // if (envResult.error) {
552
+ // throw new CodiacError(`Error attempting to retrieve environments: ${envResult.error.message||envResult.message||""}`, envResult.error);
553
+ // } else if (envResult.count == 0 || !envResult.output || envResult.output.length == 0) {
554
+ // throw new CodiacError(`No environments found: ${envResult.message||""}`);
555
+ // } else if (envResult.output.length == 1) {
556
+ // env = envResult.output[0];
557
+ // } else {
558
+ // // TODO: Let the user select which one, and remember his choice as a default for next time.
559
+ // env = envResult.output[0]; // <--- HACK!!!!
560
+ // }
561
+ // if (env.cabinets.length == 0) {
562
+ // throw new CodiacError(`No cabinets found for environment [${env.code}]. Use 'cod cabinet:create' to create one.`);
563
+ // } else if (env.cabinets.length == 1) {
564
+ // cab = env.cabinets[0].name; // TODO: Consider a confirmation here that the -y attrib will skip
565
+ // } else {
566
+ // // TODO: Let the user select which one, and remember his choice as a default for next time.
567
+ // cab = env.cabinets[0].name; // <--- HACK!!!!
568
+ // }
569
+ let cabinet;
570
+ let crit = { enterpriseCode: enterpriseCode };
571
+ if (requestedEnviro !== undefined && requestedEnviro !== "") {
572
+ crit.environment = requestedEnviro;
573
+ }
574
+ let cabResult = yield this._codiacApi.Cabinet.tryReadMany(crit); // <--- TODO: Consider injecting a RootMap instance instead of making api hits.
575
+ if (cabResult.error) {
576
+ throw new contracts_2.CodiacError(`Error checking for cabinets in enterprise [${enterpriseCode}]: ${cabResult.message || ""}; ${cabResult.error.message || cabResult.error.stack}`, cabResult.error);
577
+ }
578
+ else if (!cabResult.output || cabResult.output.length == 0) {
579
+ throw new contracts_2.CodiacError(`No cabinets found for enterprise [${enterpriseCode}]. Use 'cod cabinet:create' to create a new cabinet. ${cabResult.message || ""}`);
580
+ }
581
+ else {
582
+ let cabs = cabResult.output;
583
+ // HERE'S THE UX GAUNTLET...
584
+ let selection;
585
+ if (cabName) {
586
+ // This is where we validate that the requested/remembered cabinet is indeed/still in the current enterprise.
587
+ // let found = cabs.find(c => c.name == cabName);
588
+ // let found = cabs.findIndex(c => c.name == cabName);
589
+ selection = cabs.findIndex(c => c.name == cabName);
590
+ if (selection < 0) {
591
+ this.logger.notice(`Cabinet [${cabName}] was not found in enterprise [${enterpriseCode}].`);
592
+ this.ui.userMessage(`Cabinet [${cabName}] was not found in enterprise [${enterpriseCode}].`);
593
+ }
594
+ }
595
+ // CI/CD support here
596
+ if (suppressConfirmations && cabName) {
597
+ cabinet = cabs.find(f => f.name == cabName);
598
+ }
599
+ let choices;
600
+ while (!cabinet) {
601
+ if (!selection || selection < 0) {
602
+ if (cabs.length == 1) { // We're adding this to prevent two steps
603
+ selection = 0;
604
+ }
605
+ else { // Let them choose
606
+ choices = choices || cabs.map((c, index) => { return { name: `${c.name}${(cabs[index].name == current) ? " (current)" : ""}`, value: index }; });
607
+ selection = (yield this.ui.promptSelect('cabIndex', `Select a cabinet [enterprise: ${this.styler.hilite(enterpriseCode)}]`, choices));
608
+ }
609
+ }
610
+ let confResult = yield this.ui.promptConfirm('confirm', `Target cabinet: ${this.styler.hilite(enterpriseCode + "/" + cabs[selection].name)}`);
611
+ if (confResult === true) { // TODO: Refactor these 3 confirms into 1
612
+ // if (await this._ui.promptConfirm("targetCab", `Target cabinet (y/n): ${inOrange(cabs[selection].name)}`)) { // TODO: Refactor these 3 confirms into 1
613
+ cabinet = cabs[selection];
614
+ }
615
+ else if (cabs.length == 1) { // We're adding this so we can avoid what would be two steps
616
+ this.logger.notice(`Operation cancelled. That was the only cabinet available in enterprise [${enterpriseCode}].`);
617
+ this.ui.userMessage(`Operation cancelled. That was the only cabinet available in enterprise [${enterpriseCode}].`);
618
+ this.exitCli(0);
619
+ }
620
+ else {
621
+ selection = undefined;
622
+ }
623
+ }
624
+ }
625
+ // PROJECT CONTEXT
626
+ if (this._projCfg && this._projCfgRepo) {
627
+ if (!this._projUserCfg)
628
+ this._projUserCfg = new codiac_relay_contracts_1.ProjectUserConfig();
629
+ if (this._projUserCfg.enterprise === undefined || this._projUserCfg.enterprise.enterpriseCode !== enterpriseCode) {
630
+ this._projUserCfg.enterprise = new codiac_relay_contracts_1.ProjectEnterpriseBinding(enterpriseCode);
631
+ }
632
+ // Are we sure we wanna set the exact current branch? what if we're inheriting this cabinet from our branch lineage?
633
+ let branch = yield this._ops.gitCurrentBranchNameFor(this._ops.getConfigRoot());
634
+ this._projUserCfg.enterprise.cabinet = new codiac_relay_contracts_2.BranchBinding(branch, enterpriseCode, cabinet.name);
635
+ this._projCfgRepo.writeProjectUserConfig(this._projUserCfg);
636
+ }
637
+ // USER CONTEXT
638
+ if (this.userContext.currentEnterprise === undefined || this.userContext.currentEnterprise.enterprise !== enterpriseCode) {
639
+ this.userContext.currentEnterprise = new codiac_relay_contracts_1.EnterprisePointer(enterpriseCode);
640
+ }
641
+ this.userContext.currentEnterprise.cabinet = cabinet.name;
642
+ this.userContext.enterpriseContexts[this._tenantCode] = this.userContext.currentEnterprise;
643
+ this.userContextManager.writeUserContext(this.userContext);
644
+ this.logger.trace(`Cabinet`, cabinet);
645
+ // let cabCntx = new CabinetScope(cabinet.enterpriseCode, cabinet.environment, cabinet.name)
646
+ // this.logger.trace(`Cabinet context`, cabCntx)
647
+ resolve(cabinet);
648
+ }
649
+ catch (err) {
650
+ reject(err);
651
+ }
652
+ }));
653
+ });
654
+ }
655
+ createAuditable() {
656
+ let stamp = new Date(Date.now());
657
+ return {
658
+ created: stamp,
659
+ createdBy: this.userContext.userName,
660
+ modified: stamp,
661
+ modifiedBy: this.userContext.userName
662
+ };
663
+ }
664
+ }
665
+ exports.EnterpriseContextualizer = EnterpriseContextualizer;
666
+ /** The value in a select list prompt designating the user's choice
667
+ * to create a new record instead of selecting from the existing choices. */
668
+ EnterpriseContextualizer.CHOICE_VALUE_FOR_NEW = "** create new **";
669
+ EnterpriseContextualizer.DEFAULT_REGISTRY_URL = "https://index.docker.io/v1";
670
+ EnterpriseContextualizer.DEFAULT_ASSET_PORT_NUMBER = 1787;
671
671
  //# sourceMappingURL=enterprise-contextualizer.js.map