mirror of
https://github.com/hashicorp/vault-action.git
synced 2026-07-30 18:33:14 +03:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 130d1f5f4f | |||
| d34ee148bc | |||
| 77bab83f42 | |||
| 5e3dd4f01b | |||
| 7318a98db7 | |||
| b08bc4993d | |||
| 579f9fd8c2 | |||
| 1226471c04 | |||
| fdaeeffa26 | |||
| 0f409d4023 |
@@ -1,5 +1,20 @@
|
|||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
## 2.5.0 (Jan 26th, 2023)
|
||||||
|
|
||||||
|
Features:
|
||||||
|
|
||||||
|
* Adds ability to automatically decode secrets from base64, hex, and utf8 encodings. [GH-408](https://github.com/hashicorp/vault-action/pull/408)
|
||||||
|
|
||||||
|
Improvements:
|
||||||
|
|
||||||
|
* Improves error messages for Vault authentication failures [GH-409](https://github.com/hashicorp/vault-action/pull/409)
|
||||||
|
* bump jest from 28.1.1 to 29.3.1 [GH-397](https://github.com/hashicorp/vault-action/pull/397)
|
||||||
|
* bump @types/jest from 28.1.3 to 29.2.6 [GH-397](https://github.com/hashicorp/vault-action/pull/397), [GH-413](https://github.com/hashicorp/vault-action/pull/413)
|
||||||
|
* bump jsrsasign from 10.5.27 to 10.6.1 [GH-401](https://github.com/hashicorp/vault-action/pull/401)
|
||||||
|
* bump json5 from 2.2.1 to 2.2.3 [GH-404](https://github.com/hashicorp/vault-action/pull/404)
|
||||||
|
* bump minimatch from 3.0.4 to 3.1.2 [GH-410](https://github.com/hashicorp/vault-action/pull/410)
|
||||||
|
|
||||||
## 2.4.3 (Nov 8th, 2022)
|
## 2.4.3 (Nov 8th, 2022)
|
||||||
|
|
||||||
Improvements:
|
Improvements:
|
||||||
|
|||||||
@@ -76,6 +76,9 @@ inputs:
|
|||||||
description: 'Time in seconds, after which token expires'
|
description: 'Time in seconds, after which token expires'
|
||||||
required: false
|
required: false
|
||||||
default: 3600
|
default: 3600
|
||||||
|
secretEncodingType:
|
||||||
|
description: 'The encoding type of the secret to decode. If not specified, the secret will not be decoded. Supported values: base64, hex, utf8'
|
||||||
|
required: false
|
||||||
runs:
|
runs:
|
||||||
using: 'node16'
|
using: 'node16'
|
||||||
main: 'dist/index.js'
|
main: 'dist/index.js'
|
||||||
|
|||||||
Vendored
+9287
-9254
File diff suppressed because one or more lines are too long
Generated
+1222
-9812
File diff suppressed because it is too large
Load Diff
+4
-17
@@ -15,16 +15,6 @@
|
|||||||
"src/**/*",
|
"src/**/*",
|
||||||
"dist/**/*"
|
"dist/**/*"
|
||||||
],
|
],
|
||||||
"release": {
|
|
||||||
"branch": "main",
|
|
||||||
"plugins": [
|
|
||||||
"@semantic-release/commit-analyzer",
|
|
||||||
"@semantic-release/release-notes-generator",
|
|
||||||
"@semantic-release/github",
|
|
||||||
"@semantic-release/npm"
|
|
||||||
],
|
|
||||||
"ci": false
|
|
||||||
},
|
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/hashicorp/vault-action.git"
|
"url": "git+https://github.com/hashicorp/vault-action.git"
|
||||||
@@ -46,19 +36,16 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"got": "^11.8.5",
|
"got": "^11.8.5",
|
||||||
"jsonata": "^1.8.6",
|
"jsonata": "^1.8.6",
|
||||||
"jsrsasign": "^10.5.27"
|
"jsrsasign": "^10.6.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@actions/core": ">=1 <2"
|
"@actions/core": ">=1 <2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@actions/core": "^1.10.0",
|
"@actions/core": "^1.10.0",
|
||||||
"@types/got": "^9.6.11",
|
"@vercel/ncc": "^0.36.0",
|
||||||
"@types/jest": "^28.1.3",
|
"jest": "^29.3.1",
|
||||||
"@zeit/ncc": "^0.22.3",
|
|
||||||
"jest": "^28.1.1",
|
|
||||||
"jest-when": "^3.5.2",
|
"jest-when": "^3.5.2",
|
||||||
"mock-http-server": "^1.4.5",
|
"mock-http-server": "^1.4.5"
|
||||||
"semantic-release": "^19.0.5"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-2
@@ -6,6 +6,7 @@ const jsonata = require('jsonata');
|
|||||||
const { auth: { retrieveToken }, secrets: { getSecrets } } = require('./index');
|
const { auth: { retrieveToken }, secrets: { getSecrets } } = require('./index');
|
||||||
|
|
||||||
const AUTH_METHODS = ['approle', 'token', 'github', 'jwt', 'kubernetes'];
|
const AUTH_METHODS = ['approle', 'token', 'github', 'jwt', 'kubernetes'];
|
||||||
|
const ENCODING_TYPES = ['base64', 'hex', 'utf8'];
|
||||||
|
|
||||||
async function exportSecrets() {
|
async function exportSecrets() {
|
||||||
const vaultUrl = core.getInput('url', { required: true });
|
const vaultUrl = core.getInput('url', { required: true });
|
||||||
@@ -17,6 +18,8 @@ async function exportSecrets() {
|
|||||||
const secretsInput = core.getInput('secrets', { required: false });
|
const secretsInput = core.getInput('secrets', { required: false });
|
||||||
const secretRequests = parseSecretsInput(secretsInput);
|
const secretRequests = parseSecretsInput(secretsInput);
|
||||||
|
|
||||||
|
const secretEncodingType = core.getInput('secretEncodingType', { required: false });
|
||||||
|
|
||||||
const vaultMethod = (core.getInput('method', { required: false }) || 'token').toLowerCase();
|
const vaultMethod = (core.getInput('method', { required: false }) || 'token').toLowerCase();
|
||||||
const authPayload = core.getInput('authPayload', { required: false });
|
const authPayload = core.getInput('authPayload', { required: false });
|
||||||
if (!AUTH_METHODS.includes(vaultMethod) && !authPayload) {
|
if (!AUTH_METHODS.includes(vaultMethod) && !authPayload) {
|
||||||
@@ -81,11 +84,23 @@ async function exportSecrets() {
|
|||||||
|
|
||||||
const results = await getSecrets(requests, client);
|
const results = await getSecrets(requests, client);
|
||||||
|
|
||||||
|
|
||||||
for (const result of results) {
|
for (const result of results) {
|
||||||
const { value, request, cachedResponse } = result;
|
// Output the result
|
||||||
|
|
||||||
|
var value = result.value;
|
||||||
|
const request = result.request;
|
||||||
|
const cachedResponse = result.cachedResponse;
|
||||||
|
|
||||||
if (cachedResponse) {
|
if (cachedResponse) {
|
||||||
core.debug('ℹ using cached response');
|
core.debug('ℹ using cached response');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if a secret is encoded, decode it
|
||||||
|
if (ENCODING_TYPES.includes(secretEncodingType)) {
|
||||||
|
value = Buffer.from(value, secretEncodingType).toString();
|
||||||
|
}
|
||||||
|
|
||||||
for (const line of value.replace(/\r/g, '').split('\n')) {
|
for (const line of value.replace(/\r/g, '').split('\n')) {
|
||||||
if (line.length > 0) {
|
if (line.length > 0) {
|
||||||
command.issue('add-mask', line);
|
command.issue('add-mask', line);
|
||||||
@@ -99,7 +114,7 @@ async function exportSecrets() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @typedef {Object} SecretRequest
|
/** @typedef {Object} SecretRequest
|
||||||
* @property {string} path
|
* @property {string} path
|
||||||
* @property {string} envVarName
|
* @property {string} envVarName
|
||||||
* @property {string} outputVarName
|
* @property {string} outputVarName
|
||||||
|
|||||||
@@ -184,6 +184,12 @@ describe('exportSecrets', () => {
|
|||||||
.mockReturnValueOnce(doExport);
|
.mockReturnValueOnce(doExport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mockEncodeType(doEncode) {
|
||||||
|
when(core.getInput)
|
||||||
|
.calledWith('secretEncodingType', expect.anything())
|
||||||
|
.mockReturnValueOnce(doEncode);
|
||||||
|
}
|
||||||
|
|
||||||
it('simple secret retrieval', async () => {
|
it('simple secret retrieval', async () => {
|
||||||
mockInput('test key');
|
mockInput('test key');
|
||||||
mockVaultData({
|
mockVaultData({
|
||||||
@@ -196,6 +202,19 @@ describe('exportSecrets', () => {
|
|||||||
expect(core.setOutput).toBeCalledWith('key', '1');
|
expect(core.setOutput).toBeCalledWith('key', '1');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('encoded secret retrieval', async () => {
|
||||||
|
mockInput('test key');
|
||||||
|
mockVaultData({
|
||||||
|
key: 'MQ=='
|
||||||
|
});
|
||||||
|
mockEncodeType('base64');
|
||||||
|
|
||||||
|
await exportSecrets();
|
||||||
|
|
||||||
|
expect(core.exportVariable).toBeCalledWith('KEY', '1');
|
||||||
|
expect(core.setOutput).toBeCalledWith('key', '1');
|
||||||
|
});
|
||||||
|
|
||||||
it('intl secret retrieval', async () => {
|
it('intl secret retrieval', async () => {
|
||||||
mockInput('测试 测试');
|
mockInput('测试 测试');
|
||||||
mockVaultData({
|
mockVaultData({
|
||||||
|
|||||||
+11
-1
@@ -2,6 +2,7 @@
|
|||||||
const core = require('@actions/core');
|
const core = require('@actions/core');
|
||||||
const rsasign = require('jsrsasign');
|
const rsasign = require('jsrsasign');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
const { default: got } = require('got');
|
||||||
|
|
||||||
const defaultKubernetesTokenPath = '/var/run/secrets/kubernetes.io/serviceaccount/token'
|
const defaultKubernetesTokenPath = '/var/run/secrets/kubernetes.io/serviceaccount/token'
|
||||||
/***
|
/***
|
||||||
@@ -109,7 +110,16 @@ async function getClientToken(client, method, path, payload) {
|
|||||||
core.debug(`Retrieving Vault Token from v1/auth/${path}/login endpoint`);
|
core.debug(`Retrieving Vault Token from v1/auth/${path}/login endpoint`);
|
||||||
|
|
||||||
/** @type {import('got').Response<VaultLoginResponse>} */
|
/** @type {import('got').Response<VaultLoginResponse>} */
|
||||||
const response = await client.post(`v1/auth/${path}/login`, options);
|
let response;
|
||||||
|
try {
|
||||||
|
response = await client.post(`v1/auth/${path}/login`, options);
|
||||||
|
} catch (err) {
|
||||||
|
if (err instanceof got.HTTPError) {
|
||||||
|
throw Error(`failed to retrieve vault token. code: ${err.code}, message: ${err.message}, vaultResponse: ${JSON.stringify(err.response.body)}`)
|
||||||
|
} else {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
if (response && response.body && response.body.auth && response.body.auth.client_token) {
|
if (response && response.body && response.body.auth && response.body.auth.client_token) {
|
||||||
core.debug('✔ Vault Token successfully retrieved');
|
core.debug('✔ Vault Token successfully retrieved');
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user