@catladder/cli 0.0.0-next-4e7c6848 → 0.0.0-next-8b9ad5ca
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundles/catenv/index.js +617 -19
- package/dist/bundles/cli/index.js +811 -18
- package/dist/cli/src/adapters/baseContext.d.ts +4 -0
- package/dist/cli/src/adapters/baseContext.js +5 -0
- package/dist/cli/src/adapters/baseContext.js.map +1 -1
- package/dist/cli/src/adapters/nonInteractive.d.ts +9 -0
- package/dist/cli/src/adapters/nonInteractive.js +32 -0
- package/dist/cli/src/adapters/nonInteractive.js.map +1 -0
- package/dist/cli/src/adapters/programmatic.d.ts +1 -0
- package/dist/cli/src/adapters/programmatic.js +6 -1
- package/dist/cli/src/adapters/programmatic.js.map +1 -1
- package/dist/cli/src/adapters/terminal.d.ts +1 -0
- package/dist/cli/src/adapters/terminal.js +10 -1
- package/dist/cli/src/adapters/terminal.js.map +1 -1
- package/dist/cli/src/adapters/vaultManagerAccess.d.ts +8 -0
- package/dist/cli/src/adapters/vaultManagerAccess.js +26 -0
- package/dist/cli/src/adapters/vaultManagerAccess.js.map +1 -0
- package/dist/cli/src/apps/catenv/catenv.d.ts +2 -0
- package/dist/cli/src/apps/catenv/catenv.js +8 -1
- package/dist/cli/src/apps/catenv/catenv.js.map +1 -1
- package/dist/cli/src/apps/catenv/printVariables.d.ts +2 -2
- package/dist/cli/src/apps/catenv/printVariables.js +4 -4
- package/dist/cli/src/apps/catenv/printVariables.js.map +1 -1
- package/dist/cli/src/apps/catenv/types.d.ts +9 -0
- package/dist/cli/src/apps/catenv/writeDotEnvFiles.d.ts +2 -2
- package/dist/cli/src/apps/catenv/writeDotEnvFiles.js +1 -1
- package/dist/cli/src/apps/catenv/writeDotEnvFiles.js.map +1 -1
- package/dist/cli/src/apps/cli/commands/project/commandConfigSecrets.js +52 -3
- package/dist/cli/src/apps/cli/commands/project/commandConfigSecrets.js.map +1 -1
- package/dist/cli/src/catenv.js +3 -2
- package/dist/cli/src/catenv.js.map +1 -1
- package/dist/cli/src/commands/index.d.ts +1 -0
- package/dist/cli/src/commands/index.js +8 -1
- package/dist/cli/src/commands/index.js.map +1 -1
- package/dist/cli/src/commands/project/commandSecretsSyncGithub.d.ts +37 -0
- package/dist/cli/src/commands/project/commandSecretsSyncGithub.js +127 -0
- package/dist/cli/src/commands/project/commandSecretsSyncGithub.js.map +1 -0
- package/dist/cli/src/config/getProjectConfig.d.ts +1 -1
- package/dist/cli/src/config/getProjectConfig.js +12 -2
- package/dist/cli/src/config/getProjectConfig.js.map +1 -1
- package/dist/cli/src/core/types.d.ts +15 -0
- package/dist/cli/src/core/types.js +8 -1
- package/dist/cli/src/core/types.js.map +1 -1
- package/dist/cli/src/git/gitProjectInformation.d.ts +1 -1
- package/dist/cli/src/git/gitProjectInformation.js +3 -3
- package/dist/cli/src/git/gitProjectInformation.js.map +1 -1
- package/dist/cli/src/utils/github.d.ts +15 -0
- package/dist/cli/src/utils/github.js +54 -0
- package/dist/cli/src/utils/github.js.map +1 -0
- package/dist/cli/src/vault/BitwardenVault.d.ts +24 -0
- package/dist/cli/src/vault/BitwardenVault.js +107 -0
- package/dist/cli/src/vault/BitwardenVault.js.map +1 -0
- package/dist/cli/src/vault/GitlabVault.d.ts +11 -0
- package/dist/cli/src/vault/GitlabVault.js +24 -0
- package/dist/cli/src/vault/GitlabVault.js.map +1 -0
- package/dist/cli/src/vault/VaultManager.d.ts +43 -0
- package/dist/cli/src/vault/VaultManager.js +131 -0
- package/dist/cli/src/vault/VaultManager.js.map +1 -0
- package/dist/cli/src/vault/bw.d.ts +15 -0
- package/dist/cli/src/vault/bw.js +89 -0
- package/dist/cli/src/vault/bw.js.map +1 -0
- package/dist/cli/src/vault/cache.d.ts +38 -0
- package/dist/cli/src/vault/cache.js +53 -0
- package/dist/cli/src/vault/cache.js.map +1 -0
- package/dist/cli/src/vault/index.d.ts +5 -0
- package/dist/cli/src/vault/index.js +48 -0
- package/dist/cli/src/vault/index.js.map +1 -0
- package/dist/cli/src/vault/types.d.ts +33 -0
- package/dist/cli/src/vault/types.js +5 -0
- package/dist/cli/src/vault/types.js.map +1 -0
- package/dist/pipeline/src/backends/index.d.ts +17 -1
- package/dist/pipeline/src/backends/index.js +33 -1
- package/dist/pipeline/src/backends/index.js.map +1 -1
- package/dist/pipeline/src/constants.js +1 -1
- package/dist/pipeline/src/deploy/cloudRun/index.js +11 -4
- package/dist/pipeline/src/deploy/cloudRun/index.js.map +1 -1
- package/dist/pipeline/src/types/config.d.ts +37 -3
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/adapters/baseContext.ts +10 -0
- package/src/adapters/nonInteractive.ts +30 -0
- package/src/adapters/programmatic.ts +7 -1
- package/src/adapters/terminal.ts +9 -1
- package/src/adapters/vaultManagerAccess.ts +25 -0
- package/src/apps/catenv/catenv.ts +5 -1
- package/src/apps/catenv/printVariables.ts +16 -6
- package/src/apps/catenv/types.ts +9 -0
- package/src/apps/catenv/writeDotEnvFiles.ts +3 -3
- package/src/apps/cli/commands/project/commandConfigSecrets.ts +94 -9
- package/src/catenv.ts +22 -2
- package/src/commands/index.ts +1 -0
- package/src/commands/project/commandSecretsSyncGithub.ts +149 -0
- package/src/config/getProjectConfig.ts +21 -7
- package/src/core/types.ts +23 -0
- package/src/git/gitProjectInformation.ts +5 -3
- package/src/utils/github.ts +59 -0
- package/src/vault/BitwardenVault.ts +161 -0
- package/src/vault/GitlabVault.ts +25 -0
- package/src/vault/VaultManager.ts +211 -0
- package/src/vault/bw.ts +110 -0
- package/src/vault/cache.ts +80 -0
- package/src/vault/index.ts +5 -0
- package/src/vault/types.ts +42 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/******/ var __webpack_modules__ = ({
|
|
3
3
|
|
|
4
4
|
/***/ 48618:
|
|
5
|
-
/***/ ((__unused_webpack_module, exports) => {
|
|
5
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
6
6
|
|
|
7
7
|
"use strict";
|
|
8
8
|
|
|
@@ -11,6 +11,7 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
11
11
|
value: true
|
|
12
12
|
}));
|
|
13
13
|
exports.BaseContext = void 0;
|
|
14
|
+
const vaultManagerAccess_1 = __nccwpck_require__(37881);
|
|
14
15
|
/**
|
|
15
16
|
* Base class for CommandContext implementations.
|
|
16
17
|
* Handles caching, the `get()` method, and `promptDirect` delegation.
|
|
@@ -20,6 +21,10 @@ class BaseContext {
|
|
|
20
21
|
constructor(command) {
|
|
21
22
|
this.command = command;
|
|
22
23
|
this.cache = new Map();
|
|
24
|
+
this.vaultManagerGetter = (0, vaultManagerAccess_1.createVaultManagerGetter)(() => this);
|
|
25
|
+
}
|
|
26
|
+
getVaultManager() {
|
|
27
|
+
return this.vaultManagerGetter();
|
|
23
28
|
}
|
|
24
29
|
get(name) {
|
|
25
30
|
if (!this.cache.has(name)) {
|
|
@@ -91,6 +96,7 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
91
96
|
exports.createTerminalIO = exports.createTerminalContext = void 0;
|
|
92
97
|
const types_1 = __nccwpck_require__(92284);
|
|
93
98
|
const baseContext_1 = __nccwpck_require__(48618);
|
|
99
|
+
const vaultManagerAccess_1 = __nccwpck_require__(37881);
|
|
94
100
|
/**
|
|
95
101
|
* Resolve choices from a choices function.
|
|
96
102
|
*/
|
|
@@ -155,6 +161,10 @@ class TerminalContext extends baseContext_1.BaseContext {
|
|
|
155
161
|
super(command);
|
|
156
162
|
this.options = options;
|
|
157
163
|
}
|
|
164
|
+
get interactive() {
|
|
165
|
+
var _a;
|
|
166
|
+
return (_a = this.options.interactive) !== null && _a !== void 0 ? _a : process.stdin.isTTY === true;
|
|
167
|
+
}
|
|
158
168
|
log(message) {
|
|
159
169
|
console.log(message);
|
|
160
170
|
}
|
|
@@ -229,7 +239,10 @@ exports.createTerminalContext = createTerminalContext;
|
|
|
229
239
|
* Create a bare IO instance for terminal helper functions.
|
|
230
240
|
*/
|
|
231
241
|
function createTerminalIO(options = {}) {
|
|
232
|
-
|
|
242
|
+
var _a;
|
|
243
|
+
const io = {
|
|
244
|
+
interactive: (_a = options.interactive) !== null && _a !== void 0 ? _a : process.stdin.isTTY === true,
|
|
245
|
+
getVaultManager: (0, vaultManagerAccess_1.createVaultManagerGetter)(() => io),
|
|
233
246
|
log(message) {
|
|
234
247
|
console.log(message);
|
|
235
248
|
},
|
|
@@ -255,11 +268,45 @@ function createTerminalIO(options = {}) {
|
|
|
255
268
|
throw new types_1.MissingInputError(spec.name, spec.message);
|
|
256
269
|
}
|
|
257
270
|
};
|
|
271
|
+
return io;
|
|
258
272
|
}
|
|
259
273
|
exports.createTerminalIO = createTerminalIO;
|
|
260
274
|
|
|
261
275
|
/***/ }),
|
|
262
276
|
|
|
277
|
+
/***/ 37881:
|
|
278
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
279
|
+
|
|
280
|
+
"use strict";
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
284
|
+
value: true
|
|
285
|
+
}));
|
|
286
|
+
exports.createVaultManagerGetter = void 0;
|
|
287
|
+
const getProjectConfig_1 = __nccwpck_require__(50001);
|
|
288
|
+
const VaultManager_1 = __nccwpck_require__(55771);
|
|
289
|
+
/**
|
|
290
|
+
* lazily creates the vault manager of a context (once per context),
|
|
291
|
+
* loading the project config on first use
|
|
292
|
+
*/
|
|
293
|
+
const createVaultManagerGetter = (io, options = {}) => {
|
|
294
|
+
let managerPromise;
|
|
295
|
+
return () => managerPromise !== null && managerPromise !== void 0 ? managerPromise : managerPromise = (async () => {
|
|
296
|
+
const config = await (0, getProjectConfig_1.getProjectConfig)();
|
|
297
|
+
if (!config) {
|
|
298
|
+
throw new Error("no catladder config found — the secrets vault needs a project config");
|
|
299
|
+
}
|
|
300
|
+
return new VaultManager_1.VaultManager(config, {
|
|
301
|
+
...options,
|
|
302
|
+
io: io()
|
|
303
|
+
});
|
|
304
|
+
})();
|
|
305
|
+
};
|
|
306
|
+
exports.createVaultManagerGetter = createVaultManagerGetter;
|
|
307
|
+
|
|
308
|
+
/***/ }),
|
|
309
|
+
|
|
263
310
|
/***/ 38365:
|
|
264
311
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
265
312
|
|
|
@@ -355,7 +402,9 @@ const pipeline_1 = __nccwpck_require__(60241);
|
|
|
355
402
|
const common_tags_1 = __nccwpck_require__(63779);
|
|
356
403
|
const lodash_es_1 = __nccwpck_require__(64284);
|
|
357
404
|
const getProjectConfig_1 = __nccwpck_require__(50001);
|
|
405
|
+
const commandSecretsSyncGithub_1 = __nccwpck_require__(50962);
|
|
358
406
|
const editAsFile_1 = __nccwpck_require__(82805);
|
|
407
|
+
const github_1 = __nccwpck_require__(18036);
|
|
359
408
|
const gitlab_1 = __nccwpck_require__(4508);
|
|
360
409
|
const promise_1 = __nccwpck_require__(51762);
|
|
361
410
|
/* for convenience, parse json objects. that makes it easier to edit secrets that are object */
|
|
@@ -433,21 +482,68 @@ const doItFor = async (instance, envAndComponents) => {
|
|
|
433
482
|
}
|
|
434
483
|
}
|
|
435
484
|
}
|
|
485
|
+
const config = await (0, getProjectConfig_1.getProjectConfig)();
|
|
486
|
+
if (!config) {
|
|
487
|
+
throw new Error("no catladder config found");
|
|
488
|
+
}
|
|
436
489
|
instance.log("");
|
|
437
|
-
instance.log("
|
|
490
|
+
instance.log("writing all secrets to the vault, please wait...");
|
|
438
491
|
instance.log("");
|
|
439
492
|
for (const [componentName, envs] of Object.entries(envAndComponents)) {
|
|
440
493
|
for (const env of envs) {
|
|
441
|
-
instance.log("
|
|
442
|
-
await (
|
|
494
|
+
instance.log("writing " + env + ":" + componentName + "...\n");
|
|
495
|
+
await (await instance.getVaultManager()).writeSecrets(env, componentName, valuesToEdit[componentName][env]);
|
|
443
496
|
instance.log("");
|
|
444
497
|
instance.log("✅ " + env + ":" + componentName);
|
|
445
498
|
instance.log("--------------------------------\n");
|
|
446
499
|
}
|
|
447
500
|
}
|
|
501
|
+
await mirrorSecretsToCiBackends(instance, config, envAndComponents, valuesToEdit);
|
|
448
502
|
instance.log("done! 😻");
|
|
449
503
|
instance.log("");
|
|
450
504
|
};
|
|
505
|
+
/**
|
|
506
|
+
* the vault is the source of truth; every enabled CI backend receives
|
|
507
|
+
* a mirrored copy of the edited secrets (gitlab variables, github
|
|
508
|
+
* secrets), so all CI systems stay in sync
|
|
509
|
+
*/
|
|
510
|
+
const mirrorSecretsToCiBackends = async (instance, config, envAndComponents, valuesToEdit) => {
|
|
511
|
+
const enabled = (0, pipeline_1.getEnabledPipelineTypes)(config);
|
|
512
|
+
// gitlab mirror (unless gitlab is the vault itself, then it is
|
|
513
|
+
// already written)
|
|
514
|
+
if ((0, pipeline_1.getVaultConfig)(config).type !== "gitlab" && enabled.includes("gitlab")) {
|
|
515
|
+
for (const [componentName, envs] of Object.entries(envAndComponents)) {
|
|
516
|
+
for (const env of envs) {
|
|
517
|
+
await (0, gitlab_1.upsertAllVariables)(instance, valuesToEdit[componentName][env], env, componentName);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
instance.log("✅ mirrored to gitlab");
|
|
521
|
+
}
|
|
522
|
+
if (!enabled.includes("github")) {
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
const secrets = Object.entries(envAndComponents).flatMap(([componentName, envs]) => envs.flatMap(env => {
|
|
526
|
+
var _a;
|
|
527
|
+
return Object.entries((_a = valuesToEdit[componentName][env]) !== null && _a !== void 0 ? _a : {}).map(([key, value]) => ({
|
|
528
|
+
name: (0, pipeline_1.getSecretVarName)(env, componentName, key),
|
|
529
|
+
value: typeof value === "string" ? value : JSON.stringify(value !== null && value !== void 0 ? value : "")
|
|
530
|
+
}));
|
|
531
|
+
}));
|
|
532
|
+
if (secrets.length === 0) {
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
if (!(await (0, github_1.isGhAuthenticated)())) {
|
|
536
|
+
instance.log("⚠️ github pipeline is enabled, but the github cli (gh) is not authenticated — run `project secrets-sync-github` later to mirror the secrets");
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
const repo = await (0, commandSecretsSyncGithub_1.getConfiguredGithubRepo)();
|
|
540
|
+
if (!repo) {
|
|
541
|
+
instance.log("⚠️ github pipeline is enabled, but no github repository was found — run `project secrets-sync-github` later to mirror the secrets");
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
instance.log(`mirroring ${secrets.length} secrets to github ('${repo}')...`);
|
|
545
|
+
await (0, commandSecretsSyncGithub_1.pushSecretsToGithub)(instance, repo, secrets);
|
|
546
|
+
};
|
|
451
547
|
const projectConfigSecrets = async (io, envComponent) => {
|
|
452
548
|
if (!envComponent) {
|
|
453
549
|
const allEnvAndcomponents = await (0, getProjectConfig_1.getAllComponentsWithAllEnvsHierarchical)();
|
|
@@ -1874,7 +1970,7 @@ exports.commandKubeStopPortforward = (0, defineCommand_1.defineCommand)({
|
|
|
1874
1970
|
Object.defineProperty(exports, "__esModule", ({
|
|
1875
1971
|
value: true
|
|
1876
1972
|
}));
|
|
1877
|
-
exports.commandStarwars = exports.commandDadjoke = exports.commandSecurityAuditCreate = exports.commandSecurityAuditEvaluate = exports.commandSecurityAuditCiJob = exports.commandRestoreDb = exports.commandMongoDestroyMember = exports.commandMongoPortForward = exports.commandMongoGetShell = exports.commandTriggerCronjobProject = exports.commandDeleteProject = exports.commandPauseProject = exports.commandDeletePods = exports.commandGetShell = exports.commandListPods = exports.commandNamespace = exports.commandSecurityEvaluate = exports.commandProjectRestoreDb = exports.commandCiJobLog = exports.commandCiJobOpen = exports.commandSetup = exports.commandGetMyTotalWorktime = exports.commandRenewToken = exports.commandTriggerCronjobGeneral = exports.commandOpenLogs = exports.commandSecretsClearBackups = exports.commandConfigSecrets = exports.commandCloudSqlProxy = exports.commandOpenGit = exports.commandOpenEnv = exports.commandPortForward = exports.commandEnvVars = exports.commandKubePortForward = exports.commandKubeGetShell = exports.commandKubeStopPortforward = exports.commandKubeListPods = exports.commandKubeListSecrets = exports.commandKubeListNamespaces = exports.commandKubeCurrentContext = void 0;
|
|
1973
|
+
exports.commandStarwars = exports.commandDadjoke = exports.commandSecurityAuditCreate = exports.commandSecurityAuditEvaluate = exports.commandSecurityAuditCiJob = exports.commandRestoreDb = exports.commandMongoDestroyMember = exports.commandMongoPortForward = exports.commandMongoGetShell = exports.commandTriggerCronjobProject = exports.commandDeleteProject = exports.commandPauseProject = exports.commandDeletePods = exports.commandGetShell = exports.commandListPods = exports.commandNamespace = exports.commandSecurityEvaluate = exports.commandProjectRestoreDb = exports.commandCiJobLog = exports.commandCiJobOpen = exports.commandSetup = exports.commandGetMyTotalWorktime = exports.commandRenewToken = exports.commandTriggerCronjobGeneral = exports.commandOpenLogs = exports.commandSecretsSyncGithub = exports.commandSecretsClearBackups = exports.commandConfigSecrets = exports.commandCloudSqlProxy = exports.commandOpenGit = exports.commandOpenEnv = exports.commandPortForward = exports.commandEnvVars = exports.commandKubePortForward = exports.commandKubeGetShell = exports.commandKubeStopPortforward = exports.commandKubeListPods = exports.commandKubeListSecrets = exports.commandKubeListNamespaces = exports.commandKubeCurrentContext = void 0;
|
|
1878
1974
|
// General commands
|
|
1879
1975
|
var commandKubeCurrentContext_1 = __nccwpck_require__(70243);
|
|
1880
1976
|
Object.defineProperty(exports, "commandKubeCurrentContext", ({
|
|
@@ -1975,6 +2071,13 @@ Object.defineProperty(exports, "commandSecretsClearBackups", ({
|
|
|
1975
2071
|
return commandSecretsClearBackups_1.commandSecretsClearBackups;
|
|
1976
2072
|
}
|
|
1977
2073
|
}));
|
|
2074
|
+
var commandSecretsSyncGithub_1 = __nccwpck_require__(50962);
|
|
2075
|
+
Object.defineProperty(exports, "commandSecretsSyncGithub", ({
|
|
2076
|
+
enumerable: true,
|
|
2077
|
+
get: function () {
|
|
2078
|
+
return commandSecretsSyncGithub_1.commandSecretsSyncGithub;
|
|
2079
|
+
}
|
|
2080
|
+
}));
|
|
1978
2081
|
var commandOpenLogs_1 = __nccwpck_require__(98720);
|
|
1979
2082
|
Object.defineProperty(exports, "commandOpenLogs", ({
|
|
1980
2083
|
enumerable: true,
|
|
@@ -3186,6 +3289,140 @@ exports.commandSecretsClearBackups = (0, defineCommand_1.defineCommand)({
|
|
|
3186
3289
|
|
|
3187
3290
|
/***/ }),
|
|
3188
3291
|
|
|
3292
|
+
/***/ 50962:
|
|
3293
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
3294
|
+
|
|
3295
|
+
"use strict";
|
|
3296
|
+
|
|
3297
|
+
|
|
3298
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
3299
|
+
value: true
|
|
3300
|
+
}));
|
|
3301
|
+
exports.commandSecretsSyncGithub = exports.getConfiguredGithubRepo = exports.pushSecretsToGithub = exports.collectSecretsFromVault = void 0;
|
|
3302
|
+
const pipeline_1 = __nccwpck_require__(60241);
|
|
3303
|
+
const getProjectConfig_1 = __nccwpck_require__(50001);
|
|
3304
|
+
const defineCommand_1 = __nccwpck_require__(39489);
|
|
3305
|
+
const github_1 = __nccwpck_require__(18036);
|
|
3306
|
+
/**
|
|
3307
|
+
* all secrets declared in the config, with their values read from the
|
|
3308
|
+
* vault (github secrets are write-only and can never act as a source)
|
|
3309
|
+
*/
|
|
3310
|
+
const collectSecretsFromVault = async io => {
|
|
3311
|
+
const envAndComponents = await (0, getProjectConfig_1.getAllComponentsWithAllEnvsHierarchical)();
|
|
3312
|
+
const names = [];
|
|
3313
|
+
for (const [componentName, envs] of Object.entries(envAndComponents)) {
|
|
3314
|
+
for (const env of envs) {
|
|
3315
|
+
const {
|
|
3316
|
+
secretEnvVarKeys,
|
|
3317
|
+
jobOnlyVars
|
|
3318
|
+
} = await (0, getProjectConfig_1.getEnvironment)(env, componentName);
|
|
3319
|
+
const keys = [...secretEnvVarKeys, ...jobOnlyVars.build.secretEnvVarKeys, ...jobOnlyVars.deploy.secretEnvVarKeys];
|
|
3320
|
+
keys.forEach(({
|
|
3321
|
+
key
|
|
3322
|
+
}) => names.push((0, pipeline_1.getSecretVarName)(env, componentName, key)));
|
|
3323
|
+
}
|
|
3324
|
+
}
|
|
3325
|
+
const values = await (await io.getVaultManager()).readSecrets(names, io);
|
|
3326
|
+
const secrets = names.filter(name => values[name] !== undefined).map(name => ({
|
|
3327
|
+
name,
|
|
3328
|
+
value: values[name]
|
|
3329
|
+
}));
|
|
3330
|
+
const missing = names.filter(name => values[name] === undefined);
|
|
3331
|
+
return {
|
|
3332
|
+
secrets,
|
|
3333
|
+
missing
|
|
3334
|
+
};
|
|
3335
|
+
};
|
|
3336
|
+
exports.collectSecretsFromVault = collectSecretsFromVault;
|
|
3337
|
+
/**
|
|
3338
|
+
* pushes secrets to github repository secrets via the gh cli
|
|
3339
|
+
*/
|
|
3340
|
+
const pushSecretsToGithub = async (io, repo, secrets) => {
|
|
3341
|
+
for (const {
|
|
3342
|
+
name,
|
|
3343
|
+
value
|
|
3344
|
+
} of secrets) {
|
|
3345
|
+
await (0, github_1.setGithubSecret)(repo, name, value);
|
|
3346
|
+
io.log(`✅ ${name}`);
|
|
3347
|
+
}
|
|
3348
|
+
};
|
|
3349
|
+
exports.pushSecretsToGithub = pushSecretsToGithub;
|
|
3350
|
+
/**
|
|
3351
|
+
* resolves the github repository from the configured git remote
|
|
3352
|
+
* (`pipelines.github.gitRemote`, defaults to origin)
|
|
3353
|
+
*/
|
|
3354
|
+
const getConfiguredGithubRepo = async () => {
|
|
3355
|
+
const config = await (0, getProjectConfig_1.getProjectConfig)();
|
|
3356
|
+
if (!config) {
|
|
3357
|
+
return undefined;
|
|
3358
|
+
}
|
|
3359
|
+
return (0, github_1.getGithubRepoFromRemote)((0, pipeline_1.getPipelineGitRemote)(config, "github"));
|
|
3360
|
+
};
|
|
3361
|
+
exports.getConfiguredGithubRepo = getConfiguredGithubRepo;
|
|
3362
|
+
/**
|
|
3363
|
+
* copies the catladder secrets from the vault to github actions
|
|
3364
|
+
* repository secrets, keeping the exact same names, so the github
|
|
3365
|
+
* pipeline can reference them as ${{ secrets.<NAME> }}.
|
|
3366
|
+
*/
|
|
3367
|
+
exports.commandSecretsSyncGithub = (0, defineCommand_1.defineCommand)({
|
|
3368
|
+
name: "project secrets-sync-github",
|
|
3369
|
+
description: "copies all secrets from the vault to github repo secrets (same names), for the github pipeline",
|
|
3370
|
+
group: "project",
|
|
3371
|
+
inputs: {
|
|
3372
|
+
repo: {
|
|
3373
|
+
type: "string",
|
|
3374
|
+
message: "github repository (owner/name)",
|
|
3375
|
+
positional: true,
|
|
3376
|
+
required: false
|
|
3377
|
+
}
|
|
3378
|
+
},
|
|
3379
|
+
execute: async ctx => {
|
|
3380
|
+
var _a;
|
|
3381
|
+
const config = await (0, getProjectConfig_1.getProjectConfig)();
|
|
3382
|
+
if (!config) {
|
|
3383
|
+
throw new Error("no catladder config found");
|
|
3384
|
+
}
|
|
3385
|
+
const enabled = (0, pipeline_1.getEnabledPipelineTypes)(config);
|
|
3386
|
+
if (!enabled.includes("github")) {
|
|
3387
|
+
throw new Error("the github pipeline is not enabled in `pipelines` — nothing to sync to");
|
|
3388
|
+
}
|
|
3389
|
+
if (!(await (0, github_1.isGhAuthenticated)())) {
|
|
3390
|
+
throw new Error("the github cli (gh) is not installed or not authenticated — run `gh auth login` first");
|
|
3391
|
+
}
|
|
3392
|
+
const repo = (_a = await ctx.get("repo")) !== null && _a !== void 0 ? _a : await (0, exports.getConfiguredGithubRepo)();
|
|
3393
|
+
if (!repo) {
|
|
3394
|
+
throw new Error(`no github repository found on the '${(0, pipeline_1.getPipelineGitRemote)(config, "github")}' remote — pass it as owner/name or configure pipelines.github.gitRemote`);
|
|
3395
|
+
}
|
|
3396
|
+
const {
|
|
3397
|
+
secrets,
|
|
3398
|
+
missing
|
|
3399
|
+
} = await (0, exports.collectSecretsFromVault)(ctx);
|
|
3400
|
+
if (missing.length > 0) {
|
|
3401
|
+
ctx.log(`⚠️ ${missing.length} secrets are not set in the vault and will be skipped:`);
|
|
3402
|
+
missing.forEach(name => ctx.log(` - ${name}`));
|
|
3403
|
+
ctx.log("");
|
|
3404
|
+
}
|
|
3405
|
+
if (secrets.length === 0) {
|
|
3406
|
+
ctx.log("no secrets to sync 🤷");
|
|
3407
|
+
return;
|
|
3408
|
+
}
|
|
3409
|
+
ctx.log(`about to set ${secrets.length} secrets on '${repo}':`);
|
|
3410
|
+
secrets.forEach(({
|
|
3411
|
+
name
|
|
3412
|
+
}) => ctx.log(` - ${name}`));
|
|
3413
|
+
ctx.log("");
|
|
3414
|
+
const confirmed = await ctx.confirm("continue? 🤔");
|
|
3415
|
+
if (!confirmed) {
|
|
3416
|
+
throw new Error("abort");
|
|
3417
|
+
}
|
|
3418
|
+
await (0, exports.pushSecretsToGithub)(ctx, repo, secrets);
|
|
3419
|
+
ctx.log("");
|
|
3420
|
+
ctx.log("done! 😻 the github pipeline can use them as ${{ secrets.<NAME> }}");
|
|
3421
|
+
}
|
|
3422
|
+
});
|
|
3423
|
+
|
|
3424
|
+
/***/ }),
|
|
3425
|
+
|
|
3189
3426
|
/***/ 92494:
|
|
3190
3427
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
3191
3428
|
|
|
@@ -4179,14 +4416,24 @@ const getGitlabVar = async (io, env, componentName, variableName) => {
|
|
|
4179
4416
|
};
|
|
4180
4417
|
exports.getGitlabVar = getGitlabVar;
|
|
4181
4418
|
const resolveSecrets = async (io, varSets) => {
|
|
4182
|
-
|
|
4419
|
+
// the secret variables actually referenced by the env var values —
|
|
4420
|
+
// when they are all in the local cache, the vault is not contacted
|
|
4421
|
+
const referencedNames = [...new Set(varSets.flatMap(({
|
|
4422
|
+
envVars
|
|
4423
|
+
}) => Object.values(envVars).flatMap(value => {
|
|
4424
|
+
var _a;
|
|
4425
|
+
return (_a = `${value}`.match(/\$CL_\w+/g)) !== null && _a !== void 0 ? _a : [];
|
|
4426
|
+
})))].map(reference => reference.slice(1));
|
|
4427
|
+
const vaultManager = await io.getVaultManager();
|
|
4428
|
+
const secrets = await vaultManager.readSecrets(referencedNames, io);
|
|
4429
|
+
const secretEntries = Object.entries(secrets);
|
|
4183
4430
|
return Object.fromEntries(varSets.flatMap(({
|
|
4184
4431
|
envVars,
|
|
4185
4432
|
secretEnvVarKeys
|
|
4186
4433
|
}) => Object.entries(envVars).filter(([key, value]) => {
|
|
4187
4434
|
var _a;
|
|
4188
4435
|
return value !== undefined && value !== null && !((_a = secretEnvVarKeys.find(k => k.key === key)) === null || _a === void 0 ? void 0 : _a.hidden);
|
|
4189
|
-
}).map(([key, value]) => [key,
|
|
4436
|
+
}).map(([key, value]) => [key, secretEntries.reduce((acc, [name, secretValue]) => acc.replace(new RegExp("\\$" + name, "g"), secretValue), `${value}`)])));
|
|
4190
4437
|
};
|
|
4191
4438
|
const getEnvVarsResolved = async (io, env, componentName) => {
|
|
4192
4439
|
if (!componentName) {
|
|
@@ -4291,8 +4538,15 @@ exports.defineCommand = defineCommand;
|
|
|
4291
4538
|
Object.defineProperty(exports, "__esModule", ({
|
|
4292
4539
|
value: true
|
|
4293
4540
|
}));
|
|
4294
|
-
exports.MissingInputError = void 0;
|
|
4541
|
+
exports.MissingInputError = exports.NonInteractiveError = void 0;
|
|
4295
4542
|
// ─── Errors ──────────────────────────────────────────────────────────
|
|
4543
|
+
class NonInteractiveError extends Error {
|
|
4544
|
+
constructor(interaction) {
|
|
4545
|
+
super(`${interaction} requires an interactive terminal, but this context is not interactive`);
|
|
4546
|
+
this.name = "NonInteractiveError";
|
|
4547
|
+
}
|
|
4548
|
+
}
|
|
4549
|
+
exports.NonInteractiveError = NonInteractiveError;
|
|
4296
4550
|
class MissingInputError extends Error {
|
|
4297
4551
|
constructor(inputName, promptMessage) {
|
|
4298
4552
|
super(`Missing required input: "${inputName}" (${promptMessage}). ` + `Provide it via --${inputName}=<value> or --inputs='{"${inputName}": ...}'`);
|
|
@@ -4742,14 +4996,14 @@ exports.getProjectRootPath = getProjectRootPath;
|
|
|
4742
4996
|
/**
|
|
4743
4997
|
* Get the git remote hostname and project path from the git config.
|
|
4744
4998
|
*/
|
|
4745
|
-
const getGitRemoteHostAndPath = async () => {
|
|
4999
|
+
const getGitRemoteHostAndPath = async (remoteName = "origin") => {
|
|
4746
5000
|
var _a;
|
|
4747
|
-
const remoteUrl = await (0, gitConfig_1.gitConfigGet)(
|
|
5001
|
+
const remoteUrl = await (0, gitConfig_1.gitConfigGet)(`remote.${remoteName}.url`);
|
|
4748
5002
|
const remoteReg = /(https:\/\/|git@)([^:/]+)[:/]([^.]*)(\.git)?/;
|
|
4749
5003
|
const match = (_a = remoteUrl.match(remoteReg)) !== null && _a !== void 0 ? _a : [];
|
|
4750
5004
|
const [,, gitRemoteHost, gitRemotePath] = match;
|
|
4751
5005
|
if (!(gitRemoteHost === null || gitRemoteHost === void 0 ? void 0 : gitRemoteHost.length) || !(gitRemotePath === null || gitRemotePath === void 0 ? void 0 : gitRemotePath.length)) {
|
|
4752
|
-
throw new Error(`Failed to parse git remote hostname and path from git configs remote.
|
|
5006
|
+
throw new Error(`Failed to parse git remote hostname and path from git configs remote.${remoteName}.url! ${remoteUrl}`);
|
|
4753
5007
|
}
|
|
4754
5008
|
return {
|
|
4755
5009
|
gitRemoteHost,
|
|
@@ -5306,6 +5560,67 @@ exports["default"] = async () => {
|
|
|
5306
5560
|
|
|
5307
5561
|
/***/ }),
|
|
5308
5562
|
|
|
5563
|
+
/***/ 18036:
|
|
5564
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
5565
|
+
|
|
5566
|
+
"use strict";
|
|
5567
|
+
|
|
5568
|
+
|
|
5569
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
5570
|
+
value: true
|
|
5571
|
+
}));
|
|
5572
|
+
exports.setGithubSecret = exports.getGithubRepoFromRemote = exports.isGhAuthenticated = void 0;
|
|
5573
|
+
const child_process_1 = __nccwpck_require__(35317);
|
|
5574
|
+
const util_1 = __nccwpck_require__(39023);
|
|
5575
|
+
const execFile = (0, util_1.promisify)(child_process_1.execFile);
|
|
5576
|
+
/**
|
|
5577
|
+
* whether the github cli (gh) is installed and authenticated
|
|
5578
|
+
*/
|
|
5579
|
+
const isGhAuthenticated = async () => {
|
|
5580
|
+
try {
|
|
5581
|
+
await execFile("gh", ["auth", "status"]);
|
|
5582
|
+
return true;
|
|
5583
|
+
} catch (_a) {
|
|
5584
|
+
return false;
|
|
5585
|
+
}
|
|
5586
|
+
};
|
|
5587
|
+
exports.isGhAuthenticated = isGhAuthenticated;
|
|
5588
|
+
/**
|
|
5589
|
+
* the github repository (owner/name) a git remote points to.
|
|
5590
|
+
* Which remote belongs to github is configured per pipeline type
|
|
5591
|
+
* (`pipelines.github.gitRemote`, defaults to origin).
|
|
5592
|
+
*/
|
|
5593
|
+
const getGithubRepoFromRemote = async remoteName => {
|
|
5594
|
+
try {
|
|
5595
|
+
const {
|
|
5596
|
+
stdout
|
|
5597
|
+
} = await execFile("git", ["remote", "get-url", remoteName]);
|
|
5598
|
+
const match = stdout.match(/github\.com[:/]([\w.-]+\/[\w.-]+?)(\.git)?\s*$/);
|
|
5599
|
+
return match === null || match === void 0 ? void 0 : match[1];
|
|
5600
|
+
} catch (_a) {
|
|
5601
|
+
return undefined;
|
|
5602
|
+
}
|
|
5603
|
+
};
|
|
5604
|
+
exports.getGithubRepoFromRemote = getGithubRepoFromRemote;
|
|
5605
|
+
/**
|
|
5606
|
+
* sets a github actions repository secret via the gh cli.
|
|
5607
|
+
* The value is passed via stdin so it never shows up in a process list.
|
|
5608
|
+
*/
|
|
5609
|
+
const setGithubSecret = async (repo, name, value) => new Promise((resolve, reject) => {
|
|
5610
|
+
var _a, _b;
|
|
5611
|
+
const child = (0, child_process_1.spawn)("gh", ["secret", "set", name, "--repo", repo], {
|
|
5612
|
+
stdio: ["pipe", "ignore", "pipe"]
|
|
5613
|
+
});
|
|
5614
|
+
let stderr = "";
|
|
5615
|
+
(_a = child.stderr) === null || _a === void 0 ? void 0 : _a.on("data", data => stderr += data);
|
|
5616
|
+
child.on("error", reject);
|
|
5617
|
+
child.on("close", code => code === 0 ? resolve() : reject(new Error(`gh secret set ${name} failed: ${stderr.trim()}`)));
|
|
5618
|
+
(_b = child.stdin) === null || _b === void 0 ? void 0 : _b.end(value);
|
|
5619
|
+
});
|
|
5620
|
+
exports.setGithubSecret = setGithubSecret;
|
|
5621
|
+
|
|
5622
|
+
/***/ }),
|
|
5623
|
+
|
|
5309
5624
|
/***/ 4508:
|
|
5310
5625
|
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
|
5311
5626
|
|
|
@@ -5845,6 +6160,445 @@ exports.getShell = getShell;
|
|
|
5845
6160
|
|
|
5846
6161
|
/***/ }),
|
|
5847
6162
|
|
|
6163
|
+
/***/ 63510:
|
|
6164
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
6165
|
+
|
|
6166
|
+
"use strict";
|
|
6167
|
+
|
|
6168
|
+
|
|
6169
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
6170
|
+
value: true
|
|
6171
|
+
}));
|
|
6172
|
+
exports.BitwardenVault = void 0;
|
|
6173
|
+
const pipeline_1 = __nccwpck_require__(60241);
|
|
6174
|
+
const yaml_1 = __nccwpck_require__(6637);
|
|
6175
|
+
const bw_1 = __nccwpck_require__(52211);
|
|
6176
|
+
const DEFAULT_COLLECTION = "catladder";
|
|
6177
|
+
const SECURE_NOTE_TYPE = 2;
|
|
6178
|
+
/**
|
|
6179
|
+
* one yaml note per env and component:
|
|
6180
|
+
* `<customerName>/<appName>/<env>/<componentName>/secrets.yml`
|
|
6181
|
+
*/
|
|
6182
|
+
const itemName = (config, env, componentName) => `${config.customerName}/${config.appName}/${env}/${componentName}/secrets.yml`;
|
|
6183
|
+
const itemPrefix = config => `${config.customerName}/${config.appName}/`;
|
|
6184
|
+
/**
|
|
6185
|
+
* parses env and componentName back out of an item name
|
|
6186
|
+
*/
|
|
6187
|
+
const parseItemName = (config, name) => {
|
|
6188
|
+
const match = name.slice(itemPrefix(config).length).match(/^([^/]+)\/([^/]+)\/secrets\.yml$/);
|
|
6189
|
+
return match ? {
|
|
6190
|
+
env: match[1],
|
|
6191
|
+
componentName: match[2]
|
|
6192
|
+
} : null;
|
|
6193
|
+
};
|
|
6194
|
+
const findCollection = async (session, collectionName) => {
|
|
6195
|
+
const collections = await (0, bw_1.runBwJson)(session, ["list", "collections", "--search", collectionName]);
|
|
6196
|
+
const collection = collections.find(c => c.name === collectionName);
|
|
6197
|
+
if (!collection) {
|
|
6198
|
+
throw new Error(`bitwarden collection '${collectionName}' not found — create it and make sure you have access`);
|
|
6199
|
+
}
|
|
6200
|
+
return collection;
|
|
6201
|
+
};
|
|
6202
|
+
const encodePayload = payload => Buffer.from(JSON.stringify(payload), "utf-8").toString("base64");
|
|
6203
|
+
class BitwardenVault {
|
|
6204
|
+
constructor(config, options,
|
|
6205
|
+
/**
|
|
6206
|
+
* whether a locked bitwarden may be unlocked interactively
|
|
6207
|
+
* (false with catenv --vault-mode no-prompt)
|
|
6208
|
+
*/
|
|
6209
|
+
allowPrompt) {
|
|
6210
|
+
var _a;
|
|
6211
|
+
this.config = config;
|
|
6212
|
+
this.allowPrompt = allowPrompt;
|
|
6213
|
+
this.collectionName = (_a = options.collection) !== null && _a !== void 0 ? _a : DEFAULT_COLLECTION;
|
|
6214
|
+
this.id = `bitwarden:${this.collectionName}`;
|
|
6215
|
+
}
|
|
6216
|
+
session(io) {
|
|
6217
|
+
return (0, bw_1.getBwSession)(io, {
|
|
6218
|
+
allowPrompt: this.allowPrompt
|
|
6219
|
+
});
|
|
6220
|
+
}
|
|
6221
|
+
async readAllSecrets(io) {
|
|
6222
|
+
const {
|
|
6223
|
+
config,
|
|
6224
|
+
collectionName
|
|
6225
|
+
} = this;
|
|
6226
|
+
const bwSession = await this.session(io);
|
|
6227
|
+
const collection = await findCollection(bwSession, collectionName);
|
|
6228
|
+
const items = await (0, bw_1.runBwJson)(bwSession, ["list", "items", "--collectionid", collection.id]);
|
|
6229
|
+
const secrets = {};
|
|
6230
|
+
for (const item of items) {
|
|
6231
|
+
const parsed = parseItemName(config, item.name);
|
|
6232
|
+
if (!parsed || !item.notes) {
|
|
6233
|
+
continue;
|
|
6234
|
+
}
|
|
6235
|
+
const values = (0, yaml_1.parse)(item.notes);
|
|
6236
|
+
Object.entries(values !== null && values !== void 0 ? values : {}).forEach(([key, value]) => {
|
|
6237
|
+
secrets[(0, pipeline_1.getSecretVarName)(parsed.env, parsed.componentName, key)] = typeof value === "string" ? value : JSON.stringify(value);
|
|
6238
|
+
});
|
|
6239
|
+
}
|
|
6240
|
+
return secrets;
|
|
6241
|
+
}
|
|
6242
|
+
async writeSecrets(io, env, componentName, secrets) {
|
|
6243
|
+
const {
|
|
6244
|
+
config,
|
|
6245
|
+
collectionName
|
|
6246
|
+
} = this;
|
|
6247
|
+
const bwSession = await this.session(io);
|
|
6248
|
+
const collection = await findCollection(bwSession, collectionName);
|
|
6249
|
+
const name = itemName(config, env, componentName);
|
|
6250
|
+
const existing = (await (0, bw_1.runBwJson)(bwSession, ["list", "items", "--collectionid", collection.id, "--search", name])).find(item => item.name === name);
|
|
6251
|
+
const notes = (0, yaml_1.stringify)(secrets);
|
|
6252
|
+
if (existing) {
|
|
6253
|
+
await (0, bw_1.runBw)(bwSession, ["edit", "item", existing.id, encodePayload({
|
|
6254
|
+
...existing,
|
|
6255
|
+
notes
|
|
6256
|
+
})]);
|
|
6257
|
+
} else {
|
|
6258
|
+
await (0, bw_1.runBw)(bwSession, ["create", "item", encodePayload({
|
|
6259
|
+
type: SECURE_NOTE_TYPE,
|
|
6260
|
+
secureNote: {
|
|
6261
|
+
type: 0
|
|
6262
|
+
},
|
|
6263
|
+
name,
|
|
6264
|
+
notes,
|
|
6265
|
+
...(collection.organizationId ? {
|
|
6266
|
+
organizationId: collection.organizationId,
|
|
6267
|
+
collectionIds: [collection.id]
|
|
6268
|
+
} : {})
|
|
6269
|
+
})]);
|
|
6270
|
+
}
|
|
6271
|
+
}
|
|
6272
|
+
}
|
|
6273
|
+
exports.BitwardenVault = BitwardenVault;
|
|
6274
|
+
|
|
6275
|
+
/***/ }),
|
|
6276
|
+
|
|
6277
|
+
/***/ 31107:
|
|
6278
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
6279
|
+
|
|
6280
|
+
"use strict";
|
|
6281
|
+
|
|
6282
|
+
|
|
6283
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
6284
|
+
value: true
|
|
6285
|
+
}));
|
|
6286
|
+
exports.GitlabVault = void 0;
|
|
6287
|
+
const gitlab_1 = __nccwpck_require__(4508);
|
|
6288
|
+
/**
|
|
6289
|
+
* the legacy (and default) vault: the gitlab project variables double
|
|
6290
|
+
* as the secret store
|
|
6291
|
+
*/
|
|
6292
|
+
class GitlabVault {
|
|
6293
|
+
constructor() {
|
|
6294
|
+
this.id = "gitlab";
|
|
6295
|
+
}
|
|
6296
|
+
async readAllSecrets(io) {
|
|
6297
|
+
const variables = await (0, gitlab_1.getAllVariables)(io);
|
|
6298
|
+
return Object.fromEntries(variables.map(v => [v.key, v.value]));
|
|
6299
|
+
}
|
|
6300
|
+
async writeSecrets(io, env, componentName, secrets) {
|
|
6301
|
+
await (0, gitlab_1.upsertAllVariables)(io, secrets, env, componentName);
|
|
6302
|
+
}
|
|
6303
|
+
}
|
|
6304
|
+
exports.GitlabVault = GitlabVault;
|
|
6305
|
+
|
|
6306
|
+
/***/ }),
|
|
6307
|
+
|
|
6308
|
+
/***/ 55771:
|
|
6309
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
6310
|
+
|
|
6311
|
+
"use strict";
|
|
6312
|
+
|
|
6313
|
+
|
|
6314
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
6315
|
+
value: true
|
|
6316
|
+
}));
|
|
6317
|
+
exports.VaultManager = void 0;
|
|
6318
|
+
const pipeline_1 = __nccwpck_require__(60241);
|
|
6319
|
+
const BitwardenVault_1 = __nccwpck_require__(63510);
|
|
6320
|
+
const cache_1 = __nccwpck_require__(14236);
|
|
6321
|
+
const GitlabVault_1 = __nccwpck_require__(31107);
|
|
6322
|
+
/**
|
|
6323
|
+
* only secrets of this env are cached locally — the other envs'
|
|
6324
|
+
* secrets have no business sitting on developer machines
|
|
6325
|
+
*/
|
|
6326
|
+
const CACHED_ENV = "local";
|
|
6327
|
+
/**
|
|
6328
|
+
* owns the configured vault, the secrets mode and the local cache.
|
|
6329
|
+
* The vault is the readable source of truth for secrets; CI backends
|
|
6330
|
+
* only receive mirrored copies.
|
|
6331
|
+
*/
|
|
6332
|
+
class VaultManager {
|
|
6333
|
+
constructor(config, options = {}) {
|
|
6334
|
+
var _a, _b;
|
|
6335
|
+
this.config = config;
|
|
6336
|
+
/** refresh mode bypasses the cache only once per manager */
|
|
6337
|
+
this.refreshed = false;
|
|
6338
|
+
this.mode = (_a = options.mode) !== null && _a !== void 0 ? _a : "auto";
|
|
6339
|
+
this.io = (_b = options.io) !== null && _b !== void 0 ? _b : null;
|
|
6340
|
+
this.vault = this.createVault();
|
|
6341
|
+
}
|
|
6342
|
+
createVault() {
|
|
6343
|
+
const vaultConfig = (0, pipeline_1.getVaultConfig)(this.config);
|
|
6344
|
+
switch (vaultConfig.type) {
|
|
6345
|
+
case "gitlab":
|
|
6346
|
+
return new GitlabVault_1.GitlabVault();
|
|
6347
|
+
case "bitwarden":
|
|
6348
|
+
return new BitwardenVault_1.BitwardenVault(this.config, vaultConfig, this.mode === "auto" || this.mode === "refresh");
|
|
6349
|
+
}
|
|
6350
|
+
}
|
|
6351
|
+
/**
|
|
6352
|
+
* the vault secrets, served from the local cache when it contains
|
|
6353
|
+
* all required names; otherwise (depending on the mode) refreshed
|
|
6354
|
+
* from the vault. Only the "local" env is (re-)cached.
|
|
6355
|
+
*/
|
|
6356
|
+
async readSecrets(requiredNames, io = this.io) {
|
|
6357
|
+
const bypassCache = this.mode === "refresh" && !this.refreshed;
|
|
6358
|
+
const cache = bypassCache ? null : await (0, cache_1.readSecretsCache)();
|
|
6359
|
+
// known entries include recorded misses (null values), so declared
|
|
6360
|
+
// but intentionally unset secrets don't force a vault refresh
|
|
6361
|
+
const known = (cache === null || cache === void 0 ? void 0 : cache.vaultId) === this.vault.id ? flattenSecrets(cache.secrets) : undefined;
|
|
6362
|
+
const missing = requiredNames.filter(name => !(name in (known !== null && known !== void 0 ? known : {})));
|
|
6363
|
+
// nothing missing (or nothing required at all): don't touch the vault
|
|
6364
|
+
if (missing.length === 0 && (known || requiredNames.length === 0)) {
|
|
6365
|
+
return withoutMisses(known !== null && known !== void 0 ? known : {});
|
|
6366
|
+
}
|
|
6367
|
+
if (this.mode === "offline") {
|
|
6368
|
+
if (missing.length > 0) {
|
|
6369
|
+
io === null || io === void 0 ? void 0 : io.log(`⚠️ vault is offline (--vault-mode offline) and ${missing.length} secrets are not in the local cache: ${missing.join(", ")}`);
|
|
6370
|
+
}
|
|
6371
|
+
return withoutMisses(known !== null && known !== void 0 ? known : {});
|
|
6372
|
+
}
|
|
6373
|
+
const secrets = await this.vault.readAllSecrets(io);
|
|
6374
|
+
this.refreshed = true;
|
|
6375
|
+
await (0, cache_1.writeSecretsCache)(this.vault.id, await this.cacheableSubset(secrets));
|
|
6376
|
+
return secrets;
|
|
6377
|
+
}
|
|
6378
|
+
/**
|
|
6379
|
+
* writes secrets of one env/component to the vault and updates the
|
|
6380
|
+
* local cache (write-through, "local" env only)
|
|
6381
|
+
*/
|
|
6382
|
+
async writeSecrets(env, componentName, secrets, io = this.io) {
|
|
6383
|
+
if (!io) {
|
|
6384
|
+
throw new Error("writing to the vault requires an interactive context");
|
|
6385
|
+
}
|
|
6386
|
+
await this.vault.writeSecrets(io, env, componentName, secrets);
|
|
6387
|
+
if (env === CACHED_ENV) {
|
|
6388
|
+
await (0, cache_1.updateSecretsCache)(this.vault.id, env, componentName, Object.fromEntries(Object.entries(secrets).map(([key, value]) => [key, typeof value === "string" ? value : JSON.stringify(value)])));
|
|
6389
|
+
}
|
|
6390
|
+
}
|
|
6391
|
+
/**
|
|
6392
|
+
* the subset of the vault secrets that may be cached: the declared
|
|
6393
|
+
* secrets of the "local" env, per component, as a hierarchy
|
|
6394
|
+
*/
|
|
6395
|
+
async cacheableSubset(flatSecrets) {
|
|
6396
|
+
const local = {};
|
|
6397
|
+
for (const componentName of Object.keys(this.config.components)) {
|
|
6398
|
+
const keys = await this.declaredSecretKeys(componentName);
|
|
6399
|
+
const values = Object.fromEntries(keys.map(key => {
|
|
6400
|
+
var _a;
|
|
6401
|
+
return [key,
|
|
6402
|
+
// null records "absent in the vault" (a known miss)
|
|
6403
|
+
(_a = flatSecrets[(0, pipeline_1.getSecretVarName)(CACHED_ENV, componentName, key)]) !== null && _a !== void 0 ? _a : null];
|
|
6404
|
+
}));
|
|
6405
|
+
if (Object.keys(values).length > 0) {
|
|
6406
|
+
local[componentName] = values;
|
|
6407
|
+
}
|
|
6408
|
+
}
|
|
6409
|
+
return Object.keys(local).length > 0 ? {
|
|
6410
|
+
[CACHED_ENV]: local
|
|
6411
|
+
} : {};
|
|
6412
|
+
}
|
|
6413
|
+
async declaredSecretKeys(componentName) {
|
|
6414
|
+
try {
|
|
6415
|
+
const {
|
|
6416
|
+
secretEnvVarKeys,
|
|
6417
|
+
jobOnlyVars
|
|
6418
|
+
} = await (0, pipeline_1.getEnvironment)({
|
|
6419
|
+
config: this.config,
|
|
6420
|
+
componentName,
|
|
6421
|
+
env: CACHED_ENV
|
|
6422
|
+
});
|
|
6423
|
+
return [...secretEnvVarKeys, ...jobOnlyVars.build.secretEnvVarKeys, ...jobOnlyVars.deploy.secretEnvVarKeys].map(({
|
|
6424
|
+
key
|
|
6425
|
+
}) => key);
|
|
6426
|
+
} catch (_a) {
|
|
6427
|
+
// components without a local env simply have nothing to cache
|
|
6428
|
+
return [];
|
|
6429
|
+
}
|
|
6430
|
+
}
|
|
6431
|
+
}
|
|
6432
|
+
exports.VaultManager = VaultManager;
|
|
6433
|
+
/**
|
|
6434
|
+
* the cache hierarchy as a flat map of raw secret variable names
|
|
6435
|
+
* (null values = recorded misses)
|
|
6436
|
+
*/
|
|
6437
|
+
const flattenSecrets = secrets => Object.fromEntries(Object.entries(secrets).flatMap(([env, components]) => Object.entries(components).flatMap(([componentName, values]) => Object.entries(values).map(([key, value]) => [(0, pipeline_1.getSecretVarName)(env, componentName, key), value]))));
|
|
6438
|
+
/**
|
|
6439
|
+
* only actual values — recorded misses stay unresolved, like any other
|
|
6440
|
+
* unset variable
|
|
6441
|
+
*/
|
|
6442
|
+
const withoutMisses = known => Object.fromEntries(Object.entries(known).filter(entry => entry[1] !== null));
|
|
6443
|
+
|
|
6444
|
+
/***/ }),
|
|
6445
|
+
|
|
6446
|
+
/***/ 52211:
|
|
6447
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
6448
|
+
|
|
6449
|
+
"use strict";
|
|
6450
|
+
|
|
6451
|
+
|
|
6452
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
6453
|
+
value: true
|
|
6454
|
+
}));
|
|
6455
|
+
exports.runBwJson = exports.runBw = exports.getBwSession = void 0;
|
|
6456
|
+
const child_process_1 = __nccwpck_require__(35317);
|
|
6457
|
+
const util_1 = __nccwpck_require__(39023);
|
|
6458
|
+
const preferences_1 = __nccwpck_require__(66261);
|
|
6459
|
+
const execFile = (0, util_1.promisify)(child_process_1.execFile);
|
|
6460
|
+
const SESSION_PREFERENCE = "bwsession";
|
|
6461
|
+
class BitwardenLockedError extends Error {
|
|
6462
|
+
constructor() {
|
|
6463
|
+
super("bitwarden is locked and prompting is disabled — run `bw unlock` or catenv without --vault-mode no-prompt");
|
|
6464
|
+
}
|
|
6465
|
+
}
|
|
6466
|
+
/**
|
|
6467
|
+
* runs an interactive bw command that prints a session key on stdout
|
|
6468
|
+
* (login/unlock) while the user types the password on the terminal
|
|
6469
|
+
*/
|
|
6470
|
+
const interactiveSessionCommand = args => new Promise((resolve, reject) => {
|
|
6471
|
+
var _a;
|
|
6472
|
+
const child = (0, child_process_1.spawn)("bw", [...args, "--raw"], {
|
|
6473
|
+
stdio: ["inherit", "pipe", "inherit"]
|
|
6474
|
+
});
|
|
6475
|
+
let session = "";
|
|
6476
|
+
(_a = child.stdout) === null || _a === void 0 ? void 0 : _a.on("data", data => session += data.toString("utf-8"));
|
|
6477
|
+
child.on("error", reject);
|
|
6478
|
+
child.on("close", code => code === 0 && session.trim() ? resolve(session.trim()) : reject(new Error(`bw ${args[0]} failed`)));
|
|
6479
|
+
});
|
|
6480
|
+
const getBwStatus = async session => {
|
|
6481
|
+
try {
|
|
6482
|
+
const {
|
|
6483
|
+
stdout
|
|
6484
|
+
} = await execFile("bw", ["status"], {
|
|
6485
|
+
env: {
|
|
6486
|
+
...process.env,
|
|
6487
|
+
...(session ? {
|
|
6488
|
+
BW_SESSION: session
|
|
6489
|
+
} : {})
|
|
6490
|
+
}
|
|
6491
|
+
});
|
|
6492
|
+
return JSON.parse(stdout).status;
|
|
6493
|
+
} catch (_a) {
|
|
6494
|
+
return "unauthenticated";
|
|
6495
|
+
}
|
|
6496
|
+
};
|
|
6497
|
+
/**
|
|
6498
|
+
* a working bw session: reuses the cached one, otherwise unlocks (or
|
|
6499
|
+
* logs in) interactively — unless prompting is disabled
|
|
6500
|
+
*/
|
|
6501
|
+
const getBwSession = async (io, {
|
|
6502
|
+
allowPrompt
|
|
6503
|
+
}) => {
|
|
6504
|
+
const cached = (await (0, preferences_1.hasPreference)(SESSION_PREFERENCE)) ? String(await (0, preferences_1.getPreference)(SESSION_PREFERENCE)) : null;
|
|
6505
|
+
const status = await getBwStatus(cached);
|
|
6506
|
+
if (status === "unlocked" && cached) {
|
|
6507
|
+
return cached;
|
|
6508
|
+
}
|
|
6509
|
+
if (!allowPrompt) {
|
|
6510
|
+
throw new BitwardenLockedError();
|
|
6511
|
+
}
|
|
6512
|
+
io === null || io === void 0 ? void 0 : io.log("");
|
|
6513
|
+
io === null || io === void 0 ? void 0 : io.log(status === "unauthenticated" ? "# Please login to Bitwarden:" : "# Bitwarden is locked, please unlock:");
|
|
6514
|
+
io === null || io === void 0 ? void 0 : io.log("");
|
|
6515
|
+
const session = await interactiveSessionCommand([status === "unauthenticated" ? "login" : "unlock"]);
|
|
6516
|
+
await (0, preferences_1.setPreference)(SESSION_PREFERENCE, session);
|
|
6517
|
+
await (0, exports.runBw)(session, ["sync"]);
|
|
6518
|
+
return session;
|
|
6519
|
+
};
|
|
6520
|
+
exports.getBwSession = getBwSession;
|
|
6521
|
+
/**
|
|
6522
|
+
* runs a bw command with the given session and returns stdout
|
|
6523
|
+
*/
|
|
6524
|
+
const runBw = async (session, args) => {
|
|
6525
|
+
const {
|
|
6526
|
+
stdout
|
|
6527
|
+
} = await execFile("bw", [...args, "--raw", "--nointeraction"], {
|
|
6528
|
+
env: {
|
|
6529
|
+
...process.env,
|
|
6530
|
+
BW_SESSION: session
|
|
6531
|
+
},
|
|
6532
|
+
maxBuffer: 50 * 1024 * 1024
|
|
6533
|
+
});
|
|
6534
|
+
return stdout;
|
|
6535
|
+
};
|
|
6536
|
+
exports.runBw = runBw;
|
|
6537
|
+
const runBwJson = async (session, args) => JSON.parse(await (0, exports.runBw)(session, args));
|
|
6538
|
+
exports.runBwJson = runBwJson;
|
|
6539
|
+
|
|
6540
|
+
/***/ }),
|
|
6541
|
+
|
|
6542
|
+
/***/ 14236:
|
|
6543
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
6544
|
+
|
|
6545
|
+
"use strict";
|
|
6546
|
+
|
|
6547
|
+
|
|
6548
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
6549
|
+
value: true
|
|
6550
|
+
}));
|
|
6551
|
+
exports.updateSecretsCache = exports.writeSecretsCache = exports.readSecretsCache = void 0;
|
|
6552
|
+
const promises_1 = __nccwpck_require__(91943);
|
|
6553
|
+
const path_1 = __nccwpck_require__(16928);
|
|
6554
|
+
const gitProjectInformation_1 = __nccwpck_require__(21111);
|
|
6555
|
+
const getCacheFolder = async () => (0, path_1.join)(await (0, gitProjectInformation_1.getProjectRootPath)(), ".catladder");
|
|
6556
|
+
const getCachePath = async () => (0, path_1.join)(await getCacheFolder(), "secrets.json");
|
|
6557
|
+
const readSecretsCache = async () => {
|
|
6558
|
+
try {
|
|
6559
|
+
return JSON.parse(await (0, promises_1.readFile)(await getCachePath(), "utf-8"));
|
|
6560
|
+
} catch (_a) {
|
|
6561
|
+
return null;
|
|
6562
|
+
}
|
|
6563
|
+
};
|
|
6564
|
+
exports.readSecretsCache = readSecretsCache;
|
|
6565
|
+
const writeSecretsCache = async (vaultId, secrets) => {
|
|
6566
|
+
const folder = await getCacheFolder();
|
|
6567
|
+
await (0, promises_1.mkdir)(folder, {
|
|
6568
|
+
recursive: true
|
|
6569
|
+
});
|
|
6570
|
+
// the folder ignores itself, so the cache can never be committed
|
|
6571
|
+
await (0, promises_1.writeFile)((0, path_1.join)(folder, ".gitignore"), "*\n");
|
|
6572
|
+
const cache = {
|
|
6573
|
+
vaultId,
|
|
6574
|
+
updatedAt: new Date().toISOString(),
|
|
6575
|
+
secrets
|
|
6576
|
+
};
|
|
6577
|
+
await (0, promises_1.writeFile)(await getCachePath(), JSON.stringify(cache, null, 2));
|
|
6578
|
+
};
|
|
6579
|
+
exports.writeSecretsCache = writeSecretsCache;
|
|
6580
|
+
/**
|
|
6581
|
+
* merges freshly written secrets of one env/component into the cache
|
|
6582
|
+
* (write-through from config-secrets), so the next catenv run doesn't
|
|
6583
|
+
* need the vault
|
|
6584
|
+
*/
|
|
6585
|
+
const updateSecretsCache = async (vaultId, env, componentName, values) => {
|
|
6586
|
+
var _a;
|
|
6587
|
+
const existing = await (0, exports.readSecretsCache)();
|
|
6588
|
+
const secrets = (existing === null || existing === void 0 ? void 0 : existing.vaultId) === vaultId ? existing.secrets : {};
|
|
6589
|
+
secrets[env] = {
|
|
6590
|
+
...secrets[env],
|
|
6591
|
+
[componentName]: {
|
|
6592
|
+
...((_a = secrets[env]) === null || _a === void 0 ? void 0 : _a[componentName]),
|
|
6593
|
+
...values
|
|
6594
|
+
}
|
|
6595
|
+
};
|
|
6596
|
+
await (0, exports.writeSecretsCache)(vaultId, secrets);
|
|
6597
|
+
};
|
|
6598
|
+
exports.updateSecretsCache = updateSecretsCache;
|
|
6599
|
+
|
|
6600
|
+
/***/ }),
|
|
6601
|
+
|
|
5848
6602
|
/***/ 54038:
|
|
5849
6603
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
5850
6604
|
|
|
@@ -7163,7 +7917,7 @@ var __exportStar = this && this.__exportStar || function (m, exports) {
|
|
|
7163
7917
|
Object.defineProperty(exports, "__esModule", ({
|
|
7164
7918
|
value: true
|
|
7165
7919
|
}));
|
|
7166
|
-
exports.getEnabledPipelineTypes = exports.getPipelineBackend = void 0;
|
|
7920
|
+
exports.getEnabledPipelineTypes = exports.getVaultConfig = exports.getPipelineGitRemote = exports.getPipelineOptions = exports.getPipelineBackend = void 0;
|
|
7167
7921
|
const github_1 = __nccwpck_require__(99635);
|
|
7168
7922
|
const gitlab_1 = __nccwpck_require__(8475);
|
|
7169
7923
|
__exportStar(__nccwpck_require__(92474), exports);
|
|
@@ -7181,6 +7935,38 @@ const getPipelineBackend = type => {
|
|
|
7181
7935
|
return createBackend();
|
|
7182
7936
|
};
|
|
7183
7937
|
exports.getPipelineBackend = getPipelineBackend;
|
|
7938
|
+
/**
|
|
7939
|
+
* the options of an enabled pipeline type (empty object when enabled
|
|
7940
|
+
* with `true`)
|
|
7941
|
+
*/
|
|
7942
|
+
const getPipelineOptions = (config, type) => {
|
|
7943
|
+
var _a;
|
|
7944
|
+
const value = (_a = config.pipelines) === null || _a === void 0 ? void 0 : _a[type];
|
|
7945
|
+
return typeof value === "object" ? value : {};
|
|
7946
|
+
};
|
|
7947
|
+
exports.getPipelineOptions = getPipelineOptions;
|
|
7948
|
+
/**
|
|
7949
|
+
* the git remote pointing to the repository of this pipeline type's CI
|
|
7950
|
+
* system (e.g. during a migration, gitlab may be `origin` and github a
|
|
7951
|
+
* second remote)
|
|
7952
|
+
*/
|
|
7953
|
+
const getPipelineGitRemote = (config, type) => {
|
|
7954
|
+
var _a;
|
|
7955
|
+
return (_a = (0, exports.getPipelineOptions)(config, type).gitRemote) !== null && _a !== void 0 ? _a : "origin";
|
|
7956
|
+
};
|
|
7957
|
+
exports.getPipelineGitRemote = getPipelineGitRemote;
|
|
7958
|
+
/**
|
|
7959
|
+
* the normalized secrets vault of a config (string shorthands resolved
|
|
7960
|
+
* to their object form; defaults to the legacy gitlab store)
|
|
7961
|
+
*/
|
|
7962
|
+
const getVaultConfig = config => {
|
|
7963
|
+
var _a, _b;
|
|
7964
|
+
const vault = (_b = (_a = config.secrets) === null || _a === void 0 ? void 0 : _a.vault) !== null && _b !== void 0 ? _b : "gitlab";
|
|
7965
|
+
return typeof vault === "string" ? {
|
|
7966
|
+
type: vault
|
|
7967
|
+
} : vault;
|
|
7968
|
+
};
|
|
7969
|
+
exports.getVaultConfig = getVaultConfig;
|
|
7184
7970
|
/**
|
|
7185
7971
|
* the pipeline types enabled for this config. Multiple types can be
|
|
7186
7972
|
* enabled at once (parallel generation, e.g. during a CI migration).
|
|
@@ -9147,7 +9933,7 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
9147
9933
|
value: true
|
|
9148
9934
|
}));
|
|
9149
9935
|
exports.DOCKER_REGISTRY = exports.PIPELINE_IMAGE_TAG = void 0;
|
|
9150
|
-
exports.PIPELINE_IMAGE_TAG = "next-
|
|
9936
|
+
exports.PIPELINE_IMAGE_TAG = "next-8b9ad5ca" || 0;
|
|
9151
9937
|
exports.DOCKER_REGISTRY = "git.panter.ch:5001/catladder/catladder" || 0;
|
|
9152
9938
|
|
|
9153
9939
|
/***/ }),
|
|
@@ -11052,13 +11838,15 @@ exports.GCLOUD_RUN_DEPLOY_TYPE = {
|
|
|
11052
11838
|
}
|
|
11053
11839
|
return {};
|
|
11054
11840
|
},
|
|
11055
|
-
additionalSecretKeys: ctx => [
|
|
11841
|
+
additionalSecretKeys: ctx => [
|
|
11842
|
+
// deploy-time credentials don't exist for the local env
|
|
11843
|
+
...(ctx.envType !== "local" ? [{
|
|
11056
11844
|
key: exports.GCLOUD_DEPLOY_CREDENTIALS_KEY,
|
|
11057
11845
|
hidden: true
|
|
11058
11846
|
}, {
|
|
11059
11847
|
key: exports.GCLOUD_RUN_CANONICAL_HOST_SUFFIX,
|
|
11060
11848
|
hidden: true
|
|
11061
|
-
}, ...(ctx.deployConfigRaw && ctx.deployConfigRaw.cloudSql ? [{
|
|
11849
|
+
}] : []), ...(ctx.deployConfigRaw && ctx.deployConfigRaw.cloudSql ? [{
|
|
11062
11850
|
key: "DB_PASSWORD"
|
|
11063
11851
|
}] : [])],
|
|
11064
11852
|
getAdditionalEnvVars: ctx => {
|
|
@@ -11066,7 +11854,8 @@ exports.GCLOUD_RUN_DEPLOY_TYPE = {
|
|
|
11066
11854
|
fullName,
|
|
11067
11855
|
env,
|
|
11068
11856
|
componentName,
|
|
11069
|
-
deployConfigRaw
|
|
11857
|
+
deployConfigRaw,
|
|
11858
|
+
envType
|
|
11070
11859
|
} = ctx;
|
|
11071
11860
|
const HOSTNAME_INTERNAL = (0, BashExpression_1.joinBashExpressions)([fullName, (0, BashExpression_1.getBashVariable)((0, context_1.getSecretVarName)(env, componentName, exports.GCLOUD_RUN_CANONICAL_HOST_SUFFIX))], "-").toLowerCase();
|
|
11072
11861
|
const jobTriggers = deployConfigRaw && deployConfigRaw.jobs ? Object.fromEntries(Object.entries(deployConfigRaw.jobs).filter(([name, job]) => Boolean(job)).map(([name, job]) => ["CLOUD_RUN_JOB_TRIGGER_URL_" + (0, gitlab_1.sanitizeForBashVariable)(name), (0, cloudRunExecutionUrl_1.getCloudRunJobExecuteUrl)(name, {
|
|
@@ -11075,7 +11864,11 @@ exports.GCLOUD_RUN_DEPLOY_TYPE = {
|
|
|
11075
11864
|
region: deployConfigRaw.region
|
|
11076
11865
|
})])) : {};
|
|
11077
11866
|
return {
|
|
11078
|
-
|
|
11867
|
+
// references the canonical host suffix secret, which doesn't
|
|
11868
|
+
// exist for the local env
|
|
11869
|
+
...(envType !== "local" ? {
|
|
11870
|
+
HOSTNAME_INTERNAL
|
|
11871
|
+
} : {}),
|
|
11079
11872
|
...getCloudSqlVariables(ctx),
|
|
11080
11873
|
...jobTriggers,
|
|
11081
11874
|
DEPLOY_CLOUD_RUN_SERVICE_NAME: (0, getServiceName_1.getServiceNameForEnvContext)(ctx),
|