import { dirname, resolve, relative } from "path"; import { parseDocument, stringify } from "yaml"; const [, script, name, host] = process.argv; const sopsFilePath = resolve(dirname(script), "../.sops.yaml"); const sopsFile = await Bun.file(sopsFilePath).text(); const sopsConfig = parseDocument(sopsFile); // // STEP 1: Get the remote key, convert to age key // const remoteKeyProc = Bun.spawn(`ssh-keyscan -qt ed25519 ${host}`.split(" "), { stderr: null, }); const sshToAgeProc = Bun.spawn(["ssh-to-age"], { stdin: await new Response(remoteKeyProc.stdout).arrayBuffer(), }); const ageKey = (await new Response(sshToAgeProc.stdout).text()).trim(); // // STEP 2: Add to keys // const keysNode = sopsConfig.get("keys"); let keys = keysNode.items; // remove keynode if it exists keys = keys.filter((i) => i.anchor !== `m_${name}`); // create the new key node const newNode = sopsConfig.createNode(ageKey); newNode.anchor = `m_${name}`; keys = [...keys, newNode]; keysNode.items = keys; sopsConfig.set("keys", keysNode); // // STEP 3: Add machine to creation_rules // const pathRegex = `secrets/${name}/[^/]+\\.(yaml|json|env|ini)$`; const opsAnchors = keys .filter((i) => i.anchor.startsWith("op_")) .map((i) => sopsConfig.createAlias(i)); //console.log({opsAnchors}) const creationRuleTemplate = { path_regex: pathRegex, key_groups: [ { age: [...opsAnchors, sopsConfig.createAlias(newNode)], }, ], }; // Remove old creation_rules entry const creationRules = sopsConfig .get("creation_rules") .items.filter((i) => i.get("path_regex") !== pathRegex); const creationRulesNode = sopsConfig.createNode(creationRules); creationRulesNode.add(creationRuleTemplate); sopsConfig.set("creation_rules", creationRulesNode); await Bun.write(sopsFilePath, sopsConfig.toString()); console.log( `Finished. Added ${name} with key ${ageKey} to ${relative( dirname(script), sopsFilePath )}.` );