in src/update-secrets.ts [75:165]
export async function updateSecrets(options: UpdateSecretsOptions) {
const secretId = options.secret;
const c = options.clients ?? clients.DEFAULTS;
// if the secret id is an arn, extract the region from it
let region = options.region;
if (!region && secretId.startsWith('arn:')) {
region = secretId.split(':')[3];
}
const repository: string = options.repository ?? c.getRepositoryName();
const secret = await c.getSecret(options.secret, { region, profile: options.profile });
const keys = options.keys ?? [];
const prune = options.prune ?? false;
const keep = options.keep ?? [];
if (typeof(secret.json) !== 'object') {
throw new Error(`Secret "${secret.arn}" is not an object`);
}
if (options.allKeys === undefined && options.keys === undefined) {
throw new Error('Either `all` or `keys` must be set');
}
if (options.allKeys) {
if (keys.length > 0) {
throw new Error('Cannot set both `all` and `keys`');
}
// remove "*" and replace with all the keys from the secret
keys.push(...Object.keys(secret.json));
}
if (keys.length === 0) {
throw new Error('No keys to update');
}
// verify that all the keys exist in the secret
for (const requiredKey of keys) {
if (!(requiredKey in secret.json)) {
throw new Error(`Secret "${secretId}" does not contain key "${requiredKey}"`);
}
}
// find all the secrets in the repo that don't correspond to keys in the secret
const existingKeys = c.listSecrets(repository);
const pruneCandidates = existingKeys.filter(key => !keys.includes(key));
const keysToPrune = pruneCandidates.filter(key => !keep.includes(key));
const keysToKeep = pruneCandidates.filter(key => keep.includes(key));
c.log(`FROM : ${secret.arn}`);
c.log(`REPO : ${repository}`);
c.log(`UDPATE: ${keys.join(',')}`);
if (pruneCandidates.length > 0) {
if (prune) {
if (keysToPrune.length > 0) {
c.log(`PRUNE : ${keysToPrune.join(',')}`);
}
if (keysToKeep.length > 0) {
c.log(`KEEP : ${keysToKeep.join(',')}`);
}
} else {
c.log(`SKIP : ${pruneCandidates.join(',')} (use --prune to remove)`);
}
}
c.log();
// ask user to confirm
const confirm = options.confirm ?? true;
if (confirm && !await c.confirmPrompt()) {
c.log('Cancelled by user');
return;
}
for (const [key, value] of Object.entries(secret.json)) {
if (keys.length > 0 && !keys.includes(key)) {
continue; // skip if key is not in "keys"
}
c.storeSecret(repository, key, value);
}
// prune keys that are not in the secret
if (prune) {
for (const key of keysToPrune) {
c.removeSecret(repository, key);
}
}
}