feature request: write secrets to vault

feature request: write secrets to vault
This commit is contained in:
vikas-pundir-learnings 2023-07-16 19:06:34 +01:00
parent 65d7a12a80
commit f3f9f6b112
9 changed files with 754 additions and 32 deletions

View file

@ -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');
});
})
});

View file

@ -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);
}