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 -t 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)}.`)