@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
|
@@ -1,6 +1,78 @@
|
|
|
1
1
|
/******/ (() => { // webpackBootstrap
|
|
2
2
|
/******/ var __webpack_modules__ = ({
|
|
3
3
|
|
|
4
|
+
/***/ 1917:
|
|
5
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
11
|
+
value: true
|
|
12
|
+
}));
|
|
13
|
+
exports.createNonInteractiveIO = void 0;
|
|
14
|
+
const types_1 = __nccwpck_require__(2284);
|
|
15
|
+
const vaultManagerAccess_1 = __nccwpck_require__(7881);
|
|
16
|
+
/**
|
|
17
|
+
* the context of non-interactive runs (catenv via direnv): logging
|
|
18
|
+
* goes to stderr, any required interaction fails with a clear error.
|
|
19
|
+
*/
|
|
20
|
+
function createNonInteractiveIO(options = {}) {
|
|
21
|
+
const io = {
|
|
22
|
+
interactive: false,
|
|
23
|
+
getVaultManager: (0, vaultManagerAccess_1.createVaultManagerGetter)(() => io, {
|
|
24
|
+
mode: options.vaultMode
|
|
25
|
+
}),
|
|
26
|
+
log(message) {
|
|
27
|
+
// stderr: stdout may be evaluated (direnv)
|
|
28
|
+
console.error(message);
|
|
29
|
+
},
|
|
30
|
+
async confirm(message) {
|
|
31
|
+
throw new types_1.NonInteractiveError(`confirmation ("${message}")`);
|
|
32
|
+
},
|
|
33
|
+
async promptDirect(spec) {
|
|
34
|
+
throw new types_1.NonInteractiveError(`input "${spec.name}"`);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
return io;
|
|
38
|
+
}
|
|
39
|
+
exports.createNonInteractiveIO = createNonInteractiveIO;
|
|
40
|
+
|
|
41
|
+
/***/ }),
|
|
42
|
+
|
|
43
|
+
/***/ 7881:
|
|
44
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
45
|
+
|
|
46
|
+
"use strict";
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
50
|
+
value: true
|
|
51
|
+
}));
|
|
52
|
+
exports.createVaultManagerGetter = void 0;
|
|
53
|
+
const getProjectConfig_1 = __nccwpck_require__(1);
|
|
54
|
+
const VaultManager_1 = __nccwpck_require__(5771);
|
|
55
|
+
/**
|
|
56
|
+
* lazily creates the vault manager of a context (once per context),
|
|
57
|
+
* loading the project config on first use
|
|
58
|
+
*/
|
|
59
|
+
const createVaultManagerGetter = (io, options = {}) => {
|
|
60
|
+
let managerPromise;
|
|
61
|
+
return () => managerPromise !== null && managerPromise !== void 0 ? managerPromise : managerPromise = (async () => {
|
|
62
|
+
const config = await (0, getProjectConfig_1.getProjectConfig)();
|
|
63
|
+
if (!config) {
|
|
64
|
+
throw new Error("no catladder config found — the secrets vault needs a project config");
|
|
65
|
+
}
|
|
66
|
+
return new VaultManager_1.VaultManager(config, {
|
|
67
|
+
...options,
|
|
68
|
+
io: io()
|
|
69
|
+
});
|
|
70
|
+
})();
|
|
71
|
+
};
|
|
72
|
+
exports.createVaultManagerGetter = createVaultManagerGetter;
|
|
73
|
+
|
|
74
|
+
/***/ }),
|
|
75
|
+
|
|
4
76
|
/***/ 6057:
|
|
5
77
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
6
78
|
|
|
@@ -16,12 +88,19 @@ const verboseBanner_1 = __nccwpck_require__(5472);
|
|
|
16
88
|
const writeDotEnvFiles_1 = __nccwpck_require__(5614);
|
|
17
89
|
const writeEnvDTs_1 = __nccwpck_require__(8832);
|
|
18
90
|
const pipeline_1 = __nccwpck_require__(241);
|
|
91
|
+
const nonInteractive_1 = __nccwpck_require__(1917);
|
|
19
92
|
exports["default"] = async (choice, options) => {
|
|
20
93
|
const config = await (0, getProjectConfig_1.getProjectConfig)();
|
|
21
94
|
if (!config) {
|
|
22
95
|
return;
|
|
23
96
|
}
|
|
24
|
-
const
|
|
97
|
+
const io = (0, nonInteractive_1.createNonInteractiveIO)({
|
|
98
|
+
vaultMode: options === null || options === void 0 ? void 0 : options.vaultMode
|
|
99
|
+
});
|
|
100
|
+
const context = {
|
|
101
|
+
...(0, pipeline_1.createCatenvContext)(config),
|
|
102
|
+
io
|
|
103
|
+
};
|
|
25
104
|
if (options === null || options === void 0 ? void 0 : options.verbose) {
|
|
26
105
|
(0, verboseBanner_1.printVerboseBanner)();
|
|
27
106
|
}
|
|
@@ -42,19 +121,19 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
42
121
|
exports.printVariables = void 0;
|
|
43
122
|
const getProjectConfig_1 = __nccwpck_require__(1);
|
|
44
123
|
const utils_1 = __nccwpck_require__(1909);
|
|
45
|
-
const getAllVariablesToPrint = async (config, choice) => {
|
|
124
|
+
const getAllVariablesToPrint = async (io, config, choice) => {
|
|
46
125
|
const {
|
|
47
126
|
env,
|
|
48
127
|
currentComponent
|
|
49
128
|
} = await (0, utils_1.getCurrentComponentAndEnvFromChoice)(config, choice);
|
|
50
129
|
if (currentComponent) {
|
|
51
|
-
return await (0, getProjectConfig_1.getEnvVarsResolved)(
|
|
130
|
+
return await (0, getProjectConfig_1.getEnvVarsResolved)(io, env, currentComponent);
|
|
52
131
|
} else {
|
|
53
132
|
// when in a monorep and not in a subapp, merge all env vars.
|
|
54
133
|
// this is not 100% correct, but better than not exporting any vars at all
|
|
55
134
|
// so we also add prefixed variants
|
|
56
135
|
return await Object.keys(config.components).reduce(async (acc, componentName) => {
|
|
57
|
-
const subappvars = await (0, getProjectConfig_1.getEnvVarsResolved)(
|
|
136
|
+
const subappvars = await (0, getProjectConfig_1.getEnvVarsResolved)(io, env, componentName);
|
|
58
137
|
delete subappvars["_ALL_ENV_VAR_KEYS"];
|
|
59
138
|
return {
|
|
60
139
|
...(await acc),
|
|
@@ -66,7 +145,7 @@ const getAllVariablesToPrint = async (config, choice) => {
|
|
|
66
145
|
}
|
|
67
146
|
};
|
|
68
147
|
const printVariables = async (context, choice) => {
|
|
69
|
-
const variables = await getAllVariablesToPrint(context.config, choice);
|
|
148
|
+
const variables = await getAllVariablesToPrint(context.io, context.config, choice);
|
|
70
149
|
console.log(makeExportKeyValuestring(variables));
|
|
71
150
|
};
|
|
72
151
|
exports.printVariables = printVariables;
|
|
@@ -185,7 +264,7 @@ const writeDotEnvFiles = async (context, choice) => {
|
|
|
185
264
|
const componentsToActuallyWriteDotEnvNow = currentComponent ? componentsWithEnabledDotEnvWrite.includes(currentComponent) ? [currentComponent] : [] : componentsWithEnabledDotEnvWrite;
|
|
186
265
|
const gitRoot = await (0, projects_1.getGitRoot)();
|
|
187
266
|
for (const componentName of componentsToActuallyWriteDotEnvNow) {
|
|
188
|
-
const variables = await (0, getProjectConfig_1.getEnvVarsResolved)(
|
|
267
|
+
const variables = await (0, getProjectConfig_1.getEnvVarsResolved)(context.io, env, componentName);
|
|
189
268
|
delete variables["_ALL_ENV_VAR_KEYS"];
|
|
190
269
|
const componentDir = (0, utils_1.getComponentFullPath)(gitRoot, context.config, componentName);
|
|
191
270
|
const filePath = (0, path_1.join)(componentDir, ".env");
|
|
@@ -279,11 +358,12 @@ const catenv_1 = __importDefault(__nccwpck_require__(6057));
|
|
|
279
358
|
const parseChoice_1 = __nccwpck_require__(4272);
|
|
280
359
|
const packageInfos_1 = __importDefault(__nccwpck_require__(3568));
|
|
281
360
|
const program = new commander_1.Command();
|
|
282
|
-
program.name("catenv").description("Environment variable and pipeline generation via direnv").version(packageInfos_1.default.version).argument("[envComponent]", "env or env:component").option("-v, --verbose", "verbose output").option("-p, --print-variables", "print variables").action((envComponent, opts) => {
|
|
361
|
+
program.name("catenv").description("Environment variable and pipeline generation via direnv").version(packageInfos_1.default.version).argument("[envComponent]", "env or env:component").option("-v, --verbose", "verbose output").option("-p, --print-variables", "print variables").addOption(new commander_1.Option("--vault-mode <mode>", ["how to interact with the secrets vault:", "auto: contact the vault when cached secrets are missing (may prompt to unlock)", "no-prompt: like auto, but fail instead of prompting", "offline: never contact the vault, use only locally cached secrets", "refresh: ignore the local cache once and refresh it from the vault"].join("\n")).choices(["auto", "no-prompt", "offline", "refresh"]).default("auto")).action((envComponent, opts) => {
|
|
283
362
|
var _a, _b;
|
|
284
363
|
(0, catenv_1.default)(envComponent ? (0, parseChoice_1.parseChoice)(envComponent) : null, {
|
|
285
364
|
verbose: (_a = opts.verbose) !== null && _a !== void 0 ? _a : false,
|
|
286
|
-
printVariables: (_b = opts.printVariables) !== null && _b !== void 0 ? _b : false
|
|
365
|
+
printVariables: (_b = opts.printVariables) !== null && _b !== void 0 ? _b : false,
|
|
366
|
+
vaultMode: opts.vaultMode
|
|
287
367
|
}).then(() => {
|
|
288
368
|
// we have to exit manually, because we have some file watches
|
|
289
369
|
process.exit();
|
|
@@ -403,14 +483,24 @@ const getGitlabVar = async (io, env, componentName, variableName) => {
|
|
|
403
483
|
};
|
|
404
484
|
exports.getGitlabVar = getGitlabVar;
|
|
405
485
|
const resolveSecrets = async (io, varSets) => {
|
|
406
|
-
|
|
486
|
+
// the secret variables actually referenced by the env var values —
|
|
487
|
+
// when they are all in the local cache, the vault is not contacted
|
|
488
|
+
const referencedNames = [...new Set(varSets.flatMap(({
|
|
489
|
+
envVars
|
|
490
|
+
}) => Object.values(envVars).flatMap(value => {
|
|
491
|
+
var _a;
|
|
492
|
+
return (_a = `${value}`.match(/\$CL_\w+/g)) !== null && _a !== void 0 ? _a : [];
|
|
493
|
+
})))].map(reference => reference.slice(1));
|
|
494
|
+
const vaultManager = await io.getVaultManager();
|
|
495
|
+
const secrets = await vaultManager.readSecrets(referencedNames, io);
|
|
496
|
+
const secretEntries = Object.entries(secrets);
|
|
407
497
|
return Object.fromEntries(varSets.flatMap(({
|
|
408
498
|
envVars,
|
|
409
499
|
secretEnvVarKeys
|
|
410
500
|
}) => Object.entries(envVars).filter(([key, value]) => {
|
|
411
501
|
var _a;
|
|
412
502
|
return value !== undefined && value !== null && !((_a = secretEnvVarKeys.find(k => k.key === key)) === null || _a === void 0 ? void 0 : _a.hidden);
|
|
413
|
-
}).map(([key, value]) => [key,
|
|
503
|
+
}).map(([key, value]) => [key, secretEntries.reduce((acc, [name, secretValue]) => acc.replace(new RegExp("\\$" + name, "g"), secretValue), `${value}`)])));
|
|
414
504
|
};
|
|
415
505
|
const getEnvVarsResolved = async (io, env, componentName) => {
|
|
416
506
|
if (!componentName) {
|
|
@@ -464,6 +554,36 @@ exports.parseChoice = parseChoice;
|
|
|
464
554
|
|
|
465
555
|
/***/ }),
|
|
466
556
|
|
|
557
|
+
/***/ 2284:
|
|
558
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
559
|
+
|
|
560
|
+
"use strict";
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
564
|
+
value: true
|
|
565
|
+
}));
|
|
566
|
+
exports.MissingInputError = exports.NonInteractiveError = void 0;
|
|
567
|
+
// ─── Errors ──────────────────────────────────────────────────────────
|
|
568
|
+
class NonInteractiveError extends Error {
|
|
569
|
+
constructor(interaction) {
|
|
570
|
+
super(`${interaction} requires an interactive terminal, but this context is not interactive`);
|
|
571
|
+
this.name = "NonInteractiveError";
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
exports.NonInteractiveError = NonInteractiveError;
|
|
575
|
+
class MissingInputError extends Error {
|
|
576
|
+
constructor(inputName, promptMessage) {
|
|
577
|
+
super(`Missing required input: "${inputName}" (${promptMessage}). ` + `Provide it via --${inputName}=<value> or --inputs='{"${inputName}": ...}'`);
|
|
578
|
+
this.inputName = inputName;
|
|
579
|
+
this.promptMessage = promptMessage;
|
|
580
|
+
this.name = "MissingInputError";
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
exports.MissingInputError = MissingInputError;
|
|
584
|
+
|
|
585
|
+
/***/ }),
|
|
586
|
+
|
|
467
587
|
/***/ 6636:
|
|
468
588
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
469
589
|
|
|
@@ -518,14 +638,14 @@ exports.getProjectRootPath = getProjectRootPath;
|
|
|
518
638
|
/**
|
|
519
639
|
* Get the git remote hostname and project path from the git config.
|
|
520
640
|
*/
|
|
521
|
-
const getGitRemoteHostAndPath = async () => {
|
|
641
|
+
const getGitRemoteHostAndPath = async (remoteName = "origin") => {
|
|
522
642
|
var _a;
|
|
523
|
-
const remoteUrl = await (0, gitConfig_1.gitConfigGet)(
|
|
643
|
+
const remoteUrl = await (0, gitConfig_1.gitConfigGet)(`remote.${remoteName}.url`);
|
|
524
644
|
const remoteReg = /(https:\/\/|git@)([^:/]+)[:/]([^.]*)(\.git)?/;
|
|
525
645
|
const match = (_a = remoteUrl.match(remoteReg)) !== null && _a !== void 0 ? _a : [];
|
|
526
646
|
const [,, gitRemoteHost, gitRemotePath] = match;
|
|
527
647
|
if (!(gitRemoteHost === null || gitRemoteHost === void 0 ? void 0 : gitRemoteHost.length) || !(gitRemotePath === null || gitRemotePath === void 0 ? void 0 : gitRemotePath.length)) {
|
|
528
|
-
throw new Error(`Failed to parse git remote hostname and path from git configs remote.
|
|
648
|
+
throw new Error(`Failed to parse git remote hostname and path from git configs remote.${remoteName}.url! ${remoteUrl}`);
|
|
529
649
|
}
|
|
530
650
|
return {
|
|
531
651
|
gitRemoteHost,
|
|
@@ -947,6 +1067,445 @@ exports.getProjectNamespace = getProjectNamespace;
|
|
|
947
1067
|
|
|
948
1068
|
/***/ }),
|
|
949
1069
|
|
|
1070
|
+
/***/ 3510:
|
|
1071
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
1072
|
+
|
|
1073
|
+
"use strict";
|
|
1074
|
+
|
|
1075
|
+
|
|
1076
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
1077
|
+
value: true
|
|
1078
|
+
}));
|
|
1079
|
+
exports.BitwardenVault = void 0;
|
|
1080
|
+
const pipeline_1 = __nccwpck_require__(241);
|
|
1081
|
+
const yaml_1 = __nccwpck_require__(6637);
|
|
1082
|
+
const bw_1 = __nccwpck_require__(2211);
|
|
1083
|
+
const DEFAULT_COLLECTION = "catladder";
|
|
1084
|
+
const SECURE_NOTE_TYPE = 2;
|
|
1085
|
+
/**
|
|
1086
|
+
* one yaml note per env and component:
|
|
1087
|
+
* `<customerName>/<appName>/<env>/<componentName>/secrets.yml`
|
|
1088
|
+
*/
|
|
1089
|
+
const itemName = (config, env, componentName) => `${config.customerName}/${config.appName}/${env}/${componentName}/secrets.yml`;
|
|
1090
|
+
const itemPrefix = config => `${config.customerName}/${config.appName}/`;
|
|
1091
|
+
/**
|
|
1092
|
+
* parses env and componentName back out of an item name
|
|
1093
|
+
*/
|
|
1094
|
+
const parseItemName = (config, name) => {
|
|
1095
|
+
const match = name.slice(itemPrefix(config).length).match(/^([^/]+)\/([^/]+)\/secrets\.yml$/);
|
|
1096
|
+
return match ? {
|
|
1097
|
+
env: match[1],
|
|
1098
|
+
componentName: match[2]
|
|
1099
|
+
} : null;
|
|
1100
|
+
};
|
|
1101
|
+
const findCollection = async (session, collectionName) => {
|
|
1102
|
+
const collections = await (0, bw_1.runBwJson)(session, ["list", "collections", "--search", collectionName]);
|
|
1103
|
+
const collection = collections.find(c => c.name === collectionName);
|
|
1104
|
+
if (!collection) {
|
|
1105
|
+
throw new Error(`bitwarden collection '${collectionName}' not found — create it and make sure you have access`);
|
|
1106
|
+
}
|
|
1107
|
+
return collection;
|
|
1108
|
+
};
|
|
1109
|
+
const encodePayload = payload => Buffer.from(JSON.stringify(payload), "utf-8").toString("base64");
|
|
1110
|
+
class BitwardenVault {
|
|
1111
|
+
constructor(config, options,
|
|
1112
|
+
/**
|
|
1113
|
+
* whether a locked bitwarden may be unlocked interactively
|
|
1114
|
+
* (false with catenv --vault-mode no-prompt)
|
|
1115
|
+
*/
|
|
1116
|
+
allowPrompt) {
|
|
1117
|
+
var _a;
|
|
1118
|
+
this.config = config;
|
|
1119
|
+
this.allowPrompt = allowPrompt;
|
|
1120
|
+
this.collectionName = (_a = options.collection) !== null && _a !== void 0 ? _a : DEFAULT_COLLECTION;
|
|
1121
|
+
this.id = `bitwarden:${this.collectionName}`;
|
|
1122
|
+
}
|
|
1123
|
+
session(io) {
|
|
1124
|
+
return (0, bw_1.getBwSession)(io, {
|
|
1125
|
+
allowPrompt: this.allowPrompt
|
|
1126
|
+
});
|
|
1127
|
+
}
|
|
1128
|
+
async readAllSecrets(io) {
|
|
1129
|
+
const {
|
|
1130
|
+
config,
|
|
1131
|
+
collectionName
|
|
1132
|
+
} = this;
|
|
1133
|
+
const bwSession = await this.session(io);
|
|
1134
|
+
const collection = await findCollection(bwSession, collectionName);
|
|
1135
|
+
const items = await (0, bw_1.runBwJson)(bwSession, ["list", "items", "--collectionid", collection.id]);
|
|
1136
|
+
const secrets = {};
|
|
1137
|
+
for (const item of items) {
|
|
1138
|
+
const parsed = parseItemName(config, item.name);
|
|
1139
|
+
if (!parsed || !item.notes) {
|
|
1140
|
+
continue;
|
|
1141
|
+
}
|
|
1142
|
+
const values = (0, yaml_1.parse)(item.notes);
|
|
1143
|
+
Object.entries(values !== null && values !== void 0 ? values : {}).forEach(([key, value]) => {
|
|
1144
|
+
secrets[(0, pipeline_1.getSecretVarName)(parsed.env, parsed.componentName, key)] = typeof value === "string" ? value : JSON.stringify(value);
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
1147
|
+
return secrets;
|
|
1148
|
+
}
|
|
1149
|
+
async writeSecrets(io, env, componentName, secrets) {
|
|
1150
|
+
const {
|
|
1151
|
+
config,
|
|
1152
|
+
collectionName
|
|
1153
|
+
} = this;
|
|
1154
|
+
const bwSession = await this.session(io);
|
|
1155
|
+
const collection = await findCollection(bwSession, collectionName);
|
|
1156
|
+
const name = itemName(config, env, componentName);
|
|
1157
|
+
const existing = (await (0, bw_1.runBwJson)(bwSession, ["list", "items", "--collectionid", collection.id, "--search", name])).find(item => item.name === name);
|
|
1158
|
+
const notes = (0, yaml_1.stringify)(secrets);
|
|
1159
|
+
if (existing) {
|
|
1160
|
+
await (0, bw_1.runBw)(bwSession, ["edit", "item", existing.id, encodePayload({
|
|
1161
|
+
...existing,
|
|
1162
|
+
notes
|
|
1163
|
+
})]);
|
|
1164
|
+
} else {
|
|
1165
|
+
await (0, bw_1.runBw)(bwSession, ["create", "item", encodePayload({
|
|
1166
|
+
type: SECURE_NOTE_TYPE,
|
|
1167
|
+
secureNote: {
|
|
1168
|
+
type: 0
|
|
1169
|
+
},
|
|
1170
|
+
name,
|
|
1171
|
+
notes,
|
|
1172
|
+
...(collection.organizationId ? {
|
|
1173
|
+
organizationId: collection.organizationId,
|
|
1174
|
+
collectionIds: [collection.id]
|
|
1175
|
+
} : {})
|
|
1176
|
+
})]);
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
exports.BitwardenVault = BitwardenVault;
|
|
1181
|
+
|
|
1182
|
+
/***/ }),
|
|
1183
|
+
|
|
1184
|
+
/***/ 1107:
|
|
1185
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
1186
|
+
|
|
1187
|
+
"use strict";
|
|
1188
|
+
|
|
1189
|
+
|
|
1190
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
1191
|
+
value: true
|
|
1192
|
+
}));
|
|
1193
|
+
exports.GitlabVault = void 0;
|
|
1194
|
+
const gitlab_1 = __nccwpck_require__(4508);
|
|
1195
|
+
/**
|
|
1196
|
+
* the legacy (and default) vault: the gitlab project variables double
|
|
1197
|
+
* as the secret store
|
|
1198
|
+
*/
|
|
1199
|
+
class GitlabVault {
|
|
1200
|
+
constructor() {
|
|
1201
|
+
this.id = "gitlab";
|
|
1202
|
+
}
|
|
1203
|
+
async readAllSecrets(io) {
|
|
1204
|
+
const variables = await (0, gitlab_1.getAllVariables)(io);
|
|
1205
|
+
return Object.fromEntries(variables.map(v => [v.key, v.value]));
|
|
1206
|
+
}
|
|
1207
|
+
async writeSecrets(io, env, componentName, secrets) {
|
|
1208
|
+
await (0, gitlab_1.upsertAllVariables)(io, secrets, env, componentName);
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
exports.GitlabVault = GitlabVault;
|
|
1212
|
+
|
|
1213
|
+
/***/ }),
|
|
1214
|
+
|
|
1215
|
+
/***/ 5771:
|
|
1216
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
1217
|
+
|
|
1218
|
+
"use strict";
|
|
1219
|
+
|
|
1220
|
+
|
|
1221
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
1222
|
+
value: true
|
|
1223
|
+
}));
|
|
1224
|
+
exports.VaultManager = void 0;
|
|
1225
|
+
const pipeline_1 = __nccwpck_require__(241);
|
|
1226
|
+
const BitwardenVault_1 = __nccwpck_require__(3510);
|
|
1227
|
+
const cache_1 = __nccwpck_require__(4236);
|
|
1228
|
+
const GitlabVault_1 = __nccwpck_require__(1107);
|
|
1229
|
+
/**
|
|
1230
|
+
* only secrets of this env are cached locally — the other envs'
|
|
1231
|
+
* secrets have no business sitting on developer machines
|
|
1232
|
+
*/
|
|
1233
|
+
const CACHED_ENV = "local";
|
|
1234
|
+
/**
|
|
1235
|
+
* owns the configured vault, the secrets mode and the local cache.
|
|
1236
|
+
* The vault is the readable source of truth for secrets; CI backends
|
|
1237
|
+
* only receive mirrored copies.
|
|
1238
|
+
*/
|
|
1239
|
+
class VaultManager {
|
|
1240
|
+
constructor(config, options = {}) {
|
|
1241
|
+
var _a, _b;
|
|
1242
|
+
this.config = config;
|
|
1243
|
+
/** refresh mode bypasses the cache only once per manager */
|
|
1244
|
+
this.refreshed = false;
|
|
1245
|
+
this.mode = (_a = options.mode) !== null && _a !== void 0 ? _a : "auto";
|
|
1246
|
+
this.io = (_b = options.io) !== null && _b !== void 0 ? _b : null;
|
|
1247
|
+
this.vault = this.createVault();
|
|
1248
|
+
}
|
|
1249
|
+
createVault() {
|
|
1250
|
+
const vaultConfig = (0, pipeline_1.getVaultConfig)(this.config);
|
|
1251
|
+
switch (vaultConfig.type) {
|
|
1252
|
+
case "gitlab":
|
|
1253
|
+
return new GitlabVault_1.GitlabVault();
|
|
1254
|
+
case "bitwarden":
|
|
1255
|
+
return new BitwardenVault_1.BitwardenVault(this.config, vaultConfig, this.mode === "auto" || this.mode === "refresh");
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
/**
|
|
1259
|
+
* the vault secrets, served from the local cache when it contains
|
|
1260
|
+
* all required names; otherwise (depending on the mode) refreshed
|
|
1261
|
+
* from the vault. Only the "local" env is (re-)cached.
|
|
1262
|
+
*/
|
|
1263
|
+
async readSecrets(requiredNames, io = this.io) {
|
|
1264
|
+
const bypassCache = this.mode === "refresh" && !this.refreshed;
|
|
1265
|
+
const cache = bypassCache ? null : await (0, cache_1.readSecretsCache)();
|
|
1266
|
+
// known entries include recorded misses (null values), so declared
|
|
1267
|
+
// but intentionally unset secrets don't force a vault refresh
|
|
1268
|
+
const known = (cache === null || cache === void 0 ? void 0 : cache.vaultId) === this.vault.id ? flattenSecrets(cache.secrets) : undefined;
|
|
1269
|
+
const missing = requiredNames.filter(name => !(name in (known !== null && known !== void 0 ? known : {})));
|
|
1270
|
+
// nothing missing (or nothing required at all): don't touch the vault
|
|
1271
|
+
if (missing.length === 0 && (known || requiredNames.length === 0)) {
|
|
1272
|
+
return withoutMisses(known !== null && known !== void 0 ? known : {});
|
|
1273
|
+
}
|
|
1274
|
+
if (this.mode === "offline") {
|
|
1275
|
+
if (missing.length > 0) {
|
|
1276
|
+
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(", ")}`);
|
|
1277
|
+
}
|
|
1278
|
+
return withoutMisses(known !== null && known !== void 0 ? known : {});
|
|
1279
|
+
}
|
|
1280
|
+
const secrets = await this.vault.readAllSecrets(io);
|
|
1281
|
+
this.refreshed = true;
|
|
1282
|
+
await (0, cache_1.writeSecretsCache)(this.vault.id, await this.cacheableSubset(secrets));
|
|
1283
|
+
return secrets;
|
|
1284
|
+
}
|
|
1285
|
+
/**
|
|
1286
|
+
* writes secrets of one env/component to the vault and updates the
|
|
1287
|
+
* local cache (write-through, "local" env only)
|
|
1288
|
+
*/
|
|
1289
|
+
async writeSecrets(env, componentName, secrets, io = this.io) {
|
|
1290
|
+
if (!io) {
|
|
1291
|
+
throw new Error("writing to the vault requires an interactive context");
|
|
1292
|
+
}
|
|
1293
|
+
await this.vault.writeSecrets(io, env, componentName, secrets);
|
|
1294
|
+
if (env === CACHED_ENV) {
|
|
1295
|
+
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)])));
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
/**
|
|
1299
|
+
* the subset of the vault secrets that may be cached: the declared
|
|
1300
|
+
* secrets of the "local" env, per component, as a hierarchy
|
|
1301
|
+
*/
|
|
1302
|
+
async cacheableSubset(flatSecrets) {
|
|
1303
|
+
const local = {};
|
|
1304
|
+
for (const componentName of Object.keys(this.config.components)) {
|
|
1305
|
+
const keys = await this.declaredSecretKeys(componentName);
|
|
1306
|
+
const values = Object.fromEntries(keys.map(key => {
|
|
1307
|
+
var _a;
|
|
1308
|
+
return [key,
|
|
1309
|
+
// null records "absent in the vault" (a known miss)
|
|
1310
|
+
(_a = flatSecrets[(0, pipeline_1.getSecretVarName)(CACHED_ENV, componentName, key)]) !== null && _a !== void 0 ? _a : null];
|
|
1311
|
+
}));
|
|
1312
|
+
if (Object.keys(values).length > 0) {
|
|
1313
|
+
local[componentName] = values;
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
return Object.keys(local).length > 0 ? {
|
|
1317
|
+
[CACHED_ENV]: local
|
|
1318
|
+
} : {};
|
|
1319
|
+
}
|
|
1320
|
+
async declaredSecretKeys(componentName) {
|
|
1321
|
+
try {
|
|
1322
|
+
const {
|
|
1323
|
+
secretEnvVarKeys,
|
|
1324
|
+
jobOnlyVars
|
|
1325
|
+
} = await (0, pipeline_1.getEnvironment)({
|
|
1326
|
+
config: this.config,
|
|
1327
|
+
componentName,
|
|
1328
|
+
env: CACHED_ENV
|
|
1329
|
+
});
|
|
1330
|
+
return [...secretEnvVarKeys, ...jobOnlyVars.build.secretEnvVarKeys, ...jobOnlyVars.deploy.secretEnvVarKeys].map(({
|
|
1331
|
+
key
|
|
1332
|
+
}) => key);
|
|
1333
|
+
} catch (_a) {
|
|
1334
|
+
// components without a local env simply have nothing to cache
|
|
1335
|
+
return [];
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
exports.VaultManager = VaultManager;
|
|
1340
|
+
/**
|
|
1341
|
+
* the cache hierarchy as a flat map of raw secret variable names
|
|
1342
|
+
* (null values = recorded misses)
|
|
1343
|
+
*/
|
|
1344
|
+
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]))));
|
|
1345
|
+
/**
|
|
1346
|
+
* only actual values — recorded misses stay unresolved, like any other
|
|
1347
|
+
* unset variable
|
|
1348
|
+
*/
|
|
1349
|
+
const withoutMisses = known => Object.fromEntries(Object.entries(known).filter(entry => entry[1] !== null));
|
|
1350
|
+
|
|
1351
|
+
/***/ }),
|
|
1352
|
+
|
|
1353
|
+
/***/ 2211:
|
|
1354
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
1355
|
+
|
|
1356
|
+
"use strict";
|
|
1357
|
+
|
|
1358
|
+
|
|
1359
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
1360
|
+
value: true
|
|
1361
|
+
}));
|
|
1362
|
+
exports.runBwJson = exports.runBw = exports.getBwSession = void 0;
|
|
1363
|
+
const child_process_1 = __nccwpck_require__(5317);
|
|
1364
|
+
const util_1 = __nccwpck_require__(9023);
|
|
1365
|
+
const preferences_1 = __nccwpck_require__(6261);
|
|
1366
|
+
const execFile = (0, util_1.promisify)(child_process_1.execFile);
|
|
1367
|
+
const SESSION_PREFERENCE = "bwsession";
|
|
1368
|
+
class BitwardenLockedError extends Error {
|
|
1369
|
+
constructor() {
|
|
1370
|
+
super("bitwarden is locked and prompting is disabled — run `bw unlock` or catenv without --vault-mode no-prompt");
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
/**
|
|
1374
|
+
* runs an interactive bw command that prints a session key on stdout
|
|
1375
|
+
* (login/unlock) while the user types the password on the terminal
|
|
1376
|
+
*/
|
|
1377
|
+
const interactiveSessionCommand = args => new Promise((resolve, reject) => {
|
|
1378
|
+
var _a;
|
|
1379
|
+
const child = (0, child_process_1.spawn)("bw", [...args, "--raw"], {
|
|
1380
|
+
stdio: ["inherit", "pipe", "inherit"]
|
|
1381
|
+
});
|
|
1382
|
+
let session = "";
|
|
1383
|
+
(_a = child.stdout) === null || _a === void 0 ? void 0 : _a.on("data", data => session += data.toString("utf-8"));
|
|
1384
|
+
child.on("error", reject);
|
|
1385
|
+
child.on("close", code => code === 0 && session.trim() ? resolve(session.trim()) : reject(new Error(`bw ${args[0]} failed`)));
|
|
1386
|
+
});
|
|
1387
|
+
const getBwStatus = async session => {
|
|
1388
|
+
try {
|
|
1389
|
+
const {
|
|
1390
|
+
stdout
|
|
1391
|
+
} = await execFile("bw", ["status"], {
|
|
1392
|
+
env: {
|
|
1393
|
+
...process.env,
|
|
1394
|
+
...(session ? {
|
|
1395
|
+
BW_SESSION: session
|
|
1396
|
+
} : {})
|
|
1397
|
+
}
|
|
1398
|
+
});
|
|
1399
|
+
return JSON.parse(stdout).status;
|
|
1400
|
+
} catch (_a) {
|
|
1401
|
+
return "unauthenticated";
|
|
1402
|
+
}
|
|
1403
|
+
};
|
|
1404
|
+
/**
|
|
1405
|
+
* a working bw session: reuses the cached one, otherwise unlocks (or
|
|
1406
|
+
* logs in) interactively — unless prompting is disabled
|
|
1407
|
+
*/
|
|
1408
|
+
const getBwSession = async (io, {
|
|
1409
|
+
allowPrompt
|
|
1410
|
+
}) => {
|
|
1411
|
+
const cached = (await (0, preferences_1.hasPreference)(SESSION_PREFERENCE)) ? String(await (0, preferences_1.getPreference)(SESSION_PREFERENCE)) : null;
|
|
1412
|
+
const status = await getBwStatus(cached);
|
|
1413
|
+
if (status === "unlocked" && cached) {
|
|
1414
|
+
return cached;
|
|
1415
|
+
}
|
|
1416
|
+
if (!allowPrompt) {
|
|
1417
|
+
throw new BitwardenLockedError();
|
|
1418
|
+
}
|
|
1419
|
+
io === null || io === void 0 ? void 0 : io.log("");
|
|
1420
|
+
io === null || io === void 0 ? void 0 : io.log(status === "unauthenticated" ? "# Please login to Bitwarden:" : "# Bitwarden is locked, please unlock:");
|
|
1421
|
+
io === null || io === void 0 ? void 0 : io.log("");
|
|
1422
|
+
const session = await interactiveSessionCommand([status === "unauthenticated" ? "login" : "unlock"]);
|
|
1423
|
+
await (0, preferences_1.setPreference)(SESSION_PREFERENCE, session);
|
|
1424
|
+
await (0, exports.runBw)(session, ["sync"]);
|
|
1425
|
+
return session;
|
|
1426
|
+
};
|
|
1427
|
+
exports.getBwSession = getBwSession;
|
|
1428
|
+
/**
|
|
1429
|
+
* runs a bw command with the given session and returns stdout
|
|
1430
|
+
*/
|
|
1431
|
+
const runBw = async (session, args) => {
|
|
1432
|
+
const {
|
|
1433
|
+
stdout
|
|
1434
|
+
} = await execFile("bw", [...args, "--raw", "--nointeraction"], {
|
|
1435
|
+
env: {
|
|
1436
|
+
...process.env,
|
|
1437
|
+
BW_SESSION: session
|
|
1438
|
+
},
|
|
1439
|
+
maxBuffer: 50 * 1024 * 1024
|
|
1440
|
+
});
|
|
1441
|
+
return stdout;
|
|
1442
|
+
};
|
|
1443
|
+
exports.runBw = runBw;
|
|
1444
|
+
const runBwJson = async (session, args) => JSON.parse(await (0, exports.runBw)(session, args));
|
|
1445
|
+
exports.runBwJson = runBwJson;
|
|
1446
|
+
|
|
1447
|
+
/***/ }),
|
|
1448
|
+
|
|
1449
|
+
/***/ 4236:
|
|
1450
|
+
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
1451
|
+
|
|
1452
|
+
"use strict";
|
|
1453
|
+
|
|
1454
|
+
|
|
1455
|
+
Object.defineProperty(exports, "__esModule", ({
|
|
1456
|
+
value: true
|
|
1457
|
+
}));
|
|
1458
|
+
exports.updateSecretsCache = exports.writeSecretsCache = exports.readSecretsCache = void 0;
|
|
1459
|
+
const promises_1 = __nccwpck_require__(1943);
|
|
1460
|
+
const path_1 = __nccwpck_require__(6928);
|
|
1461
|
+
const gitProjectInformation_1 = __nccwpck_require__(1111);
|
|
1462
|
+
const getCacheFolder = async () => (0, path_1.join)(await (0, gitProjectInformation_1.getProjectRootPath)(), ".catladder");
|
|
1463
|
+
const getCachePath = async () => (0, path_1.join)(await getCacheFolder(), "secrets.json");
|
|
1464
|
+
const readSecretsCache = async () => {
|
|
1465
|
+
try {
|
|
1466
|
+
return JSON.parse(await (0, promises_1.readFile)(await getCachePath(), "utf-8"));
|
|
1467
|
+
} catch (_a) {
|
|
1468
|
+
return null;
|
|
1469
|
+
}
|
|
1470
|
+
};
|
|
1471
|
+
exports.readSecretsCache = readSecretsCache;
|
|
1472
|
+
const writeSecretsCache = async (vaultId, secrets) => {
|
|
1473
|
+
const folder = await getCacheFolder();
|
|
1474
|
+
await (0, promises_1.mkdir)(folder, {
|
|
1475
|
+
recursive: true
|
|
1476
|
+
});
|
|
1477
|
+
// the folder ignores itself, so the cache can never be committed
|
|
1478
|
+
await (0, promises_1.writeFile)((0, path_1.join)(folder, ".gitignore"), "*\n");
|
|
1479
|
+
const cache = {
|
|
1480
|
+
vaultId,
|
|
1481
|
+
updatedAt: new Date().toISOString(),
|
|
1482
|
+
secrets
|
|
1483
|
+
};
|
|
1484
|
+
await (0, promises_1.writeFile)(await getCachePath(), JSON.stringify(cache, null, 2));
|
|
1485
|
+
};
|
|
1486
|
+
exports.writeSecretsCache = writeSecretsCache;
|
|
1487
|
+
/**
|
|
1488
|
+
* merges freshly written secrets of one env/component into the cache
|
|
1489
|
+
* (write-through from config-secrets), so the next catenv run doesn't
|
|
1490
|
+
* need the vault
|
|
1491
|
+
*/
|
|
1492
|
+
const updateSecretsCache = async (vaultId, env, componentName, values) => {
|
|
1493
|
+
var _a;
|
|
1494
|
+
const existing = await (0, exports.readSecretsCache)();
|
|
1495
|
+
const secrets = (existing === null || existing === void 0 ? void 0 : existing.vaultId) === vaultId ? existing.secrets : {};
|
|
1496
|
+
secrets[env] = {
|
|
1497
|
+
...secrets[env],
|
|
1498
|
+
[componentName]: {
|
|
1499
|
+
...((_a = secrets[env]) === null || _a === void 0 ? void 0 : _a[componentName]),
|
|
1500
|
+
...values
|
|
1501
|
+
}
|
|
1502
|
+
};
|
|
1503
|
+
await (0, exports.writeSecretsCache)(vaultId, secrets);
|
|
1504
|
+
};
|
|
1505
|
+
exports.updateSecretsCache = updateSecretsCache;
|
|
1506
|
+
|
|
1507
|
+
/***/ }),
|
|
1508
|
+
|
|
950
1509
|
/***/ 4038:
|
|
951
1510
|
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
|
|
952
1511
|
|
|
@@ -2265,7 +2824,7 @@ var __exportStar = this && this.__exportStar || function (m, exports) {
|
|
|
2265
2824
|
Object.defineProperty(exports, "__esModule", ({
|
|
2266
2825
|
value: true
|
|
2267
2826
|
}));
|
|
2268
|
-
exports.getEnabledPipelineTypes = exports.getPipelineBackend = void 0;
|
|
2827
|
+
exports.getEnabledPipelineTypes = exports.getVaultConfig = exports.getPipelineGitRemote = exports.getPipelineOptions = exports.getPipelineBackend = void 0;
|
|
2269
2828
|
const github_1 = __nccwpck_require__(9635);
|
|
2270
2829
|
const gitlab_1 = __nccwpck_require__(8475);
|
|
2271
2830
|
__exportStar(__nccwpck_require__(2474), exports);
|
|
@@ -2283,6 +2842,38 @@ const getPipelineBackend = type => {
|
|
|
2283
2842
|
return createBackend();
|
|
2284
2843
|
};
|
|
2285
2844
|
exports.getPipelineBackend = getPipelineBackend;
|
|
2845
|
+
/**
|
|
2846
|
+
* the options of an enabled pipeline type (empty object when enabled
|
|
2847
|
+
* with `true`)
|
|
2848
|
+
*/
|
|
2849
|
+
const getPipelineOptions = (config, type) => {
|
|
2850
|
+
var _a;
|
|
2851
|
+
const value = (_a = config.pipelines) === null || _a === void 0 ? void 0 : _a[type];
|
|
2852
|
+
return typeof value === "object" ? value : {};
|
|
2853
|
+
};
|
|
2854
|
+
exports.getPipelineOptions = getPipelineOptions;
|
|
2855
|
+
/**
|
|
2856
|
+
* the git remote pointing to the repository of this pipeline type's CI
|
|
2857
|
+
* system (e.g. during a migration, gitlab may be `origin` and github a
|
|
2858
|
+
* second remote)
|
|
2859
|
+
*/
|
|
2860
|
+
const getPipelineGitRemote = (config, type) => {
|
|
2861
|
+
var _a;
|
|
2862
|
+
return (_a = (0, exports.getPipelineOptions)(config, type).gitRemote) !== null && _a !== void 0 ? _a : "origin";
|
|
2863
|
+
};
|
|
2864
|
+
exports.getPipelineGitRemote = getPipelineGitRemote;
|
|
2865
|
+
/**
|
|
2866
|
+
* the normalized secrets vault of a config (string shorthands resolved
|
|
2867
|
+
* to their object form; defaults to the legacy gitlab store)
|
|
2868
|
+
*/
|
|
2869
|
+
const getVaultConfig = config => {
|
|
2870
|
+
var _a, _b;
|
|
2871
|
+
const vault = (_b = (_a = config.secrets) === null || _a === void 0 ? void 0 : _a.vault) !== null && _b !== void 0 ? _b : "gitlab";
|
|
2872
|
+
return typeof vault === "string" ? {
|
|
2873
|
+
type: vault
|
|
2874
|
+
} : vault;
|
|
2875
|
+
};
|
|
2876
|
+
exports.getVaultConfig = getVaultConfig;
|
|
2286
2877
|
/**
|
|
2287
2878
|
* the pipeline types enabled for this config. Multiple types can be
|
|
2288
2879
|
* enabled at once (parallel generation, e.g. during a CI migration).
|
|
@@ -4249,7 +4840,7 @@ Object.defineProperty(exports, "__esModule", ({
|
|
|
4249
4840
|
value: true
|
|
4250
4841
|
}));
|
|
4251
4842
|
exports.DOCKER_REGISTRY = exports.PIPELINE_IMAGE_TAG = void 0;
|
|
4252
|
-
exports.PIPELINE_IMAGE_TAG = "next-
|
|
4843
|
+
exports.PIPELINE_IMAGE_TAG = "next-8b9ad5ca" || 0;
|
|
4253
4844
|
exports.DOCKER_REGISTRY = "git.panter.ch:5001/catladder/catladder" || 0;
|
|
4254
4845
|
|
|
4255
4846
|
/***/ }),
|
|
@@ -6154,13 +6745,15 @@ exports.GCLOUD_RUN_DEPLOY_TYPE = {
|
|
|
6154
6745
|
}
|
|
6155
6746
|
return {};
|
|
6156
6747
|
},
|
|
6157
|
-
additionalSecretKeys: ctx => [
|
|
6748
|
+
additionalSecretKeys: ctx => [
|
|
6749
|
+
// deploy-time credentials don't exist for the local env
|
|
6750
|
+
...(ctx.envType !== "local" ? [{
|
|
6158
6751
|
key: exports.GCLOUD_DEPLOY_CREDENTIALS_KEY,
|
|
6159
6752
|
hidden: true
|
|
6160
6753
|
}, {
|
|
6161
6754
|
key: exports.GCLOUD_RUN_CANONICAL_HOST_SUFFIX,
|
|
6162
6755
|
hidden: true
|
|
6163
|
-
}, ...(ctx.deployConfigRaw && ctx.deployConfigRaw.cloudSql ? [{
|
|
6756
|
+
}] : []), ...(ctx.deployConfigRaw && ctx.deployConfigRaw.cloudSql ? [{
|
|
6164
6757
|
key: "DB_PASSWORD"
|
|
6165
6758
|
}] : [])],
|
|
6166
6759
|
getAdditionalEnvVars: ctx => {
|
|
@@ -6168,7 +6761,8 @@ exports.GCLOUD_RUN_DEPLOY_TYPE = {
|
|
|
6168
6761
|
fullName,
|
|
6169
6762
|
env,
|
|
6170
6763
|
componentName,
|
|
6171
|
-
deployConfigRaw
|
|
6764
|
+
deployConfigRaw,
|
|
6765
|
+
envType
|
|
6172
6766
|
} = ctx;
|
|
6173
6767
|
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();
|
|
6174
6768
|
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, {
|
|
@@ -6177,7 +6771,11 @@ exports.GCLOUD_RUN_DEPLOY_TYPE = {
|
|
|
6177
6771
|
region: deployConfigRaw.region
|
|
6178
6772
|
})])) : {};
|
|
6179
6773
|
return {
|
|
6180
|
-
|
|
6774
|
+
// references the canonical host suffix secret, which doesn't
|
|
6775
|
+
// exist for the local env
|
|
6776
|
+
...(envType !== "local" ? {
|
|
6777
|
+
HOSTNAME_INTERNAL
|
|
6778
|
+
} : {}),
|
|
6181
6779
|
...getCloudSqlVariables(ctx),
|
|
6182
6780
|
...jobTriggers,
|
|
6183
6781
|
DEPLOY_CLOUD_RUN_SERVICE_NAME: (0, getServiceName_1.getServiceNameForEnvContext)(ctx),
|