mirror of
https://github.com/hashicorp/vault-action.git
synced 2026-04-16 16:55:45 +00:00
feature request: write secrets to vault
feature request: write secrets to vault
This commit is contained in:
parent
65d7a12a80
commit
f3f9f6b112
9 changed files with 754 additions and 32 deletions
|
|
@ -9,10 +9,12 @@ const { exportSecrets } = require('../../src/action');
|
|||
|
||||
const vaultUrl = `http://${process.env.VAULT_HOST || 'localhost'}:${process.env.VAULT_PORT || '8200'}`;
|
||||
const vaultToken = `${process.env.VAULT_TOKEN || 'testtoken'}`
|
||||
const secretsMethod = { Read: "read", Write: "write" };
|
||||
|
||||
describe('integration', () => {
|
||||
beforeAll(async () => {
|
||||
// Verify Connection
|
||||
console.log('before all');
|
||||
await got(`${vaultUrl}/v1/secret/config`, {
|
||||
headers: {
|
||||
'X-Vault-Token': vaultToken,
|
||||
|
|
@ -75,7 +77,7 @@ describe('integration', () => {
|
|||
}
|
||||
}
|
||||
|
||||
await got(`${vaultUrl}/v1/secret-kv1/test`, {
|
||||
await got(`${vaultUrl}/v1/secret-kv1/test`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Vault-Token': vaultToken,
|
||||
|
|
@ -124,6 +126,12 @@ describe('integration', () => {
|
|||
.mockReturnValueOnce(secrets);
|
||||
}
|
||||
|
||||
function mockSecretsMethod(method) {
|
||||
when(core.getInput)
|
||||
.calledWith('secretsMethod', expect.anything())
|
||||
.mockReturnValueOnce(method);
|
||||
}
|
||||
|
||||
it('prints a nice error message when secret not found', async () => {
|
||||
mockInput(`secret/data/test secret ;
|
||||
secret/data/test secret | NAMED_SECRET ;
|
||||
|
|
@ -140,6 +148,16 @@ describe('integration', () => {
|
|||
expect(core.exportVariable).toBeCalledWith('SECRET', 'SUPERSECRET');
|
||||
});
|
||||
|
||||
it('write secret: simple secret', async () => {
|
||||
mockInput('secret/data/writetest secret=TEST');
|
||||
mockSecretsMethod(secretsMethod.Write);
|
||||
|
||||
await exportSecrets();
|
||||
|
||||
expect(core.exportVariable).toBeCalledTimes(1);
|
||||
expect(core.exportVariable).toBeCalledWith('SECRET', 'SUCCESS');
|
||||
});
|
||||
|
||||
it('re-map secret', async () => {
|
||||
mockInput('secret/data/test secret | TEST_KEY');
|
||||
|
||||
|
|
@ -148,6 +166,15 @@ describe('integration', () => {
|
|||
expect(core.exportVariable).toBeCalledWith('TEST_KEY', 'SUPERSECRET');
|
||||
});
|
||||
|
||||
it('write secret: re-map secret', async () => {
|
||||
mockInput('secret/data/writetest secret=TEST | TEST_KEY');
|
||||
mockSecretsMethod(secretsMethod.Write);
|
||||
await exportSecrets();
|
||||
|
||||
expect(core.exportVariable).toBeCalledTimes(1);
|
||||
expect(core.exportVariable).toBeCalledWith('TEST_KEY', 'SUCCESS');
|
||||
});
|
||||
|
||||
it('get nested secret', async () => {
|
||||
mockInput(`secret/data/nested/test "other-Secret-dash"`);
|
||||
|
||||
|
|
@ -171,6 +198,18 @@ describe('integration', () => {
|
|||
expect(core.exportVariable).toBeCalledWith('OTHERSECRETDASH', 'OTHERSUPERSECRET');
|
||||
});
|
||||
|
||||
it('write secrets: multiple secrets', async () => {
|
||||
mockInput(`
|
||||
secret/data/writetest secret=TEST ;
|
||||
secret/data/writetest secret=TEST | NAMED_SECRET ;`);
|
||||
mockSecretsMethod(secretsMethod.Write);
|
||||
await exportSecrets();
|
||||
|
||||
expect(core.exportVariable).toBeCalledTimes(2);
|
||||
expect(core.exportVariable).toBeCalledWith('SECRET', 'SUCCESS');
|
||||
expect(core.exportVariable).toBeCalledWith('NAMED_SECRET', 'SUCCESS');
|
||||
});
|
||||
|
||||
it('leading slash kvv2', async () => {
|
||||
mockInput('/secret/data/foobar fookv2');
|
||||
|
||||
|
|
@ -179,6 +218,15 @@ describe('integration', () => {
|
|||
expect(core.exportVariable).toBeCalledWith('FOOKV2', 'bar');
|
||||
});
|
||||
|
||||
it('write secrets: leading slash kvv2', async () => {
|
||||
mockInput('/secret/data/foobar fookv2=bar');
|
||||
mockSecretsMethod(secretsMethod.Write);
|
||||
await exportSecrets();
|
||||
|
||||
expect(core.exportVariable).toBeCalledTimes(1);
|
||||
expect(core.exportVariable).toBeCalledWith('FOOKV2', 'SUCCESS');
|
||||
});
|
||||
|
||||
it('get secret from K/V v1', async () => {
|
||||
mockInput('secret-kv1/test secret');
|
||||
|
||||
|
|
@ -187,6 +235,15 @@ describe('integration', () => {
|
|||
expect(core.exportVariable).toBeCalledWith('SECRET', 'CUSTOMSECRET');
|
||||
});
|
||||
|
||||
it('write secrets: secret from K/V v1', async () => {
|
||||
mockInput('secret-kv1/test secret=CUSTOMSECRET');
|
||||
mockSecretsMethod(secretsMethod.Write);
|
||||
|
||||
await exportSecrets();
|
||||
expect(core.exportVariable).toBeCalledTimes(1);
|
||||
expect(core.exportVariable).toBeCalledWith('SECRET', 'SUCCESS');
|
||||
});
|
||||
|
||||
it('get nested secret from K/V v1', async () => {
|
||||
mockInput('secret-kv1/nested/test "other-Secret-dash"');
|
||||
|
||||
|
|
@ -203,6 +260,15 @@ describe('integration', () => {
|
|||
expect(core.exportVariable).toBeCalledWith('FOOKV1', 'bar');
|
||||
});
|
||||
|
||||
it('write secrets: leading slash kvv1', async () => {
|
||||
mockInput('/secret-kv1/foobar fookv1=bar');
|
||||
mockSecretsMethod(secretsMethod.Write);
|
||||
|
||||
await exportSecrets();
|
||||
expect(core.exportVariable).toBeCalledTimes(1);
|
||||
expect(core.exportVariable).toBeCalledWith('FOOKV1', 'SUCCESS');
|
||||
});
|
||||
|
||||
describe('generic engines', () => {
|
||||
beforeAll(async () => {
|
||||
await got(`${vaultUrl}/v1/cubbyhole/test`, {
|
||||
|
|
@ -237,5 +303,26 @@ describe('integration', () => {
|
|||
expect(core.exportVariable).toBeCalledWith('FOO', 'bar');
|
||||
expect(core.exportVariable).toBeCalledWith('ZIP', 'zap');
|
||||
});
|
||||
|
||||
it('write secrets: supports cubbyhole', async () => {
|
||||
mockInput('/cubbyhole/test foo=foo');
|
||||
mockSecretsMethod(secretsMethod.Write);
|
||||
|
||||
await exportSecrets();
|
||||
|
||||
expect(core.exportVariable).toBeCalledWith('FOO', 'SUCCESS');
|
||||
});
|
||||
|
||||
it('write secrets: multiple secrets', async () => {
|
||||
mockInput(`
|
||||
/cubbyhole/test foo=foo ;
|
||||
/cubbyhole/test zip=zip`);
|
||||
mockSecretsMethod(secretsMethod.Write);
|
||||
|
||||
await exportSecrets();
|
||||
|
||||
expect(core.exportVariable).toBeCalledWith('FOO', 'SUCCESS');
|
||||
expect(core.exportVariable).toBeCalledWith('ZIP', 'SUCCESS');
|
||||
});
|
||||
})
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ const { exportSecrets } = require('../../src/action');
|
|||
|
||||
const vaultUrl = `http://${process.env.VAULT_HOST || 'localhost'}:${process.env.VAULT_PORT || '8201'}`;
|
||||
const vaultToken = `${process.env.VAULT_TOKEN || 'testtoken'}`
|
||||
const secretsMethod = { Read: "read", Write: "write" };
|
||||
|
||||
describe('integration', () => {
|
||||
beforeAll(async () => {
|
||||
|
|
@ -64,6 +65,16 @@ describe('integration', () => {
|
|||
expect(core.exportVariable).toBeCalledWith('SECRET', 'SUPERSECRET_IN_NAMESPACE');
|
||||
});
|
||||
|
||||
it('write secret: simple secret', async () => {
|
||||
mockInput('secret/data/writetest secret=TEST');
|
||||
mockSecretsMethod(secretsMethod.Write);
|
||||
|
||||
await exportSecrets();
|
||||
|
||||
expect(core.exportVariable).toBeCalledTimes(1);
|
||||
expect(core.exportVariable).toBeCalledWith('SECRET', 'SUCCESS');
|
||||
});
|
||||
|
||||
it('re-map secret', async () => {
|
||||
mockInput('secret/data/test secret | TEST_KEY');
|
||||
|
||||
|
|
@ -72,6 +83,15 @@ describe('integration', () => {
|
|||
expect(core.exportVariable).toBeCalledWith('TEST_KEY', 'SUPERSECRET_IN_NAMESPACE');
|
||||
});
|
||||
|
||||
it('write secret: re-map secret', async () => {
|
||||
mockInput('secret/data/writetest secret=TEST | TEST_KEY');
|
||||
mockSecretsMethod(secretsMethod.Write);
|
||||
await exportSecrets();
|
||||
|
||||
expect(core.exportVariable).toBeCalledTimes(1);
|
||||
expect(core.exportVariable).toBeCalledWith('TEST_KEY', 'SUCCESS');
|
||||
});
|
||||
|
||||
it('get nested secret', async () => {
|
||||
mockInput('secret/data/nested/test otherSecret');
|
||||
|
||||
|
|
@ -95,6 +115,18 @@ describe('integration', () => {
|
|||
expect(core.exportVariable).toBeCalledWith('OTHERSECRET', 'OTHERSUPERSECRET_IN_NAMESPACE');
|
||||
});
|
||||
|
||||
it('write secrets: multiple secrets', async () => {
|
||||
mockInput(`
|
||||
secret/data/writetest secret=TEST ;
|
||||
secret/data/writetest secret=TEST | NAMED_SECRET ;`);
|
||||
mockSecretsMethod(secretsMethod.Write);
|
||||
await exportSecrets();
|
||||
|
||||
expect(core.exportVariable).toBeCalledTimes(2);
|
||||
expect(core.exportVariable).toBeCalledWith('SECRET', 'SUCCESS');
|
||||
expect(core.exportVariable).toBeCalledWith('NAMED_SECRET', 'SUCCESS');
|
||||
});
|
||||
|
||||
it('get secret from K/V v1', async () => {
|
||||
mockInput('my-secret/test secret');
|
||||
|
||||
|
|
@ -103,6 +135,15 @@ describe('integration', () => {
|
|||
expect(core.exportVariable).toBeCalledWith('SECRET', 'CUSTOMSECRET_IN_NAMESPACE');
|
||||
});
|
||||
|
||||
it('write secrets: secret from K/V v1', async () => {
|
||||
mockInput('secret-kv1/test secret=CUSTOMSECRET');
|
||||
mockSecretsMethod(secretsMethod.Write);
|
||||
|
||||
await exportSecrets();
|
||||
expect(core.exportVariable).toBeCalledTimes(1);
|
||||
expect(core.exportVariable).toBeCalledWith('SECRET', 'SUCCESS');
|
||||
});
|
||||
|
||||
it('get nested secret from K/V v1', async () => {
|
||||
mockInput('my-secret/nested/test otherSecret');
|
||||
|
||||
|
|
@ -290,3 +331,10 @@ function mockInput(secrets) {
|
|||
.calledWith('secrets', expect.anything())
|
||||
.mockReturnValueOnce(secrets);
|
||||
}
|
||||
|
||||
function mockSecretsMethod(method) {
|
||||
when(core.getInput)
|
||||
.calledWith('secretsMethod', expect.anything())
|
||||
.mockReturnValueOnce(method);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue