Last active 1 month ago

Revision 9cf2b45809c9abfa3ed2eece010ee750b0555988

deploy-host.nix Raw
1(writeNuBin "deploy"
2 {
3 makeWrapperArgs = [
4 "--prefix"
5 "PATH"
6 ":"
7 (lib.makeBinPath (
8 with pkgs;
9 [
10 sops
11 git
12 ssh-to-age
13 nixos-anywhere
14 openssh
15 ]
16 ))
17 ];
18 }
19 # nu
20 ''
21 def main [host: string, ip: string, ...args: string]: nothing -> nothing {
22 # Work on raw YAML text for anchors
23 let raw = open --raw .sops.yaml
24
25 let anchor = $"host_($host)"
26 if not ($raw | str contains $"&($anchor)") {
27 error make $"Host anchor ($anchor) not found in .sops.yaml"
28 }
29
30 let old_age_key = $raw
31 | parse --regex $"&($anchor) \(?<key>age[0-9a-z]+\)"
32 | get key.0
33 if ($old_age_key | is-empty) {
34 error make $"Failed to extract old age key for ($anchor)"
35 }
36
37 # Create temp dir
38 let tempdir = mktemp -d
39 let ssh_dir = ($tempdir)/etc/ssh
40 mkdir $ssh_dir
41
42 let rsa_key = $"($ssh_dir)/ssh_host_rsa_key"
43 let ed25519_key = $"($ssh_dir)/ssh_host_ed25519_key"
44
45 ssh-keygen -t rsa -b 4096 -f $rsa_key -N "" -C $host
46 ssh-keygen -t ed25519 -f $ed25519_key -N "" -C $host
47
48 let age_pub = open --raw $"($ed25519_key).pub" | ssh-to-age
49
50 # Replace anchor in raw YAML
51 $raw
52 | str replace -r $"&($anchor) age[0-9a-z]+" $"&($anchor) ($age_pub)"
53 | save --force .sops.yaml
54
55 print $"Updated .sops.yaml for ($host)"
56
57 let git_files = git ls-files | lines
58
59 (open .sops.yaml).creation_rules
60 | where {|rule|
61 $rule.key_groups | any {|kg|
62 $kg.age | any {|k| $k == $age_pub }
63 }
64 }
65 | get path_regex
66 | par-each {|regex| $git_files | where {|f| $f =~ $regex } }
67 | flatten
68 | uniq
69 | each {|file_to_reencrypt|
70 print $"Re-encrypting ($file_to_reencrypt)"
71 sops updatekeys $file_to_reencrypt
72 print # needed so that updatekeys output is shown
73 }
74
75 nixos-anywhere --flake $".#($host)" --target-host $"root@($ip)" --extra-files $tempdir ...$args
76
77 # Remove lingering temp directory.
78 # We only care about the successful case because
79 # failing means the keys won't be used anyway
80 rm -rf $tempdir
81 }
82 ''
83)