nixos/tools/onboard-machine.js
2023-12-11 18:18:41 -05:00

71 lines
1.9 KiB
JavaScript

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