diff --git a/CHANGELOG.md b/CHANGELOG.md index de29729..6b7777a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [v6.0.0](2024-03-19) + +### Added +- Supports AWS_REGION env var, with default fallback as `us-east-1` + +### Fixed +- Dependencies updated and vulnerability in `"es6-weak-map": "^2.0.3"` removed + +### Removed +- Dropped support for NodeJS `<18.18` +- `direnv` tool from tool-versions and `.envrc` file, redundant for linking node module binaries + ## [v5.3.1](2022-05-16) + ### Fixed - using `-m` when there's no missing secrets doesn't crash anymore diff --git a/README.md b/README.md index 674c968..42dcdd0 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ Options: -s, --stage [stage] Specify stage to run on. (required) -c, --config [config] Path to oprah configuration (default: "oprah.yml") -i, --interactive specify values through command line + -r, --removing [removing] Removing orphan configs or secrets (default: false) -h, --help display help for command Commands: @@ -197,6 +198,17 @@ Options: -h, --help display help for command ``` +### Examples + +Sample of current usage: + +#### Fetching individual values + +[BFF](https://github.com/ACloudGuru/school/blob/212fcc9fc983d6efb49b2a7c28ff0854ebb631c1/backend/services/bff/bin/push-schema#L54) +``` +export APOLLO_KEY=$(yarn --silent oprah fetch -k ENGINE_API_KEY -s "$ACG_ENV" | jq -er ".ENGINE_API_KEY") +``` + ### License Feel free to use the code, it's released using the MIT license. @@ -209,3 +221,9 @@ Feel free to use the code, it's released using the MIT license. [npm-url]: https://www.npmjs.com/package/oprah [codacy-image]: https://api.codacy.com/project/badge/Grade/6464d14b26214357ba838d2cdbdfcb8e [codacy-url]: https://www.codacy.com/app/subash.adhikari/oprah?utm_source=github.com&utm_medium=referral&utm_content=ACloudGuru/oprah&utm_campaign=Badge_Grade + +## TODO: + +- [ ] Remove init method - does nothing but validate providers, can be done in CLI definition +- [ ] Refactor for latest AWS SDK +- [ ] Set AWS SDK as peer dependency diff --git a/bin/oprah b/bin/oprah index e7f0cf5..8f59a63 100755 --- a/bin/oprah +++ b/bin/oprah @@ -3,16 +3,17 @@ const chalk = require('chalk'); const program = require('commander'); -const pjson = require('../package.json'); +const { version } = require('../package.json'); const { makeOprah } = require('../lib/make-oprah'); const { logError, log } = require('../lib/utils/logger'); let oprahPromise = null; program - .version(pjson.version) + .version(version) .option('-s, --stage [stage]', 'Specify stage to run on. (required)') - .option('-c, --config [config]', 'Path to oprah configuration', 'oprah.yml'); + .option('-c, --config [config]', 'Path to oprah configuration', 'oprah.yml') + .option('--region [region]', 'AWS region to use (default: us-east-1)'); program .command('run') @@ -23,31 +24,43 @@ program ) .option('-i, --interactive', 'Run on interactive mode') .option('-m, --missing', 'Only prompt missing values in interactive mode') - .option('-r, --removing [removing]', 'Removing orphan configs or secrets') - .action(({ interactive, variables, missing, removing = false }) => { - let parsedVariables = {}; - - try { - if (variables) { - parsedVariables = JSON.parse(variables); + .option( + '-r, --removing [removing]', + 'Removing orphan configs or secrets (default: false)' + ) + .action( + ({ + interactive, + variables, + missing, + removing = false, + region = 'us-east-1' + }) => { + let parsedVariables = {}; + + try { + if (variables) { + parsedVariables = JSON.parse(variables); + } + } catch (error) { + logError(`Variables must be in JSON format!! ${error.message}.`); + program.help(); } - } catch (error) { - logError(`Variables must be in JSON format!! ${error.message}.`); - program.help(); - } - const { stage, config } = program.opts(); + const { stage, config } = program.opts(); - const params = { - stage, - interactive, - missingOnly: missing, - config, - variables: parsedVariables - }; + const params = { + stage, + interactive, + missingOnly: missing, + config, + variables: parsedVariables, + region + }; - oprahPromise = makeOprah(params).run({ removing }); - }); + oprahPromise = makeOprah(params).run({ removing }); + } + ); program .command('init') @@ -82,8 +95,8 @@ program ) .option('-C, --config-only [configOnly]', 'Only export configs') .action(({ path, target, configOnly = false }) => { - const { stage, config } = program.opts(); - oprahPromise = makeOprah({ stage, config }).export( + const { stage, config, region } = program.opts(); + oprahPromise = makeOprah({ stage, config, region }).export( path || (target === 'env' ? '.env_oprah' : '/tmp/oprah-exports.json'), target || 'json', configOnly @@ -100,8 +113,8 @@ program 'The location of the secrets and configuration file (default: "/tmp/oprah-exports.json")' ) .action(({ path }) => { - const { stage, config } = program.opts(); - oprahPromise = makeOprah({ stage, config }).import( + const { stage, config, region } = program.opts(); + oprahPromise = makeOprah({ stage, config, region }).import( path || '/tmp/oprah-exports.json' ); }); @@ -110,8 +123,8 @@ program .command('list') .description('List all remote configurations and secrets.') .action(() => { - const { stage, config } = program.opts(); - oprahPromise = makeOprah({ stage, config }).list(); + const { stage, config, region } = program.opts(); + oprahPromise = makeOprah({ stage, config, region }).list(); }); program @@ -119,11 +132,11 @@ program .description('Fetch config or secret') .option( '-k, --keys [keys]', - 'Comma seperated configs to fetch (example: "SOME_CONFIG,ANOTHER_CONFIG")' + 'Comma separated configs to fetch (example: "SOME_CONFIG,ANOTHER_CONFIG")' ) .action(({ keys }) => { - const { stage, config } = program.opts(); - oprahPromise = makeOprah({ stage, config }).fetch({ + const { stage, config, region } = program.opts(); + oprahPromise = makeOprah({ stage, config, region }).fetch({ keys: keys.split(',') }); }); @@ -133,15 +146,14 @@ program .description('Cleaning up orphan configs or secrets') .option('-d, --dry-run [dryRun]', 'Execute a dry run') .action(({ dryRun }) => { - const { stage, config } = program.opts(); - oprahPromise = makeOprah({ stage, config }).cleanUp({ + const { stage, config, region } = program.opts(); + oprahPromise = makeOprah({ stage, config, region }).cleanUp({ dryRun }); }); function displayHelpAndExit() { program.help(); - process.exit(1); } program.on('command:*', () => { diff --git a/lib/services/parameter-store/stores/ssm/make-delete-parameters.js b/lib/services/parameter-store/stores/ssm/make-delete-parameters.js new file mode 100644 index 0000000..ec9dc67 --- /dev/null +++ b/lib/services/parameter-store/stores/ssm/make-delete-parameters.js @@ -0,0 +1,15 @@ +const chunk = require('lodash/chunk'); + +const makeDeleteParameters = ({ ssm }) => ({ parameterNames }) => { + const chunks = chunk(parameterNames, 10); + const promises = chunks.map(chunkedParameterNames => + ssm + .deleteParameters({ + Names: chunkedParameterNames + }) + .promise() + ); + return Promise.all(promises); +}; + +module.exports = { makeDeleteParameters }; diff --git a/lib/services/parameter-store/stores/ssm/make-ssm-client.js b/lib/services/parameter-store/stores/ssm/make-ssm-client.js new file mode 100644 index 0000000..1388c19 --- /dev/null +++ b/lib/services/parameter-store/stores/ssm/make-ssm-client.js @@ -0,0 +1,10 @@ +const AWS = require('aws-sdk'); + +const makeSsmClient = ({ region }) => { + AWS.config.update({ region }); + return new AWS.SSM(); +}; + +module.exports = { + makeSsmClient +};