5
0
Fork 0
mirror of https://github.com/hashicorp/vault-action.git synced 2025-11-07 07:06:56 +00:00
vault-action/integrationTests/basic/integration.test.js
2024-04-15 14:40:43 +08:00

341 lines
9.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { vi, describe, test, expect } from 'vitest';
vi.mock('@actions/core');
import core from '@actions/core';
import got from 'got';
import { when } from 'jest-when'
import { exportSecrets } from '../../src/action.js';
const vaultUrl = `http://${process.env.VAULT_HOST || 'localhost'}:${process.env.VAULT_PORT || '8200'}`;
const vaultToken = `${process.env.VAULT_TOKEN || 'testtoken'}`
describe('integration', () => {
beforeAll(async () => {
// Verify Connection
await got(`${vaultUrl}/v1/secret/config`, {
headers: {
'X-Vault-Token': vaultToken,
},
});
await got(`${vaultUrl}/v1/secret/data/test`, {
method: 'POST',
headers: {
'X-Vault-Token': vaultToken,
},
json: {
data: {
secret: 'SUPERSECRET',
},
},
});
await got(`${vaultUrl}/v1/secret/data/test-with-dot-char`, {
method: 'POST',
headers: {
'X-Vault-Token': vaultToken,
},
body: `{"data":{"secret.foo":{"SUPERKEY":"SUPERSECRET"}}}`
});
await got(`${vaultUrl}/v1/secret/data/nested/test`, {
method: 'POST',
headers: {
'X-Vault-Token': vaultToken,
},
json: {
data: {
"other-Secret-dash": 'OTHERSUPERSECRET',
},
}
});
await got(`${vaultUrl}/v1/secret/data/foobar`, {
method: 'POST',
headers: {
'X-Vault-Token': vaultToken,
},
json: {
data: {
fookv2: 'bar',
},
}
});
// Enable custom secret engine
try {
await got(`${vaultUrl}/v1/sys/mounts/secret-kv1`, {
method: 'POST',
headers: {
'X-Vault-Token': vaultToken,
},
json: {
type: 'kv'
}
});
} catch (error) {
const {response} = error;
if (response.statusCode === 400 && response.body.includes("path is already in use")) {
// Engine might already be enabled from previous test runs
} else {
throw error;
}
}
await got(`${vaultUrl}/v1/secret-kv1/test`, {
method: 'POST',
headers: {
'X-Vault-Token': vaultToken,
},
json: {
secret: 'CUSTOMSECRET',
}
});
await got(`${vaultUrl}/v1/secret-kv1/foobar`, {
method: 'POST',
headers: {
'X-Vault-Token': vaultToken,
},
json: {
fookv1: 'bar',
}
});
await got(`${vaultUrl}/v1/secret-kv1/nested/test`, {
method: 'POST',
headers: {
'X-Vault-Token': vaultToken,
},
json: {
"other-Secret-dash": 'OTHERCUSTOMSECRET',
},
});
});
beforeEach(() => {
vi.resetAllMocks();
when(core.getInput)
.calledWith('url', expect.anything())
.mockReturnValueOnce(`${vaultUrl}`);
when(core.getInput)
.calledWith('token', expect.anything())
.mockReturnValueOnce(vaultToken);
});
function mockInput(secrets) {
when(core.getInput)
.calledWith('secrets', expect.anything())
.mockReturnValueOnce(secrets);
}
function mockIgnoreNotFound(shouldIgnore) {
when(core.getInput)
.calledWith('ignoreNotFound', expect.anything())
.mockReturnValueOnce(shouldIgnore);
}
it('prints a nice error message when secret not found', async () => {
mockInput(`secret/data/test secret ;
secret/data/test secret | NAMED_SECRET ;
secret/data/notFound kehe | NO_SIR ;`);
await expect(exportSecrets()).rejects.toEqual(Error(`Unable to retrieve result for "secret/data/notFound" because it was not found: {"errors":[]}`));
})
it('does not error when secret not found and ignoreNotFound is true', async () => {
mockInput(`secret/data/test secret ;
secret/data/test secret | NAMED_SECRET ;
secret/data/notFound kehe | NO_SIR ;`);
mockIgnoreNotFound("true");
await exportSecrets();
expect(core.exportVariable).toBeCalledTimes(2);
expect(core.exportVariable).toBeCalledWith('SECRET', 'SUPERSECRET');
expect(core.exportVariable).toBeCalledWith('NAMED_SECRET', 'SUPERSECRET');
})
it('get simple secret', async () => {
mockInput('secret/data/test secret');
await exportSecrets();
expect(core.exportVariable).toBeCalledWith('SECRET', 'SUPERSECRET');
});
it('re-map secret', async () => {
mockInput('secret/data/test secret | TEST_KEY');
await exportSecrets();
expect(core.exportVariable).toBeCalledWith('TEST_KEY', 'SUPERSECRET');
});
it('get nested secret', async () => {
mockInput(`secret/data/nested/test "other-Secret-dash"`);
await exportSecrets();
expect(core.exportVariable).toBeCalledWith('OTHERSECRETDASH', 'OTHERSUPERSECRET');
});
it('get multiple secrets', async () => {
mockInput(`
secret/data/test secret ;
secret/data/test secret | NAMED_SECRET ;
secret/data/nested/test "other-Secret-dash" ;`);
await exportSecrets();
expect(core.exportVariable).toBeCalledTimes(3);
expect(core.exportVariable).toBeCalledWith('SECRET', 'SUPERSECRET');
expect(core.exportVariable).toBeCalledWith('NAMED_SECRET', 'SUPERSECRET');
expect(core.exportVariable).toBeCalledWith('OTHERSECRETDASH', 'OTHERSUPERSECRET');
});
it('get wildcard secrets with dot char', async () => {
mockInput(`secret/data/test-with-dot-char * ;`);
await exportSecrets();
expect(core.exportVariable).toBeCalledTimes(1);
expect(core.exportVariable).toBeCalledWith('SECRET__FOO', 'SUPERSECRET');
});
it('get wildcard secrets', async () => {
mockInput(`secret/data/test * ;`);
await exportSecrets();
expect(core.exportVariable).toBeCalledTimes(1);
expect(core.exportVariable).toBeCalledWith('SECRET', 'SUPERSECRET');
});
it('get wildcard secrets with name prefix', async () => {
mockInput(`secret/data/test * | GROUP_ ;`);
await exportSecrets();
expect(core.exportVariable).toBeCalledTimes(1);
expect(core.exportVariable).toBeCalledWith('GROUP_SECRET', 'SUPERSECRET');
});
it('leading slash kvv2', async () => {
mockInput('/secret/data/foobar fookv2');
await exportSecrets();
expect(core.exportVariable).toBeCalledWith('FOOKV2', 'bar');
});
it('get secret from K/V v1', async () => {
mockInput('secret-kv1/test secret');
await exportSecrets();
expect(core.exportVariable).toBeCalledWith('SECRET', 'CUSTOMSECRET');
});
it('get nested secret from K/V v1', async () => {
mockInput('secret-kv1/nested/test "other-Secret-dash"');
await exportSecrets();
expect(core.exportVariable).toBeCalledWith('OTHERSECRETDASH', 'OTHERCUSTOMSECRET');
});
it('get K/V v1 wildcard secrets', async () => {
mockInput(`secret-kv1/test * ;`);
await exportSecrets();
expect(core.exportVariable).toBeCalledTimes(1);
expect(core.exportVariable).toBeCalledWith('SECRET', 'CUSTOMSECRET');
});
it('get K/V v1 wildcard secrets with name prefix', async () => {
mockInput(`secret-kv1/test * | GROUP_ ;`);
await exportSecrets();
expect(core.exportVariable).toBeCalledTimes(1);
expect(core.exportVariable).toBeCalledWith('GROUP_SECRET', 'CUSTOMSECRET');
});
it('get wildcard nested secret from K/V v1', async () => {
mockInput('secret-kv1/nested/test *');
await exportSecrets();
expect(core.exportVariable).toBeCalledWith('OTHERSECRETDASH', 'OTHERCUSTOMSECRET');
});
it('leading slash kvv1', async () => {
mockInput('/secret-kv1/foobar fookv1');
await exportSecrets();
expect(core.exportVariable).toBeCalledWith('FOOKV1', 'bar');
});
describe('generic engines', () => {
beforeAll(async () => {
await got(`${vaultUrl}/v1/cubbyhole/test`, {
method: 'POST',
headers: {
'X-Vault-Token': vaultToken,
},
json: {
foo: "bar",
zip: "zap"
},
});
});
it('supports cubbyhole', async () => {
mockInput('/cubbyhole/test foo');
await exportSecrets();
expect(core.exportVariable).toBeCalledWith('FOO', 'bar');
});
it('wildcard supports cubbyhole', async () => {
mockInput('/cubbyhole/test *');
await exportSecrets();
expect(core.exportVariable).toBeCalledTimes(2);
expect(core.exportVariable).toBeCalledWith('FOO', 'bar');
expect(core.exportVariable).toBeCalledWith('ZIP', 'zap');
});
it('caches responses', async () => {
mockInput(`
/cubbyhole/test foo ;
/cubbyhole/test zip`);
await exportSecrets();
expect(core.debug).toBeCalledWith(' using cached response');
expect(core.exportVariable).toBeCalledWith('FOO', 'bar');
expect(core.exportVariable).toBeCalledWith('ZIP', 'zap');
});
})
});