UNPKG

@usebruno/cli

Version:

With Bruno CLI, you can now run your API collections with ease using simple command line commands.

158 lines (148 loc) 4.69 kB
const debug = require('debug'); const nodeVaultDebug = debug('node-vault'); const axios = require('axios'); const { getOptions } = require('./bru'); const options = getOptions(); const verbose = options?.['verbose']; if (verbose) { debug.enable('node-vault'); } const getExternalSecretsData = async ({ type, config, paths, debug }) => { var vault = require('node-vault')({ apiVersion: 'v1', debug: debug ? nodeVaultDebug : null }); let secretsData; if (type == 'vault') { if (config?.type == 'vault-server') { if (config?.vaultServerConfig?.auth?.method == 'token') { vault.endpoint = config?.vaultServerConfig?.url; if (config?.vaultServerConfig?.namespace?.length) { vault.namespace = config?.vaultServerConfig?.namespace; } vault.token = config?.vaultServerConfig?.auth?.token; secretsData = await fetchExternalSecrets({ vault, paths }); } else if (config?.vaultServerConfig?.auth?.method == 'app_role') { vault.endpoint = config?.vaultServerConfig?.url; if (config?.vaultServerConfig?.namespace?.length) { vault.namespace = config?.vaultServerConfig?.namespace; } const accessToken = await getVaultServerApproleToken({ vault, options: config?.vaultServerConfig?.auth?.appRole }); vault.token = accessToken; secretsData = await fetchExternalSecrets({ vault, paths }); } } else if (config?.type == 'vault-cloud') { if ( config?.vaultCloudConfig?.auth?.method == 'client_credentials' && config?.vaultCloudConfig?.auth?.clientCredentials && config?.vaultCloudConfig?.project ) { const accessToken = await getVaultCloudToken({ options: config?.vaultCloudConfig?.auth?.clientCredentials }); secretsData = await Promise.all( paths.map((path) => getVaultCloudSecrets({ options: { ...config?.vaultCloudConfig?.auth?.clientCredentials, ...config?.vaultCloudConfig?.project }, accessToken, path }) ) ); } } } return secretsData; }; const fetchExternalSecrets = async ({ paths, vault }) => { return Promise.all( paths.map( (path) => new Promise(async (resolve, reject) => { let data, error; await vault .read(path) .then((res) => { let data = res?.data?.data || res?.data || data; resolve({ path, data }); }) .catch((e) => { let error = e?.response?.body; resolve({ path, error }); }); }) ) ); }; const getVaultCloudToken = async ({ options }) => { const { tokenEndpoint, clientId, clientSecret } = options; return await axios .post( tokenEndpoint, { grant_type: 'client_credentials', client_id: clientId, client_secret: clientSecret, audience: 'https://api.hashicorp.cloud' }, { headers: { check: 'again', 'Content-Type': 'application/x-www-form-urlencoded' } } ) .then((response) => { return response?.data?.access_token; }) .catch((error) => { throw new Error(error?.response?.data?.error); }); }; const getVaultCloudSecrets = async ({ options, accessToken, path }) => { const { secretsEndpoint, organizationId, projectId } = options; if (!organizationId || !projectId) { return { path, data: {} }; } const appName = path.split('/')?.[0]; const secrets = await axios .get(`${secretsEndpoint}/organizations/${organizationId}/projects/${projectId}/apps/${appName}/open`, { headers: { check: 'again', Authorization: `Bearer ${accessToken}` } }) .then((response) => { return response.data.secrets; }) .catch((error) => { return null; }); return { path, data: secrets?.reduce((acc, s) => { return { ...acc, [s?.name]: s?.version?.value }; }, {}) }; }; const getVaultServerApproleToken = async ({ vault, options }) => { const { role, roleId, secretId } = options; return await vault .approleLogin({ role, role_id: roleId, secret_id: secretId }) .then((res) => { return res?.auth?.client_token; }) .catch((e) => { throw new Error( JSON.stringify(e?.response?.body || e?.message || 'Error while getting token from approle login') ); }); }; module.exports = { getExternalSecretsData, fetchExternalSecrets, getVaultCloudToken, getVaultCloudSecrets, getVaultServerApproleToken };