Skip to content

Commit

Permalink
refactor(sre-secrets): enhance typing (#61)
Browse files Browse the repository at this point in the history

Co-authored-by: Renovate Bot <bot@renovateapp.com>
  • Loading branch information
douglasduteil and renovate-bot committed Jul 23, 2021
1 parent ed27ee9 commit 4724b16
Show file tree
Hide file tree
Showing 26 changed files with 1,726 additions and 552 deletions.
13 changes: 13 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Editor configuration, see http://editorconfig.org
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
max_line_length = off
trim_trailing_whitespace = false
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
"devDependencies": {
"lerna": "^4.0.0"
},
"resolutions": {
"jest": "26.6.0"
},
"scripts": {
"lint": "lerna run --parallel --stream lint",
"test": "lerna run --parallel --stream test",
"build": "lerna run --parallel --stream build",
"test-coverage": "lerna run --parallel --stream test-coverage"
},
"resolutions": {
"jest": "27.0.6",
"@typescript-eslint/typescript-estree": "4.28.4",
"@babel/plugin-transform-modules-commonjs": "7.14.5"
}
}
2 changes: 1 addition & 1 deletion packages/azure-db/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
"yaml": "^1.10.2"
},
"devDependencies": {
"jest": "^26.6.3"
"jest": "^27.0.6"
}
}
2 changes: 1 addition & 1 deletion packages/k8strip/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
],
"license": "MIT",
"devDependencies": {
"jest": "^26.6.3"
"jest": "^27.0.6"
},
"dependencies": {
"ajv": "^8.6.2",
Expand Down
5 changes: 4 additions & 1 deletion packages/sre-seal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@socialgouv/sre-seal",
"version": "1.8.1",
"preferGlobal": true,
"main": "./src",
"main": "./src/index.js",
"bin": {
"sre-seal": "bin/index.js"
},
Expand All @@ -15,5 +15,8 @@
"pipe-args": "^1.3.0",
"yaml": "^1.10.2",
"yargs": "^15.4.1"
},
"devDependencies": {
"@kubernetes-models/sealed-secrets": "^1.6.3"
}
}
12 changes: 12 additions & 0 deletions packages/sre-seal/src/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ISealedSecret } from "@kubernetes-models/sealed-secrets/bitnami.com/v1alpha1/SealedSecret";

export interface Options {
context: string;
namespace: string;
name: string;
secrets: Record<string, string>;
}

export function createSealedSecret(options: Options): Promise<ISealSecret>;
export function crypt(options: Omit<Options, secrets>): Promise<string>;
export function cryptFromSecrets(options: Options): Promise<ISealSecret>;
2 changes: 2 additions & 0 deletions packages/sre-secrets/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
dist
3 changes: 0 additions & 3 deletions packages/sre-secrets/.eslintrc.json

This file was deleted.

8 changes: 8 additions & 0 deletions packages/sre-secrets/.eslintrc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
root: true
overrides:
- files: "*.js"
extends:
- "@socialgouv/eslint-config-recommended"
- files: "*.ts"
extends:
- "@socialgouv/eslint-config-typescript"
61 changes: 34 additions & 27 deletions packages/sre-secrets/__tests__/index.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,49 @@
const fs = require("fs")
const util = require("util")
const yaml = require("js-yaml")
const exec = util.promisify(require("child_process").exec)
import { readFileSync } from "fs";
import { load } from "js-yaml";
import { directory } from "tempy";

import { main } from "../src/index";

describe("Test sealed secrets generation", () => {
const filePath = "./__tests__/data/.secrets.yaml"
const folderPath = `${process.env.RUNNER_TEMP || "/tmp"}/sre-secrets`
const filePath = "./__tests__/data/.secrets.yaml";
const folderPath = directory({ prefix: "sre-secrets" });
const matchers = {
spec: {
encryptedData: {
toto: expect.any(String),
tata: expect.any(String),
toto: expect.any(String),
},
},
}
};

test("Generate sealed secrets", async () => {
const cmd = `node ./dist/index.js --from=${filePath} --to=${folderPath}`
const { stdout, stderr } = await exec(cmd)
if (stdout) console.log("stdout:", stdout)
if (stderr) console.log("stderr:", stderr)
})
beforeAll(async () => {
await main({
fromPath: filePath,
toPath: folderPath,
});
// HACK(douglasduteil): ensure EOL after logs
// We might want to remove all spinner logs in the future
process.stdout.write("\n");
await new Promise((resolve) => {
setTimeout(resolve, 500);
});
});

test("Check dev snapshot", () => {
const path = `${folderPath}/environments/dev/app.sealed-secret.yaml`
const content = yaml.safeLoad(fs.readFileSync(path, "utf8"))
expect(content).toMatchSnapshot(matchers)
})
const path = `${folderPath}/environments/dev/app.sealed-secret.yaml`;
const content = load(readFileSync(path, "utf8"));
expect(content).toMatchSnapshot(matchers);
});

test("Check preprod snapshot", () => {
const path = `${folderPath}/environments/preprod/app.sealed-secret.yaml`
const content = yaml.safeLoad(fs.readFileSync(path, "utf8"))
expect(content).toMatchSnapshot(matchers)
})
const path = `${folderPath}/environments/preprod/app.sealed-secret.yaml`;
const content = load(readFileSync(path, "utf8"));
expect(content).toMatchSnapshot(matchers);
});

test("Check prod snapshot", () => {
const path = `${folderPath}/environments/prod/app-prod.sealed-secret.yaml`
const content = yaml.safeLoad(fs.readFileSync(path, "utf8"))
expect(content).toMatchSnapshot(matchers)
})
})
const path = `${folderPath}/environments/prod/app-prod.sealed-secret.yaml`;
const content = load(readFileSync(path, "utf8"));
expect(content).toMatchSnapshot(matchers);
});
});
7 changes: 7 additions & 0 deletions packages/sre-secrets/__tests__/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "../tsconfig.json",
"compilerOptions": {
"types": ["jest", "node"]
}
}
42 changes: 31 additions & 11 deletions packages/sre-secrets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"preferGlobal": true,
"main": "./src",
"bin": {
"sre-secrets": "dist/index.js"
"sre-secrets": "dist/bin/sre-secrets.js"
},
"files": [
"dist"
Expand All @@ -14,26 +14,46 @@
},
"scripts": {
"start": "tsc -w",
"build": "tsc -p .",
"build": "tsc -p src",
"test": "jest",
"lint": "eslint .",
"test-coverage": "jest --coverage --coverageReporters=lcov --coverageReporters=text-summary"
},
"dependencies": {
"@socialgouv/sre-seal": "^1.8.1",
"chalk": "^4.1.0",
"js-yaml": "^3.14.1",
"chalk": "^4.1.1",
"js-yaml": "^4.1.0",
"ora": "^5.4.1",
"yargs": "^16.2.0"
"yargs": "^17.0.1"
},
"devDependencies": {
"@socialgouv/eslint-config-recommended": "^1.75.0",
"@types/jest": "^26.0.20",
"@types/node": "^14.17.5",
"@types/yargs": "^15.0.13",
"@babel/core": "^7.14.8",
"@babel/plugin-transform-modules-commonjs": "^7.14.5",
"@babel/preset-typescript": "^7.14.5",
"@socialgouv/eslint-config-typescript": "^1.82.0",
"@tsconfig/node14": "^1.0.1",
"@types/jest": "^26.0.24",
"@types/js-yaml": "^4.0.2",
"@types/node": "^16.4.1",
"@types/yargs": "^17.0.2",
"eslint": "^7.31.0",
"jest": "^26.6.3",
"jest": "^27.0.6",
"prettier": "^2.3.2",
"ts-jest": "^26.5.6",
"tempy": "^1.0.1",
"typescript": "^4.3.5"
},
"babel": {
"env": {
"test": {
"presets": [
"@babel/preset-typescript"
],
"plugins": [
[
"@babel/plugin-transform-modules-commonjs"
]
]
}
}
}
}
16 changes: 16 additions & 0 deletions packages/sre-secrets/src/bin/sre-secrets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env node

