@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
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { IO } from "../../core/types";
|
|
2
|
+
/**
|
|
3
|
+
* all secrets declared in the config, with their values read from the
|
|
4
|
+
* vault (github secrets are write-only and can never act as a source)
|
|
5
|
+
*/
|
|
6
|
+
export declare const collectSecretsFromVault: (io: IO) => Promise<{
|
|
7
|
+
secrets: {
|
|
8
|
+
name: string;
|
|
9
|
+
value: string;
|
|
10
|
+
}[];
|
|
11
|
+
missing: string[];
|
|
12
|
+
}>;
|
|
13
|
+
/**
|
|
14
|
+
* pushes secrets to github repository secrets via the gh cli
|
|
15
|
+
*/
|
|
16
|
+
export declare const pushSecretsToGithub: (io: IO, repo: string, secrets: {
|
|
17
|
+
name: string;
|
|
18
|
+
value: string;
|
|
19
|
+
}[]) => Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* resolves the github repository from the configured git remote
|
|
22
|
+
* (`pipelines.github.gitRemote`, defaults to origin)
|
|
23
|
+
*/
|
|
24
|
+
export declare const getConfiguredGithubRepo: () => Promise<string | undefined>;
|
|
25
|
+
/**
|
|
26
|
+
* copies the catladder secrets from the vault to github actions
|
|
27
|
+
* repository secrets, keeping the exact same names, so the github
|
|
28
|
+
* pipeline can reference them as ${{ secrets.<NAME> }}.
|
|
29
|
+
*/
|
|
30
|
+
export declare const commandSecretsSyncGithub: import("../../core/types").CommandDef<{
|
|
31
|
+
readonly repo: {
|
|
32
|
+
readonly type: "string";
|
|
33
|
+
readonly message: "github repository (owner/name)";
|
|
34
|
+
readonly positional: true;
|
|
35
|
+
readonly required: false;
|
|
36
|
+
};
|
|
37
|
+
}>;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.commandSecretsSyncGithub = exports.getConfiguredGithubRepo = exports.pushSecretsToGithub = exports.collectSecretsFromVault = void 0;
|
|
7
|
+
const pipeline_1 = require("../../../../pipeline/src/index.js");
|
|
8
|
+
const getProjectConfig_1 = require("../../config/getProjectConfig");
|
|
9
|
+
const defineCommand_1 = require("../../core/defineCommand");
|
|
10
|
+
const github_1 = require("../../utils/github");
|
|
11
|
+
/**
|
|
12
|
+
* all secrets declared in the config, with their values read from the
|
|
13
|
+
* vault (github secrets are write-only and can never act as a source)
|
|
14
|
+
*/
|
|
15
|
+
const collectSecretsFromVault = async io => {
|
|
16
|
+
const envAndComponents = await (0, getProjectConfig_1.getAllComponentsWithAllEnvsHierarchical)();
|
|
17
|
+
const names = [];
|
|
18
|
+
for (const [componentName, envs] of Object.entries(envAndComponents)) {
|
|
19
|
+
for (const env of envs) {
|
|
20
|
+
const {
|
|
21
|
+
secretEnvVarKeys,
|
|
22
|
+
jobOnlyVars
|
|
23
|
+
} = await (0, getProjectConfig_1.getEnvironment)(env, componentName);
|
|
24
|
+
const keys = [...secretEnvVarKeys, ...jobOnlyVars.build.secretEnvVarKeys, ...jobOnlyVars.deploy.secretEnvVarKeys];
|
|
25
|
+
keys.forEach(({
|
|
26
|
+
key
|
|
27
|
+
}) => names.push((0, pipeline_1.getSecretVarName)(env, componentName, key)));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const values = await (await io.getVaultManager()).readSecrets(names, io);
|
|
31
|
+
const secrets = names.filter(name => values[name] !== undefined).map(name => ({
|
|
32
|
+
name,
|
|
33
|
+
value: values[name]
|
|
34
|
+
}));
|
|
35
|
+
const missing = names.filter(name => values[name] === undefined);
|
|
36
|
+
return {
|
|
37
|
+
secrets,
|
|
38
|
+
missing
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
exports.collectSecretsFromVault = collectSecretsFromVault;
|
|
42
|
+
/**
|
|
43
|
+
* pushes secrets to github repository secrets via the gh cli
|
|
44
|
+
*/
|
|
45
|
+
const pushSecretsToGithub = async (io, repo, secrets) => {
|
|
46
|
+
for (const {
|
|
47
|
+
name,
|
|
48
|
+
value
|
|
49
|
+
} of secrets) {
|
|
50
|
+
await (0, github_1.setGithubSecret)(repo, name, value);
|
|
51
|
+
io.log(`✅ ${name}`);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
exports.pushSecretsToGithub = pushSecretsToGithub;
|
|
55
|
+
/**
|
|
56
|
+
* resolves the github repository from the configured git remote
|
|
57
|
+
* (`pipelines.github.gitRemote`, defaults to origin)
|
|
58
|
+
*/
|
|
59
|
+
const getConfiguredGithubRepo = async () => {
|
|
60
|
+
const config = await (0, getProjectConfig_1.getProjectConfig)();
|
|
61
|
+
if (!config) {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
return (0, github_1.getGithubRepoFromRemote)((0, pipeline_1.getPipelineGitRemote)(config, "github"));
|
|
65
|
+
};
|
|
66
|
+
exports.getConfiguredGithubRepo = getConfiguredGithubRepo;
|
|
67
|
+
/**
|
|
68
|
+
* copies the catladder secrets from the vault to github actions
|
|
69
|
+
* repository secrets, keeping the exact same names, so the github
|
|
70
|
+
* pipeline can reference them as ${{ secrets.<NAME> }}.
|
|
71
|
+
*/
|
|
72
|
+
exports.commandSecretsSyncGithub = (0, defineCommand_1.defineCommand)({
|
|
73
|
+
name: "project secrets-sync-github",
|
|
74
|
+
description: "copies all secrets from the vault to github repo secrets (same names), for the github pipeline",
|
|
75
|
+
group: "project",
|
|
76
|
+
inputs: {
|
|
77
|
+
repo: {
|
|
78
|
+
type: "string",
|
|
79
|
+
message: "github repository (owner/name)",
|
|
80
|
+
positional: true,
|
|
81
|
+
required: false
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
execute: async ctx => {
|
|
85
|
+
var _a;
|
|
86
|
+
const config = await (0, getProjectConfig_1.getProjectConfig)();
|
|
87
|
+
if (!config) {
|
|
88
|
+
throw new Error("no catladder config found");
|
|
89
|
+
}
|
|
90
|
+
const enabled = (0, pipeline_1.getEnabledPipelineTypes)(config);
|
|
91
|
+
if (!enabled.includes("github")) {
|
|
92
|
+
throw new Error("the github pipeline is not enabled in `pipelines` — nothing to sync to");
|
|
93
|
+
}
|
|
94
|
+
if (!(await (0, github_1.isGhAuthenticated)())) {
|
|
95
|
+
throw new Error("the github cli (gh) is not installed or not authenticated — run `gh auth login` first");
|
|
96
|
+
}
|
|
97
|
+
const repo = (_a = await ctx.get("repo")) !== null && _a !== void 0 ? _a : await (0, exports.getConfiguredGithubRepo)();
|
|
98
|
+
if (!repo) {
|
|
99
|
+
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`);
|
|
100
|
+
}
|
|
101
|
+
const {
|
|
102
|
+
secrets,
|
|
103
|
+
missing
|
|
104
|
+
} = await (0, exports.collectSecretsFromVault)(ctx);
|
|
105
|
+
if (missing.length > 0) {
|
|
106
|
+
ctx.log(`⚠️ ${missing.length} secrets are not set in the vault and will be skipped:`);
|
|
107
|
+
missing.forEach(name => ctx.log(` - ${name}`));
|
|
108
|
+
ctx.log("");
|
|
109
|
+
}
|
|
110
|
+
if (secrets.length === 0) {
|
|
111
|
+
ctx.log("no secrets to sync 🤷");
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
ctx.log(`about to set ${secrets.length} secrets on '${repo}':`);
|
|
115
|
+
secrets.forEach(({
|
|
116
|
+
name
|
|
117
|
+
}) => ctx.log(` - ${name}`));
|
|
118
|
+
ctx.log("");
|
|
119
|
+
const confirmed = await ctx.confirm("continue? 🤔");
|
|
120
|
+
if (!confirmed) {
|
|
121
|
+
throw new Error("abort");
|
|
122
|
+
}
|
|
123
|
+
await (0, exports.pushSecretsToGithub)(ctx, repo, secrets);
|
|
124
|
+
ctx.log("");
|
|
125
|
+
ctx.log("done! 😻 the github pipeline can use them as ${{ secrets.<NAME> }}");
|
|
126
|
+
}
|
|
127
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commandSecretsSyncGithub.js","sourceRoot":"","sources":["../../../../../src/commands/project/commandSecretsSyncGithub.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,7 +18,7 @@ export declare const getAllPipelineContexts: (onlyComponent?: string | string[],
|
|
|
18
18
|
}) => Promise<import("../../../pipeline/src/index.js").ComponentContext[]>;
|
|
19
19
|
export declare const getEnvironment: (env: string, componentName: string) => Promise<import("../../../pipeline/src/index.js").Environment>;
|
|
20
20
|
export declare const getGitlabVar: (io: IO, env: string, componentName: string, variableName: string) => Promise<string>;
|
|
21
|
-
export declare const getEnvVarsResolved: (io: IO
|
|
21
|
+
export declare const getEnvVarsResolved: (io: IO, env: string, componentName: string | null) => Promise<Record<string, string>>;
|
|
22
22
|
/**
|
|
23
23
|
*
|
|
24
24
|
* is used to get job only vars that should also be editable locally with catladder.
|
|
@@ -89,14 +89,24 @@ const getGitlabVar = async (io, env, componentName, variableName) => {
|
|
|
89
89
|
};
|
|
90
90
|
exports.getGitlabVar = getGitlabVar;
|
|
91
91
|
const resolveSecrets = async (io, varSets) => {
|
|
92
|
-
|
|
92
|
+
// the secret variables actually referenced by the env var values —
|
|
93
|
+
// when they are all in the local cache, the vault is not contacted
|
|
94
|
+
const referencedNames = [...new Set(varSets.flatMap(({
|
|
95
|
+
envVars
|
|
96
|
+
}) => Object.values(envVars).flatMap(value => {
|
|
97
|
+
var _a;
|
|
98
|
+
return (_a = `${value}`.match(/\$CL_\w+/g)) !== null && _a !== void 0 ? _a : [];
|
|
99
|
+
})))].map(reference => reference.slice(1));
|
|
100
|
+
const vaultManager = await io.getVaultManager();
|
|
101
|
+
const secrets = await vaultManager.readSecrets(referencedNames, io);
|
|
102
|
+
const secretEntries = Object.entries(secrets);
|
|
93
103
|
return Object.fromEntries(varSets.flatMap(({
|
|
94
104
|
envVars,
|
|
95
105
|
secretEnvVarKeys
|
|
96
106
|
}) => Object.entries(envVars).filter(([key, value]) => {
|
|
97
107
|
var _a;
|
|
98
108
|
return value !== undefined && value !== null && !((_a = secretEnvVarKeys.find(k => k.key === key)) === null || _a === void 0 ? void 0 : _a.hidden);
|
|
99
|
-
}).map(([key, value]) => [key,
|
|
109
|
+
}).map(([key, value]) => [key, secretEntries.reduce((acc, [name, secretValue]) => acc.replace(new RegExp("\\$" + name, "g"), secretValue), `${value}`)])));
|
|
100
110
|
};
|
|
101
111
|
const getEnvVarsResolved = async (io, env, componentName) => {
|
|
102
112
|
if (!componentName) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getProjectConfig.js","sourceRoot":"","sources":["../../../../src/config/getProjectConfig.ts"],"names":[],"mappings":";;;AAKA,kDAM6B;AAG7B,
|
|
1
|
+
{"version":3,"file":"getProjectConfig.js","sourceRoot":"","sources":["../../../../src/config/getProjectConfig.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { VaultManager } from "../vault/VaultManager";
|
|
1
2
|
import type { ComponentContext } from "../../../pipeline/src/index.js";
|
|
2
3
|
export type PromptChoice = string | {
|
|
3
4
|
name: string;
|
|
@@ -57,6 +58,17 @@ export type InputsSchema = Record<string, InputDef>;
|
|
|
57
58
|
* that are NOT part of a command's declared input schema.
|
|
58
59
|
*/
|
|
59
60
|
export interface IO {
|
|
61
|
+
/**
|
|
62
|
+
* whether this context can interact with the user (prompts, editors).
|
|
63
|
+
* Non-interactive contexts throw {@link NonInteractiveError} when an
|
|
64
|
+
* interaction would be required.
|
|
65
|
+
*/
|
|
66
|
+
readonly interactive: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* the secrets vault of this context, created lazily from the project
|
|
69
|
+
* config
|
|
70
|
+
*/
|
|
71
|
+
getVaultManager(): Promise<VaultManager>;
|
|
60
72
|
log(message: string): void;
|
|
61
73
|
/**
|
|
62
74
|
* Ask for confirmation. Returns true/false.
|
|
@@ -100,6 +112,9 @@ export interface CommandDef<TInputs extends InputsSchema = InputsSchema> {
|
|
|
100
112
|
isAvailable?: (contexts: ComponentContext[]) => boolean;
|
|
101
113
|
execute: (ctx: CommandContext<TInputs>) => Promise<void>;
|
|
102
114
|
}
|
|
115
|
+
export declare class NonInteractiveError extends Error {
|
|
116
|
+
constructor(interaction: string);
|
|
117
|
+
}
|
|
103
118
|
export declare class MissingInputError extends Error {
|
|
104
119
|
readonly inputName: string;
|
|
105
120
|
readonly promptMessage: string;
|
|
@@ -3,8 +3,15 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.MissingInputError = void 0;
|
|
6
|
+
exports.MissingInputError = exports.NonInteractiveError = void 0;
|
|
7
7
|
// ─── Errors ──────────────────────────────────────────────────────────
|
|
8
|
+
class NonInteractiveError extends Error {
|
|
9
|
+
constructor(interaction) {
|
|
10
|
+
super(`${interaction} requires an interactive terminal, but this context is not interactive`);
|
|
11
|
+
this.name = "NonInteractiveError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.NonInteractiveError = NonInteractiveError;
|
|
8
15
|
class MissingInputError extends Error {
|
|
9
16
|
constructor(inputName, promptMessage) {
|
|
10
17
|
super(`Missing required input: "${inputName}" (${promptMessage}). ` + `Provide it via --${inputName}=<value> or --inputs='{"${inputName}": ...}'`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/core/types.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/core/types.ts"],"names":[],"mappings":";;;AAiJA,wEAAwE;AAExE,MAAa,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,WAAmB;QAC7B,KAAK,CACH,GAAG,WAAW,wEAAwE,CACvF,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAPD,kDAOC;AAED,MAAa,iBAAkB,SAAQ,KAAK;IAC1C,YACkB,SAAiB,EACjB,aAAqB;QAErC,KAAK,CACH,4BAA4B,SAAS,MAAM,aAAa,KAAK;YAC3D,oBAAoB,SAAS,2BAA2B,SAAS,UAAU,CAC9E,CAAC;QANc,cAAS,GAAT,SAAS,CAAQ;QACjB,kBAAa,GAAb,aAAa,CAAQ;QAMrC,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AAXD,8CAWC"}
|
|
@@ -5,7 +5,7 @@ export declare const getProjectRootPath: () => Promise<string>;
|
|
|
5
5
|
/**
|
|
6
6
|
* Get the git remote hostname and project path from the git config.
|
|
7
7
|
*/
|
|
8
|
-
export declare const getGitRemoteHostAndPath: () => Promise<{
|
|
8
|
+
export declare const getGitRemoteHostAndPath: (remoteName?: string) => Promise<{
|
|
9
9
|
gitRemoteHost: string;
|
|
10
10
|
gitRemotePath: string;
|
|
11
11
|
}>;
|
|
@@ -19,14 +19,14 @@ exports.getProjectRootPath = getProjectRootPath;
|
|
|
19
19
|
/**
|
|
20
20
|
* Get the git remote hostname and project path from the git config.
|
|
21
21
|
*/
|
|
22
|
-
const getGitRemoteHostAndPath = async () => {
|
|
22
|
+
const getGitRemoteHostAndPath = async (remoteName = "origin") => {
|
|
23
23
|
var _a;
|
|
24
|
-
const remoteUrl = await (0, gitConfig_1.gitConfigGet)(
|
|
24
|
+
const remoteUrl = await (0, gitConfig_1.gitConfigGet)(`remote.${remoteName}.url`);
|
|
25
25
|
const remoteReg = /(https:\/\/|git@)([^:/]+)[:/]([^.]*)(\.git)?/;
|
|
26
26
|
const match = (_a = remoteUrl.match(remoteReg)) !== null && _a !== void 0 ? _a : [];
|
|
27
27
|
const [,, gitRemoteHost, gitRemotePath] = match;
|
|
28
28
|
if (!(gitRemoteHost === null || gitRemoteHost === void 0 ? void 0 : gitRemoteHost.length) || !(gitRemotePath === null || gitRemotePath === void 0 ? void 0 : gitRemotePath.length)) {
|
|
29
|
-
throw new Error(`Failed to parse git remote hostname and path from git configs remote.
|
|
29
|
+
throw new Error(`Failed to parse git remote hostname and path from git configs remote.${remoteName}.url! ${remoteUrl}`);
|
|
30
30
|
}
|
|
31
31
|
return {
|
|
32
32
|
gitRemoteHost,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gitProjectInformation.js","sourceRoot":"","sources":["../../../../src/git/gitProjectInformation.ts"],"names":[],"mappings":";;;AAAA,2CAA2C;AAC3C,iEAA6C;AAE7C;;GAEG;AACI,MAAM,kBAAkB,GAAG,KAAK,IAAqB,EAAE;IAC5D,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAA,4BAAI,EAAC,+BAA+B,CAAC,CAAC;IAC/D,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACvB,CAAC,CAAC;AAHW,QAAA,kBAAkB,sBAG7B;AAEF;;GAEG;AACI,MAAM,uBAAuB,GAAG,KAAK,
|
|
1
|
+
{"version":3,"file":"gitProjectInformation.js","sourceRoot":"","sources":["../../../../src/git/gitProjectInformation.ts"],"names":[],"mappings":";;;AAAA,2CAA2C;AAC3C,iEAA6C;AAE7C;;GAEG;AACI,MAAM,kBAAkB,GAAG,KAAK,IAAqB,EAAE;IAC5D,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAA,4BAAI,EAAC,+BAA+B,CAAC,CAAC;IAC/D,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACvB,CAAC,CAAC;AAHW,QAAA,kBAAkB,sBAG7B;AAEF;;GAEG;AACI,MAAM,uBAAuB,GAAG,KAAK,EAC1C,UAAU,GAAG,QAAQ,EAIpB,EAAE;;IACH,MAAM,SAAS,GAAG,MAAM,IAAA,wBAAY,EAAC,UAAU,UAAU,MAAM,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,8CAA8C,CAAC;IACjE,MAAM,KAAK,GAAG,MAAA,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,mCAAI,EAAE,CAAC;IAC/C,MAAM,CAAC,EAAE,AAAD,EAAG,aAAa,EAAE,aAAa,CAAC,GAAG,KAAK,CAAC;IACjD,IAAI,CAAC,CAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,MAAM,CAAA,IAAI,CAAC,CAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,MAAM,CAAA,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CACb,wEAAwE,UAAU,SAAS,SAAS,EAAE,CACvG,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC;AAC1C,CAAC,CAAC;AAhBW,QAAA,uBAAuB,2BAgBlC;AAEK,MAAM,qBAAqB,GAAG,KAAK,IAAI,EAAE;IAC9C,MAAM,CAAC,EAAE,aAAa,EAAE,aAAa,EAAE,EAAE,eAAe,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAC3E,CAAC,IAAA,+BAAuB,GAAE,EAAE,IAAA,0BAAkB,GAAE,CAAC,CAClD,CAAC;IACF,OAAO;QACL,aAAa;QACb,aAAa;QACb,eAAe;KAChB,CAAC;AACJ,CAAC,CAAC;AATW,QAAA,qBAAqB,yBAShC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* whether the github cli (gh) is installed and authenticated
|
|
3
|
+
*/
|
|
4
|
+
export declare const isGhAuthenticated: () => Promise<boolean>;
|
|
5
|
+
/**
|
|
6
|
+
* the github repository (owner/name) a git remote points to.
|
|
7
|
+
* Which remote belongs to github is configured per pipeline type
|
|
8
|
+
* (`pipelines.github.gitRemote`, defaults to origin).
|
|
9
|
+
*/
|
|
10
|
+
export declare const getGithubRepoFromRemote: (remoteName: string) => Promise<string | undefined>;
|
|
11
|
+
/**
|
|
12
|
+
* sets a github actions repository secret via the gh cli.
|
|
13
|
+
* The value is passed via stdin so it never shows up in a process list.
|
|
14
|
+
*/
|
|
15
|
+
export declare const setGithubSecret: (repo: string, name: string, value: string) => Promise<void>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.setGithubSecret = exports.getGithubRepoFromRemote = exports.isGhAuthenticated = void 0;
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const util_1 = require("util");
|
|
9
|
+
const execFile = (0, util_1.promisify)(child_process_1.execFile);
|
|
10
|
+
/**
|
|
11
|
+
* whether the github cli (gh) is installed and authenticated
|
|
12
|
+
*/
|
|
13
|
+
const isGhAuthenticated = async () => {
|
|
14
|
+
try {
|
|
15
|
+
await execFile("gh", ["auth", "status"]);
|
|
16
|
+
return true;
|
|
17
|
+
} catch (_a) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
exports.isGhAuthenticated = isGhAuthenticated;
|
|
22
|
+
/**
|
|
23
|
+
* the github repository (owner/name) a git remote points to.
|
|
24
|
+
* Which remote belongs to github is configured per pipeline type
|
|
25
|
+
* (`pipelines.github.gitRemote`, defaults to origin).
|
|
26
|
+
*/
|
|
27
|
+
const getGithubRepoFromRemote = async remoteName => {
|
|
28
|
+
try {
|
|
29
|
+
const {
|
|
30
|
+
stdout
|
|
31
|
+
} = await execFile("git", ["remote", "get-url", remoteName]);
|
|
32
|
+
const match = stdout.match(/github\.com[:/]([\w.-]+\/[\w.-]+?)(\.git)?\s*$/);
|
|
33
|
+
return match === null || match === void 0 ? void 0 : match[1];
|
|
34
|
+
} catch (_a) {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
exports.getGithubRepoFromRemote = getGithubRepoFromRemote;
|
|
39
|
+
/**
|
|
40
|
+
* sets a github actions repository secret via the gh cli.
|
|
41
|
+
* The value is passed via stdin so it never shows up in a process list.
|
|
42
|
+
*/
|
|
43
|
+
const setGithubSecret = async (repo, name, value) => new Promise((resolve, reject) => {
|
|
44
|
+
var _a, _b;
|
|
45
|
+
const child = (0, child_process_1.spawn)("gh", ["secret", "set", name, "--repo", repo], {
|
|
46
|
+
stdio: ["pipe", "ignore", "pipe"]
|
|
47
|
+
});
|
|
48
|
+
let stderr = "";
|
|
49
|
+
(_a = child.stderr) === null || _a === void 0 ? void 0 : _a.on("data", data => stderr += data);
|
|
50
|
+
child.on("error", reject);
|
|
51
|
+
child.on("close", code => code === 0 ? resolve() : reject(new Error(`gh secret set ${name} failed: ${stderr.trim()}`)));
|
|
52
|
+
(_b = child.stdin) === null || _b === void 0 ? void 0 : _b.end(value);
|
|
53
|
+
});
|
|
54
|
+
exports.setGithubSecret = setGithubSecret;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../../../src/utils/github.ts"],"names":[],"mappings":";;;AAAA,iDAA8D;AAC9D,+BAAiC;AAEjC,MAAM,QAAQ,GAAG,IAAA,gBAAS,EAAC,wBAAU,CAAC,CAAC;AAEvC;;GAEG;AACI,MAAM,iBAAiB,GAAG,KAAK,IAAsB,EAAE;IAC5D,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,WAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AAPW,QAAA,iBAAiB,qBAO5B;AAEF;;;;GAIG;AACI,MAAM,uBAAuB,GAAG,KAAK,EAC1C,UAAkB,EACW,EAAE;IAC/B,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;QAC5E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CACxB,gDAAgD,CACjD,CAAC;QACF,OAAO,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAG,CAAC,CAAC,CAAC;IACpB,CAAC;IAAC,WAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC,CAAC;AAZW,QAAA,uBAAuB,2BAYlC;AAEF;;;GAGG;AACI,MAAM,eAAe,GAAG,KAAK,EAClC,IAAY,EACZ,IAAY,EACZ,KAAa,EACE,EAAE,CACjB,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;;IACpC,MAAM,KAAK,GAAG,IAAA,qBAAK,EAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE;QACjE,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC;KAClC,CAAC,CAAC;IACH,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,MAAA,KAAK,CAAC,MAAM,0CAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC;IACrD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CACzB,IAAI,KAAK,CAAC;QACR,CAAC,CAAC,OAAO,EAAE;QACX,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,IAAI,YAAY,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CACxE,CAAC;IACF,MAAA,KAAK,CAAC,KAAK,0CAAE,GAAG,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC,CAAC,CAAC;AAlBQ,QAAA,eAAe,mBAkBvB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Config } from "../../../pipeline/src/index.js";
|
|
2
|
+
import type { IO } from "../core/types";
|
|
3
|
+
import type { SecretsVault } from "./types";
|
|
4
|
+
export declare class BitwardenVault implements SecretsVault {
|
|
5
|
+
private readonly config;
|
|
6
|
+
/**
|
|
7
|
+
* whether a locked bitwarden may be unlocked interactively
|
|
8
|
+
* (false with catenv --vault-mode no-prompt)
|
|
9
|
+
*/
|
|
10
|
+
private readonly allowPrompt;
|
|
11
|
+
readonly id: string;
|
|
12
|
+
private readonly collectionName;
|
|
13
|
+
constructor(config: Config, options: {
|
|
14
|
+
collection?: string;
|
|
15
|
+
},
|
|
16
|
+
/**
|
|
17
|
+
* whether a locked bitwarden may be unlocked interactively
|
|
18
|
+
* (false with catenv --vault-mode no-prompt)
|
|
19
|
+
*/
|
|
20
|
+
allowPrompt: boolean);
|
|
21
|
+
private session;
|
|
22
|
+
readAllSecrets(io: IO | null): Promise<Record<string, string>>;
|
|
23
|
+
writeSecrets(io: IO, env: string, componentName: string, secrets: Record<string, unknown>): Promise<void>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.BitwardenVault = void 0;
|
|
7
|
+
const pipeline_1 = require("../../../pipeline/src/index.js");
|
|
8
|
+
const yaml_1 = require("yaml");
|
|
9
|
+
const bw_1 = require("./bw");
|
|
10
|
+
const DEFAULT_COLLECTION = "catladder";
|
|
11
|
+
const SECURE_NOTE_TYPE = 2;
|
|
12
|
+
/**
|
|
13
|
+
* one yaml note per env and component:
|
|
14
|
+
* `<customerName>/<appName>/<env>/<componentName>/secrets.yml`
|
|
15
|
+
*/
|
|
16
|
+
const itemName = (config, env, componentName) => `${config.customerName}/${config.appName}/${env}/${componentName}/secrets.yml`;
|
|
17
|
+
const itemPrefix = config => `${config.customerName}/${config.appName}/`;
|
|
18
|
+
/**
|
|
19
|
+
* parses env and componentName back out of an item name
|
|
20
|
+
*/
|
|
21
|
+
const parseItemName = (config, name) => {
|
|
22
|
+
const match = name.slice(itemPrefix(config).length).match(/^([^/]+)\/([^/]+)\/secrets\.yml$/);
|
|
23
|
+
return match ? {
|
|
24
|
+
env: match[1],
|
|
25
|
+
componentName: match[2]
|
|
26
|
+
} : null;
|
|
27
|
+
};
|
|
28
|
+
const findCollection = async (session, collectionName) => {
|
|
29
|
+
const collections = await (0, bw_1.runBwJson)(session, ["list", "collections", "--search", collectionName]);
|
|
30
|
+
const collection = collections.find(c => c.name === collectionName);
|
|
31
|
+
if (!collection) {
|
|
32
|
+
throw new Error(`bitwarden collection '${collectionName}' not found — create it and make sure you have access`);
|
|
33
|
+
}
|
|
34
|
+
return collection;
|
|
35
|
+
};
|
|
36
|
+
const encodePayload = payload => Buffer.from(JSON.stringify(payload), "utf-8").toString("base64");
|
|
37
|
+
class BitwardenVault {
|
|
38
|
+
constructor(config, options,
|
|
39
|
+
/**
|
|
40
|
+
* whether a locked bitwarden may be unlocked interactively
|
|
41
|
+
* (false with catenv --vault-mode no-prompt)
|
|
42
|
+
*/
|
|
43
|
+
allowPrompt) {
|
|
44
|
+
var _a;
|
|
45
|
+
this.config = config;
|
|
46
|
+
this.allowPrompt = allowPrompt;
|
|
47
|
+
this.collectionName = (_a = options.collection) !== null && _a !== void 0 ? _a : DEFAULT_COLLECTION;
|
|
48
|
+
this.id = `bitwarden:${this.collectionName}`;
|
|
49
|
+
}
|
|
50
|
+
session(io) {
|
|
51
|
+
return (0, bw_1.getBwSession)(io, {
|
|
52
|
+
allowPrompt: this.allowPrompt
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
async readAllSecrets(io) {
|
|
56
|
+
const {
|
|
57
|
+
config,
|
|
58
|
+
collectionName
|
|
59
|
+
} = this;
|
|
60
|
+
const bwSession = await this.session(io);
|
|
61
|
+
const collection = await findCollection(bwSession, collectionName);
|
|
62
|
+
const items = await (0, bw_1.runBwJson)(bwSession, ["list", "items", "--collectionid", collection.id]);
|
|
63
|
+
const secrets = {};
|
|
64
|
+
for (const item of items) {
|
|
65
|
+
const parsed = parseItemName(config, item.name);
|
|
66
|
+
if (!parsed || !item.notes) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const values = (0, yaml_1.parse)(item.notes);
|
|
70
|
+
Object.entries(values !== null && values !== void 0 ? values : {}).forEach(([key, value]) => {
|
|
71
|
+
secrets[(0, pipeline_1.getSecretVarName)(parsed.env, parsed.componentName, key)] = typeof value === "string" ? value : JSON.stringify(value);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return secrets;
|
|
75
|
+
}
|
|
76
|
+
async writeSecrets(io, env, componentName, secrets) {
|
|
77
|
+
const {
|
|
78
|
+
config,
|
|
79
|
+
collectionName
|
|
80
|
+
} = this;
|
|
81
|
+
const bwSession = await this.session(io);
|
|
82
|
+
const collection = await findCollection(bwSession, collectionName);
|
|
83
|
+
const name = itemName(config, env, componentName);
|
|
84
|
+
const existing = (await (0, bw_1.runBwJson)(bwSession, ["list", "items", "--collectionid", collection.id, "--search", name])).find(item => item.name === name);
|
|
85
|
+
const notes = (0, yaml_1.stringify)(secrets);
|
|
86
|
+
if (existing) {
|
|
87
|
+
await (0, bw_1.runBw)(bwSession, ["edit", "item", existing.id, encodePayload({
|
|
88
|
+
...existing,
|
|
89
|
+
notes
|
|
90
|
+
})]);
|
|
91
|
+
} else {
|
|
92
|
+
await (0, bw_1.runBw)(bwSession, ["create", "item", encodePayload({
|
|
93
|
+
type: SECURE_NOTE_TYPE,
|
|
94
|
+
secureNote: {
|
|
95
|
+
type: 0
|
|
96
|
+
},
|
|
97
|
+
name,
|
|
98
|
+
notes,
|
|
99
|
+
...(collection.organizationId ? {
|
|
100
|
+
organizationId: collection.organizationId,
|
|
101
|
+
collectionIds: [collection.id]
|
|
102
|
+
} : {})
|
|
103
|
+
})]);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.BitwardenVault = BitwardenVault;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BitwardenVault.js","sourceRoot":"","sources":["../../../../src/vault/BitwardenVault.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { IO } from "../core/types";
|
|
2
|
+
import type { SecretsVault } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* the legacy (and default) vault: the gitlab project variables double
|
|
5
|
+
* as the secret store
|
|
6
|
+
*/
|
|
7
|
+
export declare class GitlabVault implements SecretsVault {
|
|
8
|
+
readonly id = "gitlab";
|
|
9
|
+
readAllSecrets(io: IO | null): Promise<Record<string, string>>;
|
|
10
|
+
writeSecrets(io: IO, env: string, componentName: string, secrets: Record<string, unknown>): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.GitlabVault = void 0;
|
|
7
|
+
const gitlab_1 = require("../utils/gitlab");
|
|
8
|
+
/**
|
|
9
|
+
* the legacy (and default) vault: the gitlab project variables double
|
|
10
|
+
* as the secret store
|
|
11
|
+
*/
|
|
12
|
+
class GitlabVault {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.id = "gitlab";
|
|
15
|
+
}
|
|
16
|
+
async readAllSecrets(io) {
|
|
17
|
+
const variables = await (0, gitlab_1.getAllVariables)(io);
|
|
18
|
+
return Object.fromEntries(variables.map(v => [v.key, v.value]));
|
|
19
|
+
}
|
|
20
|
+
async writeSecrets(io, env, componentName, secrets) {
|
|
21
|
+
await (0, gitlab_1.upsertAllVariables)(io, secrets, env, componentName);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.GitlabVault = GitlabVault;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GitlabVault.js","sourceRoot":"","sources":["../../../../src/vault/GitlabVault.ts"],"names":[],"mappings":";;;AACA,4CAAsE;AAGtE;;;GAGG;AACH,MAAa,WAAW;IAAxB;QACW,OAAE,GAAG,QAAQ,CAAC;IAezB,CAAC;IAbC,KAAK,CAAC,cAAc,CAAC,EAAa;QAChC,MAAM,SAAS,GAAG,MAAM,IAAA,wBAAe,EAAC,EAAE,CAAC,CAAC;QAC5C,OAAO,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,EAAM,EACN,GAAW,EACX,aAAqB,EACrB,OAAgC;QAEhC,MAAM,IAAA,2BAAkB,EAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,aAAa,CAAC,CAAC;IAC5D,CAAC;CACF;AAhBD,kCAgBC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Config } from "../../../pipeline/src/index.js";
|
|
2
|
+
import type { IO } from "../core/types";
|
|
3
|
+
import type { SecretsMode, SecretsVault } from "./types";
|
|
4
|
+
export type VaultManagerOptions = {
|
|
5
|
+
mode?: SecretsMode;
|
|
6
|
+
/**
|
|
7
|
+
* default IO for vault interactions (logging, unlock prompts).
|
|
8
|
+
* Method-level io takes precedence.
|
|
9
|
+
*/
|
|
10
|
+
io?: IO | null;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* owns the configured vault, the secrets mode and the local cache.
|
|
14
|
+
* The vault is the readable source of truth for secrets; CI backends
|
|
15
|
+
* only receive mirrored copies.
|
|
16
|
+
*/
|
|
17
|
+
export declare class VaultManager {
|
|
18
|
+
private readonly config;
|
|
19
|
+
readonly mode: SecretsMode;
|
|
20
|
+
readonly vault: SecretsVault;
|
|
21
|
+
private readonly io;
|
|
22
|
+
/** refresh mode bypasses the cache only once per manager */
|
|
23
|
+
private refreshed;
|
|
24
|
+
constructor(config: Config, options?: VaultManagerOptions);
|
|
25
|
+
private createVault;
|
|
26
|
+
/**
|
|
27
|
+
* the vault secrets, served from the local cache when it contains
|
|
28
|
+
* all required names; otherwise (depending on the mode) refreshed
|
|
29
|
+
* from the vault. Only the "local" env is (re-)cached.
|
|
30
|
+
*/
|
|
31
|
+
readSecrets(requiredNames: string[], io?: IO | null): Promise<Record<string, string>>;
|
|
32
|
+
/**
|
|
33
|
+
* writes secrets of one env/component to the vault and updates the
|
|
34
|
+
* local cache (write-through, "local" env only)
|
|
35
|
+
*/
|
|
36
|
+
writeSecrets(env: string, componentName: string, secrets: Record<string, unknown>, io?: IO | null): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* the subset of the vault secrets that may be cached: the declared
|
|
39
|
+
* secrets of the "local" env, per component, as a hierarchy
|
|
40
|
+
*/
|
|
41
|
+
private cacheableSubset;
|
|
42
|
+
private declaredSecretKeys;
|
|
43
|
+
}
|