[FEATURE] Working Prototype

This commit is contained in:
dunemask 2023-11-05 17:41:45 -07:00
parent 2a191ec913
commit 70168074dc
2 changed files with 94 additions and 47 deletions

View file

@ -4,39 +4,49 @@ import rls from "readline-sync";
const configFilePath = `${os.homedir()}/.infisical-env.config.json`; const configFilePath = `${os.homedir()}/.infisical-env.config.json`;
const configTemplate = { const configTemplate = {
projects: [], projects: [
storeTokens: false, {
infisicalInstance: "https://app.infisical.com" name: "proj1",
environments: [
{
slug: "prod",
envar: "INFISICAL_PROJ1_PROD_READ_TOKEN",
paths: ["/", "/database"],
},
],
},
],
storeTokens: false,
infisicalInstance: "https://app.infisical.com",
};
export function loadConfig() {
return JSON.parse(fs.readFileSync(configFilePath));
} }
export function loadConfig(){ export function upsertConfig() {
return JSON.parse(fs.readFileSync(configFilePath)); if (fs.existsSync(configFilePath)) return;
generateConfig();
} }
export function upsertConfig(){ export function writeConfig(overrides) {
if(fs.existsSync(configFilePath)) return; const config = { ...configTemplate, ...overrides };
generateConfig(); fs.writeFileSync(configFilePath, JSON.stringify(config));
} }
export function writeConfig(overrides){ export function generateConfig() {
const config = {...configTemplate, ...overrides}; const url = rls.question("Infisical Instance: ");
fs.writeFileSync(configFilePath, JSON.stringify(config)); const store = rls.keyInYNStrict("Store Tokens? (Will Be Unencrypted)");
} const projectOptions = ["Add Project", "Exit"];
const envOptions = ["Add Environment", "Exit"];
export function generateConfig(){ const pathOptions = ["Add Path", "Exit"];
const url = rls.question("Infisical Instance: "); var opt;
const store = rls.keyInYNStrict("Store Tokens? (Will Be Unencrypted)"); projLoop: while (1) {
const projectOptions = ["Add Project", "Exit"];
const envOptions = ["Add Environment", "Exit"];
const pathOptions = ["Add Path", "Exit"];
var opt;
projLoop: while(1){
opt = rls.keyInSelect(projectOptions, "Select");
if(opt !== 1) break projLoop;
envLoop: while(1){
opt = rls.keyInSelect(projectOptions, "Select"); opt = rls.keyInSelect(projectOptions, "Select");
} if (opt !== 1) break projLoop;
} envLoop: while (1) {
console.log({infisicalInstance: url, storeTokens: store}); opt = rls.keyInSelect(projectOptions, "Select");
}
}
console.log({ infisicalInstance: url, storeTokens: store });
} }

View file

@ -2,7 +2,7 @@ import fs from "node:fs";
import os from "node:os"; import os from "node:os";
import InfisicalClient from "infisical-node"; import InfisicalClient from "infisical-node";
import rls from "readline-sync"; import rls from "readline-sync";
import {loadConfig, upsertConfig} from "./configurator.js"; import { loadConfig, upsertConfig } from "./configurator.js";
const envpath = `${os.homedir()}/.env`; const envpath = `${os.homedir()}/.env`;
//upsertConfig(); //TODO Build Configuration Generator //upsertConfig(); //TODO Build Configuration Generator
const config = loadConfig(); const config = loadConfig();
@ -12,29 +12,66 @@ const siteURL = config.infisicalInstance;
const projects = config.projects; const projects = config.projects;
const pendingSecrets = []; const pendingSecrets = [];
async function getProjectSecrets(project, environment, token, path="/", includeImports=true){ async function getProjectSecrets(
const client = new InfisicalClient({token, siteURL}); project,
const secrets = await client.getAllSecrets({environment, path, includeImports, attachToProcessEnv: false}); environment,
return secrets.map((s)=>({...s, project, path})) token,
path = "/",
includeImports = true,
) {
const client = new InfisicalClient({ token, siteURL });
const secrets = await client.getAllSecrets({
environment,
path,
includeImports,
attachToProcessEnv: false,
});
return secrets.map((s) => ({ ...s, project, path }));
} }
function mapToFile(secrets, filename){ function mapToFile(proj, secrets) {
const envSecrets = secrets.map((s)=>`export ${s.secretName}=${s.secretValue}`).join("\n"); const filename = `infisical-autoenv-${proj}`;
fs.writeFileSync(`${envpath}/${filename}`, envSecrets); const date = new Date();
const dateString =
date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
const paths = Object.keys(secrets);
const lines = paths.map(
(p) =>
`# ---${p}--- ${dateString}\n` +
secrets[p]
.map((s) => `export ${s.secretName}=${s.secretValue}`)
.join("\n"),
);
const fileData = lines.join("\n");
fs.writeFileSync(`${envpath}/${filename}`, fileData);
} }
for(var p of projects){ for (var p of projects) {
for(var e of p.environments){ for (var e of p.environments) {
if(!process.env[e.envar]) throw Error(`${e.envar} could not be found!`); if (!process.env[e.envar]) throw Error(`${e.envar} could not be found!`);
for(var path of e.paths){ for (var path of e.paths) {
pendingSecrets.push(getProjectSecrets(p.name, e.slug, process.env[e.envar], path)); pendingSecrets.push(
} getProjectSecrets(p.name, e.slug, process.env[e.envar], path),
} );
}
}
} }
const loadedSecrets = await Promise.all(pendingSecrets) const loadedSecrets = await Promise.all(pendingSecrets);
const filteredSecrets = loadedSecrets.flat(2).filter((s)=>!s.isFallback); const filteredSecrets = loadedSecrets.flat(2).filter((s) => !s.isFallback);
console.log(filteredSecrets);
const proj = projects.map((p) => ({
name: p.name,
paths: p.environments.map((envs) => envs.paths).flat(2),
}));
const projectSecrets = {};
for (var p of proj) {
projectSecrets[p.name] = {};
for (var path of p.paths) {
projectSecrets[p.name][path] = filteredSecrets.filter(
(s) => s.project === p.name && s.path === path,
);
}
mapToFile(p.name, projectSecrets[p.name]);
}