import { main } from "../index";
import spinner from "../spinner";
import yargs from "../yargs";

Promise.resolve()
.then(async () => {
const { f: fromPath, t: toPath } = await yargs.parse();
await main({ fromPath, toPath });
process.exit(0);
})
.catch((error) => {
spinner.fail(error);
process.exit(1);
});
118 changes: 63 additions & 55 deletions packages/sre-secrets/src/environments.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,73 @@
import yargs from "./yargs"
import spinner from "./spinner"
import { safeDump } from "js-yaml"
import seal, { Config } from "./seal"
import { yellow, green } from "chalk"
import { mkdirSync, writeFileSync } from "fs"
import { cryptFromSecrets } from "@socialgouv/sre-seal";
import { green, yellow } from "chalk";
import { mkdirSync, writeFileSync } from "fs";
import { dump } from "js-yaml";

const { argv } = yargs
const baseName = "sealed-secret"
const folderPath = argv.t || "./.k8s"
import type { ServiceEnvironment } from "./services";
import spinner from "./spinner";

const processEnvironment = async (
namespace,
serviceName,
environmentName,
{ fileName, secretsName, secrets }
) => {
const config: Config = {
secrets,
namespace: namespace,
name: secretsName || `${serviceName}-${baseName}`,
context: environmentName === "prod" ? "prod2" : "dev2",
}
const baseName = "sealed-secret";

const sealed = await seal(config)
const processEnvironment =
({ toPath }: { toPath: string }) =>
async (
namespace: string,
serviceName: string,
environmentName: string,
{ fileName, secretsName, secrets }: ServiceEnvironment
) => {
const context = environmentName === "prod" ? "prod2" : "dev2";
const name = secretsName ?? `${serviceName}-${baseName}`;
const sealed = await cryptFromSecrets({
context,
name,
namespace,
secrets,
});

mkdirSync(`${folderPath}/environments/${environmentName}`, {
recursive: true,
})
mkdirSync(`${toPath}/environments/${environmentName}`, {
recursive: true,
});

writeFileSync(
`${folderPath}/environments/${environmentName}/${
fileName || serviceName
}.${baseName}.yaml`,
safeDump(sealed, { noRefs: true })
)
}
writeFileSync(
`${toPath}/environments/${environmentName}/${
fileName ?? serviceName
}.${baseName}.yaml`,
dump(sealed, { noRefs: true })
);
};

export const processEnvironments = async (
namespace,
serviceName,
environments
) => {
const environmentNames = Object.keys(environments)
export const processEnvironments =
({ toPath }: { toPath: string }) =>
async (
namespace: string,
serviceName: string,
environments: Record<string, ServiceEnvironment>
): Promise<void> => {
const environmentNames = Object.keys(environments);

for (const environmentName of environmentNames) {
spinner.start(
`creating ${yellow(serviceName)} sealed secrets for ${yellow(
environmentName
)}`
)
for (const environmentName of environmentNames) {
spinner.start(
`creating ${yellow(serviceName)} sealed secrets for ${yellow(
environmentName
)}`
);

const config = environments[environmentName]
const config = environments[environmentName];

await processEnvironment(namespace, serviceName, environmentName, config)
await processEnvironment({ toPath })(
namespace,
serviceName,
environmentName,
config
);

spinner.succeed(
`${green(serviceName)} sealed secrets created for ${green(
environmentName
)} environment (${folderPath}/environments/${environmentName}/${
config?.fileName || serviceName
}.${baseName}.yaml)`
)
}
}
spinner.succeed(
`${green(serviceName)} sealed secrets created for ${green(
environmentName
)} environment (${toPath}/environments/${environmentName}/${
config.fileName ?? serviceName
}.${baseName}.yaml)`
);
}
};

0 comments on commit 4724b16

Please sign in to comment.