Skip to content

Commit

Permalink
chore: add configuration to show or hide secret values
Browse files Browse the repository at this point in the history
  • Loading branch information
danteay committed Nov 1, 2023
1 parent 4ce1ca4 commit e63a253
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 20 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ jobs:
secret_name: <secret-name>
json_file_path: path/to/json/secrets.json
dry_run: true # Default false
show_values: false # If true secret values will be displayed on action logs (default false)
exclude: '^_' # Regular expression that excludes the matching keys to be synced (default '^_')
```
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ inputs:
description: "Dry run mode (preview changes without modifying the secret)"
required: false
default: "false"
show_values:
description: "Dry run mode (preview changes without modifying the secret)"
required: false
default: "false"
exclude:
description: "List of regular expressions that determines if a secret key should be excluded from sync"
required: false
Expand Down
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ const getAction = () => {
core.getInput("secret_name"),
core.getInput("json_file_path"),
core.getInput("exclude"),
core.getBooleanInput("show_values"),
);
};

const run = async () => {
try {
const dryRun = core.getInput("dry_run") === "true";
const dryRun = core.getBooleanInput("dry_run");

const changeSet = await getAction().run();

Expand Down
27 changes: 19 additions & 8 deletions src/action/Action.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import fs from "fs";
import lodash from "lodash";

import SecretsManager from "../secrets-manager/SecretsManager.js";
import ChangeSet from "./ChangeSet.js";
Expand All @@ -14,21 +13,32 @@ export default class Action {
/**
* Creates a new Action instance.
*
* @param {string} keyId - The AWS access key ID.
* @param {string} secretKey - The AWS secret access key.
* @param {string} region - The AWS region.
* @param {string} secretName - The name of the secret in AWS Secrets Manager.
* @param {string} jsonFile - The path to the JSON file containing the new secret values.
* @param {string} skipPattern - A list of regular expressions that eval keys of the json file and if match,
* @param {string} keyId The AWS access key ID.
* @param {string} secretKey The AWS secret access key.
* @param {string} region The AWS region.
* @param {string} secretName The name of the secret in AWS Secrets Manager.
* @param {string} jsonFile The path to the JSON file containing the new secret values.
* @param {string} skipPattern A regular expression that eval keys of the json file and if match,
* that key should be omitted
* @param {string} showValues If this flag is set to true all secret values will be displayed on logs,
* if false, a place holder will be displayed.
*
* @throws {Error} Throws an error if any required parameter is missing or if the JSON file doesn't exist.
*/
constructor(keyId, secretKey, region, secretName, jsonFile, skipPattern) {
constructor(
keyId,
secretKey,
region,
secretName,
jsonFile,
skipPattern,
showValues = false,
) {
this.#validateData(keyId, secretKey, region, secretName, jsonFile);

this.jsonFile = jsonFile;
this.skipPattern = skipPattern || defaultSkipPattern;
this.showValues = showValues;

this.smClient = new SecretsManager(keyId, secretKey, region, secretName);
}
Expand All @@ -47,6 +57,7 @@ export default class Action {
newSecretData,
existingSecretData,
this.skipPattern,
this.showValues,
);
}

Expand Down
36 changes: 29 additions & 7 deletions src/action/ChangeSet.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import core from "@actions/core";
import lodash from "lodash";
import chalk from "chalk";

Expand All @@ -9,6 +8,7 @@ const skipTag = chalk.yellow("[SKIP]");
const addedTag = chalk.green("[ADDED]");
const changedTag = chalk.magenta("[CHANGED]");
const removedTag = chalk.red("[REMOVED]");
const valPlaceholder = "**********";

/**
* ChangeSet is a class that represents a set of changes to be applied to secrets in AWS Secrets Manager.
Expand Down Expand Up @@ -39,19 +39,33 @@ export default class ChangeSet {
*/
#skipPattern;

/**
* A flag to unhide secret values on log messages
* @type {boolean}
*/
#showValues;

/**
* Creates a new ChangeSet instance.
*
* @param {SecretsManager} smClient - An instance of the SecretsManager class for interacting with AWS Secrets Manager.
* @param {Object} newValues - The new set of values to be applied to the secrets manager.
* @param {Object} existingValues - The existing set of values to be replaced by the new ones.
* @param {string} skipPattern - A regular expression to skip keys.
* @param {SecretsManager} smClient An instance of the SecretsManager class for interacting with AWS Secrets Manager.
* @param {Object} newValues The new set of values to be applied to the secrets manager.
* @param {Object} existingValues The existing set of values to be replaced by the new ones.
* @param {string} skipPattern A regular expression to skip keys.
* @param {boolean} showValues A flag to unhide secret values on log messages
*/
constructor(smClient, newValues, existingValues, skipPattern) {
constructor(
smClient,
newValues,
existingValues,
skipPattern,
showValues = false,
) {
this.#changeDesc = [];
this.#updatedValues = { ...existingValues };
this.#smClient = smClient;
this.#skipPattern = skipPattern || "";
this.#showValues = showValues;

this.#eval(newValues, existingValues);
}
Expand Down Expand Up @@ -128,7 +142,6 @@ export default class ChangeSet {
let exp = new RegExp(this.#skipPattern);

if (exp.test(key)) {
core.debug(`Skipping ${key} with regexp '${this.#skipPattern}'`);
return true;
}

Expand Down Expand Up @@ -160,6 +173,10 @@ export default class ChangeSet {
* @param {string} val Value that is set to the key
*/
#addedDesc(key, val) {
if (!this.#showValues) {
val = valPlaceholder;
}

this.#changeDesc.push(`${logPrefix}: ${addedTag} '${key}': '${val}'`);
}

Expand All @@ -171,6 +188,11 @@ export default class ChangeSet {
* @param {string} newVal New secret value after sync
*/
#changedDesc(key, oldVal, newVal) {
if (!this.#showValues) {
oldVal = valPlaceholder;
newVal = valPlaceholder;
}

this.#changeDesc.push(
`${logPrefix}: ${changedTag} '${key}': '${oldVal}' => '${newVal}'`,
);
Expand Down
35 changes: 31 additions & 4 deletions tests/action/ChangeSet.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { expect } from "chai";
import { expect, should } from "chai";
import sinon from "sinon";

import ChangeSet from "../../src/action/ChangeSet.js";
Expand Down Expand Up @@ -68,8 +68,8 @@ describe("ChangeSet", () => {
const descriptions = changeSet.changeDesc();

expect(descriptions).to.deep.equal([
"SecretKey: [CHANGED] 'key1': 'value1' => 'new-value1'",
"SecretKey: [CHANGED] 'key2': 'value2' => 'new-value2'",
"SecretKey: [CHANGED] 'key1': '**********' => '**********'",
"SecretKey: [CHANGED] 'key2': '**********' => '**********'",
]);
});

Expand Down Expand Up @@ -100,7 +100,9 @@ describe("ChangeSet", () => {

const descriptions = changeSet.changeDesc();

expect(descriptions).to.deep.equal(["SecretKey: [ADDED] 'key3': 'value3'"]);
expect(descriptions).to.deep.equal([
"SecretKey: [ADDED] 'key3': '**********'",
]);
});

it("should exclude keys from patterns", () => {
Expand All @@ -121,6 +123,31 @@ describe("ChangeSet", () => {

const descriptions = changeSet.changeDesc();

expect(descriptions).to.deep.equal([
"SecretKey: [SKIP] '_excluded'",
"SecretKey: [ADDED] 'key3': '**********'",
]);
});

it("should show real values on logs", () => {
const newValues = {
_excluded: "some",
key1: "value1",
key2: "value2",
key3: "value3",
};
const existingValues = { key1: "value1", key2: "value2" };

const changeSet = new ChangeSet(
secretsManagerStub,
newValues,
existingValues,
["^_"],
true,
);

const descriptions = changeSet.changeDesc();

expect(descriptions).to.deep.equal([
"SecretKey: [SKIP] '_excluded'",
"SecretKey: [ADDED] 'key3': 'value3'",
Expand Down

0 comments on commit e63a253

Please sign in to comment.