Skip to content

Commit

Permalink
feat: more options to run command
Browse files Browse the repository at this point in the history
  • Loading branch information
kyle-ruan authored and patrickshiel committed Aug 27, 2021
1 parent d2278ce commit be290f5
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 25 deletions.
16 changes: 14 additions & 2 deletions bin/oprah
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ program
)
.option('-i, --interactive', 'Run on interactive mode')
.option('-m, --missing', 'Only prompt missing values in interactive mode')
.action(({ interactive, variables, missing }) => {
.option('-cu, --cleaning-up [cleanUp]', 'Clean up orphan configs or secrets')
.action(({ interactive, variables, missing, cleanUp = false }) => {
let parsedVariables = {};

try {
Expand All @@ -45,7 +46,7 @@ program
variables: parsedVariables
};

oprahPromise = makeOprah(params).run();
oprahPromise = makeOprah(params).run({ deleting: cleanUp });
});

program
Expand Down Expand Up @@ -116,6 +117,17 @@ program
});
});

program
.command('clean-up')
.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({
dryRun
});
});

function displayHelpAndExit() {
program.help();
process.exit(1);
Expand Down
42 changes: 33 additions & 9 deletions lib/commands/cleanup/make-cleanup.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
const get = require('lodash/get');
const property = require('lodash/property');
const { get, property, isEmpty } = require('lodash');
const chalk = require('chalk');
const { log } = require('../../utils/logger');

const makeCleanup = ({ parameterStore, settingsService }) => async () => {
const maskValue = value => {
const stringToMask = value || '';
return stringToMask.replace(/\S(?=\S{4})/g, '*');
};

const makeCleanup = ({ parameterStore, settingsService }) => async (
{ dryRun } = { dryRun: false }
) => {
const settings = await settingsService.getSettings();
const configPath = get(settings, 'config.path');
const secretPath = get(settings, 'secret.path');
Expand All @@ -15,12 +23,28 @@ const makeCleanup = ({ parameterStore, settingsService }) => async () => {
({ Name }) => ![...configParameters, ...secretParameters].includes(Name)
);

return (
unusedParameters.length &&
parameterStore.deleteParameters({
parameterNames: unusedParameters.map(property('Name'))
})
);
if (isEmpty(unusedParameters)) {
log(chalk.gray('Cleanup --> No unused parameters'));
return Promise.resolve();
}

if (dryRun) {
log(chalk.gray('Cleanup --> Parameters to be deleted: '));
return unusedParameters.map(({ Name, Value, Type }) => {
const shouldMask = Type === 'SecureString';
return log(
chalk.gray(
`Cleanup --> Name: ${Name} | Value: [${
shouldMask ? maskValue(Value) : Value
}]`
)
);
});
}

return parameterStore.deleteParameters({
parameterNames: unusedParameters.map(property('Name'))
});
};

module.exports = { makeCleanup };
83 changes: 82 additions & 1 deletion lib/commands/cleanup/make-cleanup.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ describe('cleanup', () => {
config: path.resolve(__dirname, '../../../mocks/ssm-provider.yml')
});

beforeEach(() => {
jest.clearAllMocks();
});
it('should delete unused parameters', async () => {
mockGetAllParameters.mockResolvedValueOnce([
{
Expand Down Expand Up @@ -69,7 +72,7 @@ describe('cleanup', () => {
]);
mockDeleteParameters.mockResolvedValue({});

await oprah.cleanup();
await oprah.cleanUp({ dryRun: false });
expect.assertions(4);
expect(mockGetAllParameters.mock.calls.length).toEqual(2);
expect(mockGetAllParameters.mock.calls[0][0].path).toEqual('/test/config');
Expand All @@ -78,4 +81,82 @@ describe('cleanup', () => {
'/test/config/THREE'
]);
});

it('should not call delete parameters if no unused parameters', async () => {
mockGetAllParameters.mockResolvedValueOnce([
{
Name: '/test/config/ONE',
Type: 'String',
Value: '3200',
Version: 1,
DataType: 'text'
},
{
Name: '/test/config/TWO',
Type: 'String',
Value: 'my-database',
Version: 1,
DataType: 'text'
}
]);
mockGetAllParameters.mockResolvedValueOnce([
{
Name: '/test/secret/FOUR',
Type: 'String',
Value: 'disabled',
Version: 1,
DataType: 'text'
}
]);
mockDeleteParameters.mockResolvedValue({});

await oprah.cleanUp({ dryRun: false });
expect.assertions(4);
expect(mockGetAllParameters.mock.calls.length).toEqual(2);
expect(mockGetAllParameters.mock.calls[0][0].path).toEqual('/test/config');
expect(mockGetAllParameters.mock.calls[1][0].path).toEqual('/test/secret');
expect(mockDeleteParameters.mock.calls.length).toEqual(0);
});
it("should not delete unused parameters if it's a dry run", async () => {
mockGetAllParameters.mockResolvedValueOnce([
{
Name: '/test/config/ONE',
Type: 'String',
Value: '3200',
Version: 1,
DataType: 'text'
},
{
Name: '/test/config/TWO',
Type: 'String',
Value: 'my-database',
Version: 1,
DataType: 'text'
},
{
Name: '/test/config/THREE',
Type: 'String',
Value: 'test-table',
Version: 1,
DataType: 'text'
}
]);
mockGetAllParameters.mockResolvedValueOnce([
{
Name: '/test/secret/FOUR',
Type: 'String',
Value: 'disabled',
Version: 1,
DataType: 'text'
}
]);
mockDeleteParameters.mockResolvedValue({});

await oprah.cleanUp({ dryRun: true });
expect.assertions(4);
expect(mockGetAllParameters.mock.calls.length).toEqual(2);
expect(mockGetAllParameters.mock.calls[0][0].path).toEqual('/test/config');
expect(mockGetAllParameters.mock.calls[1][0].path).toEqual('/test/secret');
expect(mockDeleteParameters.mock.calls.length).toEqual(0);
});
});
7 changes: 6 additions & 1 deletion lib/commands/run/make-run.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
const makeRun = ({ init, configure }) => () => init().then(configure);
const makeRun = ({ init, configure, cleanUp }) => (
{ deleting } = { deleting: false }
) =>
init()
.then(configure)
.then(() => deleting && cleanUp());

module.exports = { makeRun };
26 changes: 21 additions & 5 deletions lib/commands/run/make-run.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,30 @@ const { makeRun } = require('./make-run');

const mockInit = jest.fn(() => Promise.resolve({}));
const mockConfigure = jest.fn(() => Promise.resolve({}));
const mockCleanUp = jest.fn(() => Promise.resolve({}));

describe('#makeRun', () => {
it('should call both init and configure method', () => {
const run = makeRun({ init: mockInit, configure: mockConfigure });
const run = makeRun({
init: mockInit,
configure: mockConfigure,
cleanUp: mockCleanUp
});

beforeEach(() => {
jest.clearAllMocks();
});

return run().then(() => {
it('should call init, configuration but not cleanUp if deleting is not required', () =>
run({ deleting: false }).then(() => {
expect(mockInit).toHaveBeenCalledTimes(1);
expect(mockConfigure).toHaveBeenCalledTimes(1);
});
});
expect(mockCleanUp).not.toHaveBeenCalled();
}));

it('should call init, configuration and cleanUp if deleting is required', () =>
run({ deleting: true }).then(() => {
expect(mockInit).toHaveBeenCalledTimes(1);
expect(mockConfigure).toHaveBeenCalledTimes(1);
expect(mockCleanUp).toHaveBeenCalledTimes(1);
}));
});
6 changes: 4 additions & 2 deletions lib/make-oprah.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,17 @@ const makeOprah = ({

const init = makeInit({ settingsService, cfService });

const cleanUp = makeCleanup({ parameterStore, settingsService });

return {
configure,
init,
run: makeRun({ init, configure }),
run: makeRun({ init, configure, cleanUp }),
list: makeList({ settingsService, parameterStore }),
export: makeExport({ settingsService, parameterStore }),
import: makeImport({ settingsService, parameterStore }),
fetch: makeFetch({ parameterStore, settingsService }),
cleanup: makeCleanup({ parameterStore, settingsService })
cleanUp
};
};

Expand Down
4 changes: 2 additions & 2 deletions lib/services/parameter-store/make-delete-parameters.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ const { log } = require('../../utils/logger');
const makeDeleteParameters = ({ getProviderStore }) => async ({
parameterNames
}) => {
log(chalk.gray(`Deleting unused parameters...`));
log(chalk.gray(`Cleanup --> Deleting unused parameters...`));
const providerStore = await getProviderStore();

return providerStore
.deleteParameters({ parameterNames })
.then(() => log(chalk.gray('Parameters deleted')));
.then(() => log(chalk.gray('Cleanup --> All orphan parameters deleted')));
};

module.exports = { makeDeleteParameters };
2 changes: 0 additions & 2 deletions lib/services/parameter-store/make-get-all-parameters.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
const { sortParameters } = require('./sort-parameters');

const makeGetAllParameters = ({ getProviderStore }) => async ({ path }) => {
if (!path) {
throw new Error('Missing path!');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ const getParametersByPathRecursively = async params => {
const getAllParametersByPath = async ({ path }) => {
const allParameters = await getParametersByPathRecursively({
Path: path,
Recursive: true
Recursive: true,
WithDecryption: true
});

return allParameters;
Expand Down

0 comments on commit be290f5

Please sign in to comment.