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
13
action.js
13
action.js
|
|
@ -10,7 +10,7 @@ async function exportSecrets() {
|
||||||
const keys = parseKeysInput(keysInput);
|
const keys = parseKeysInput(keysInput);
|
||||||
|
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
const [keyPath, { outputName, dataKey }] = key;
|
const { keyPath, outputName, dataKey } = key;
|
||||||
const result = await got(`${vaultUrl}/v1/secret/data/${keyPath}`, {
|
const result = await got(`${vaultUrl}/v1/secret/data/${keyPath}`, {
|
||||||
headers: {
|
headers: {
|
||||||
'X-Vault-Token': vaultToken
|
'X-Vault-Token': vaultToken
|
||||||
|
|
@ -38,8 +38,8 @@ function parseKeysInput(keys) {
|
||||||
.map(key => key.trim())
|
.map(key => key.trim())
|
||||||
.filter(key => key.length !== 0);
|
.filter(key => key.length !== 0);
|
||||||
|
|
||||||
/** @type {Map<string, { outputName: string; dataKey: string; }>} */
|
/** @type {{ keyPath: string; outputName: string; dataKey: string; }[]} */
|
||||||
const output = new Map();
|
const output = [];
|
||||||
for (const keyPair of keyPairs) {
|
for (const keyPair of keyPairs) {
|
||||||
let path = keyPair;
|
let path = keyPair;
|
||||||
let outputName = null;
|
let outputName = null;
|
||||||
|
|
@ -63,14 +63,15 @@ function parseKeysInput(keys) {
|
||||||
throw Error(`You must provide a valid path and key. Input: "${keyPair}"`)
|
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 we're not using a mapped name, normalize the key path into a variable name.
|
||||||
if (!outputName) {
|
if (!outputName) {
|
||||||
outputName = normalizeKeyName(dataKey);
|
outputName = normalizeKeyName(dataKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
output.set(secretPath, {
|
output.push({
|
||||||
|
keyPath,
|
||||||
outputName,
|
outputName,
|
||||||
dataKey
|
dataKey
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -14,17 +14,18 @@ const { when } = require('jest-when');
|
||||||
describe('parseKeysInput', () => {
|
describe('parseKeysInput', () => {
|
||||||
it('parses simple key', () => {
|
it('parses simple key', () => {
|
||||||
const output = parseKeysInput('test key');
|
const output = parseKeysInput('test key');
|
||||||
expect(output.has('test')).toBeTruthy();
|
expect(output).toContainEqual({
|
||||||
expect(output.get('test')).toMatchObject({
|
keyPath: 'test',
|
||||||
|
dataKey: 'key',
|
||||||
outputName: 'KEY',
|
outputName: 'KEY',
|
||||||
dataKey: 'key'
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parses mapped key', () => {
|
it('parses mapped key', () => {
|
||||||
const output = parseKeysInput('test key|testName');
|
const output = parseKeysInput('test key|testName');
|
||||||
expect(output.get('test')).toMatchObject({
|
expect(output).toHaveLength(1);
|
||||||
outputName: 'testName'
|
expect(output[0]).toMatchObject({
|
||||||
|
outputName: 'testName',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -41,29 +42,43 @@ describe('parseKeysInput', () => {
|
||||||
it('parses multiple keys', () => {
|
it('parses multiple keys', () => {
|
||||||
const output = parseKeysInput('first a;second b;');
|
const output = parseKeysInput('first a;second b;');
|
||||||
|
|
||||||
expect(output.size).toBe(2);
|
expect(output).toHaveLength(2);
|
||||||
expect(output.has('first')).toBeTruthy();
|
expect(output[0]).toMatchObject({
|
||||||
expect(output.has('second')).toBeTruthy();
|
keyPath: 'first',
|
||||||
|
});
|
||||||
|
expect(output[1]).toMatchObject({
|
||||||
|
keyPath: 'second',
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parses multiple complex keys', () => {
|
it('parses multiple complex keys', () => {
|
||||||
const output = parseKeysInput('first a;second b|secondName');
|
const output = parseKeysInput('first a;second b|secondName');
|
||||||
|
|
||||||
expect(output.size).toBe(2);
|
expect(output).toHaveLength(2);
|
||||||
expect(output.get('first')).toMatchObject({
|
expect(output[0]).toMatchObject({
|
||||||
dataKey: 'a'
|
outputName: 'A',
|
||||||
});
|
});
|
||||||
expect(output.get('second')).toMatchObject({
|
expect(output[1]).toMatchObject({
|
||||||
outputName: 'secondName'
|
outputName: 'secondName',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('parses multiline input', () => {
|
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).toHaveLength(3);
|
||||||
expect(output.has('first')).toBeTruthy();
|
expect(output[0]).toMatchObject({
|
||||||
expect(output.has('second')).toBeTruthy();
|
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');
|
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