mirror of
https://github.com/hashicorp/vault-action.git
synced 2025-11-07 15:16:56 +00:00
fix: keys with the same path getting overwritten
This commit is contained in:
parent
b524055d38
commit
9c32e02d93
3 changed files with 54 additions and 23 deletions
11
action.js
11
action.js
|
|
@ -10,7 +10,7 @@ async function exportSecrets() {
|
|||
const keys = parseKeysInput(keysInput);
|
||||
|
||||
for (const key of keys) {
|
||||
const [keyPath, { outputName, dataKey }] = key;
|
||||
const { keyPath, outputName, dataKey } = key;
|
||||
const result = await got(`${vaultUrl}/v1/secret/data/${keyPath}`, {
|
||||
headers: {
|
||||
'X-Vault-Token': vaultToken
|
||||
|
|
@ -38,8 +38,8 @@ function parseKeysInput(keys) {
|
|||
.map(key => key.trim())
|
||||
.filter(key => key.length !== 0);
|
||||
|
||||
/** @type {Map<string, { outputName: string; dataKey: string; }>} */
|
||||
const output = new Map();
|
||||
/** @type {{ keyPath: string; outputName: string; dataKey: string; }[]} */
|
||||
const output = [];
|
||||
for (const keyPair of keyPairs) {
|
||||
let path = keyPair;
|
||||
let outputName = null;
|
||||
|
|
@ -63,14 +63,15 @@ function parseKeysInput(keys) {
|
|||
throw Error(`You must provide a valid path and key. Input: "${keyPair}"`)
|
||||
}
|
||||
|
||||
const [secretPath, dataKey] = pathParts;
|
||||
const [keyPath, dataKey] = pathParts;
|
||||
|
||||
// If we're not using a mapped name, normalize the key path into a variable name.
|
||||
if (!outputName) {
|
||||
outputName = normalizeKeyName(dataKey);
|
||||
}
|
||||
|
||||
output.set(secretPath, {
|
||||
output.push({
|
||||
keyPath,
|
||||
outputName,
|
||||
dataKey
|
||||
});
|
||||
|
|
|
|||
|
|
@ -14,17 +14,18 @@ const { when } = require('jest-when');
|
|||
describe('parseKeysInput', () => {
|
||||
it('parses simple key', () => {
|
||||
const output = parseKeysInput('test key');
|
||||
expect(output.has('test')).toBeTruthy();
|
||||
expect(output.get('test')).toMatchObject({
|
||||
expect(output).toContainEqual({
|
||||
keyPath: 'test',
|
||||
dataKey: 'key',
|
||||
outputName: 'KEY',
|
||||
dataKey: 'key'
|
||||
});
|
||||
});
|
||||
|
||||
it('parses mapped key', () => {
|
||||
const output = parseKeysInput('test key|testName');
|
||||
expect(output.get('test')).toMatchObject({
|
||||
outputName: 'testName'
|
||||
expect(output).toHaveLength(1);
|
||||
expect(output[0]).toMatchObject({
|
||||
outputName: 'testName',
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -41,29 +42,43 @@ describe('parseKeysInput', () => {
|
|||
it('parses multiple keys', () => {
|
||||
const output = parseKeysInput('first a;second b;');
|
||||
|
||||
expect(output.size).toBe(2);
|
||||
expect(output.has('first')).toBeTruthy();
|
||||
expect(output.has('second')).toBeTruthy();
|
||||
expect(output).toHaveLength(2);
|
||||
expect(output[0]).toMatchObject({
|
||||
keyPath: 'first',
|
||||
});
|
||||
expect(output[1]).toMatchObject({
|
||||
keyPath: 'second',
|
||||
});
|
||||
});
|
||||
|
||||
it('parses multiple complex keys', () => {
|
||||
const output = parseKeysInput('first a;second b|secondName');
|
||||
|
||||
expect(output.size).toBe(2);
|
||||
expect(output.get('first')).toMatchObject({
|
||||
dataKey: 'a'
|
||||
expect(output).toHaveLength(2);
|
||||
expect(output[0]).toMatchObject({
|
||||
outputName: 'A',
|
||||
});
|
||||
expect(output.get('second')).toMatchObject({
|
||||
outputName: 'secondName'
|
||||
expect(output[1]).toMatchObject({
|
||||
outputName: 'secondName',
|
||||
});
|
||||
});
|
||||
|
||||
it('parses multiline input', () => {
|
||||
const output = parseKeysInput('\nfirst a;\nsecond b;\n');
|
||||
const output = parseKeysInput(`
|
||||
first a;
|
||||
second b;
|
||||
third c | SOME_C;`);
|
||||
|
||||
expect(output.size).toBe(2);
|
||||
expect(output.has('first')).toBeTruthy();
|
||||
expect(output.has('second')).toBeTruthy();
|
||||
expect(output).toHaveLength(3);
|
||||
expect(output[0]).toMatchObject({
|
||||
keyPath: 'first',
|
||||
});
|
||||
expect(output[1]).toMatchObject({
|
||||
outputName: 'B',
|
||||
});
|
||||
expect(output[2]).toMatchObject({
|
||||
outputName: 'SOME_C',
|
||||
});
|
||||
})
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -85,4 +85,19 @@ describe('integration', () => {
|
|||
|
||||
expect(core.exportVariable).toBeCalledWith('OTHERSECRET', 'OTHERSUPERSECRET');
|
||||
});
|
||||
|
||||
it('get multiple secrets', async () => {
|
||||
mockInput(`
|
||||
test secret ;
|
||||
test secret | NAMED_SECRET ;
|
||||
nested/test otherSecret ;`);
|
||||
|
||||
await exportSecrets();
|
||||
|
||||
expect(core.exportVariable).toBeCalledTimes(3);
|
||||
|
||||
expect(core.exportVariable).toBeCalledWith('SECRET', 'SUPERSECRET');
|
||||
expect(core.exportVariable).toBeCalledWith('NAMED_SECRET', 'SUPERSECRET');
|
||||
expect(core.exportVariable).toBeCalledWith('OTHERSECRET', 'OTHERSUPERSECRET');
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue