From 6b827e56b128deb8c14b2a01bcbc539b3ff60d1f Mon Sep 17 00:00:00 2001 From: Tom Hubrecht Date: Wed, 21 Feb 2024 17:18:14 +0100 Subject: [PATCH] feat(infra): Init backups --- machines/compute01/_configuration.nix | 1 + machines/compute01/hedgedoc.nix | 2 + machines/compute01/secrets/bupstash-put_key | Bin 0 -> 2319 bytes machines/compute01/secrets/secrets.nix | 1 + machines/compute01/vaultwarden.nix | 2 + machines/geo01/_configuration.nix | 1 + machines/geo02/_configuration.nix | 1 + machines/storage01/_configuration.nix | 1 + modules/default.nix | 2 + modules/dgn-backups/default.nix | 125 ++++++++++++++++++++ 10 files changed, 136 insertions(+) create mode 100644 machines/compute01/secrets/bupstash-put_key create mode 100644 modules/dgn-backups/default.nix diff --git a/machines/compute01/_configuration.nix b/machines/compute01/_configuration.nix index e260728..15d723e 100644 --- a/machines/compute01/_configuration.nix +++ b/machines/compute01/_configuration.nix @@ -3,6 +3,7 @@ lib.extra.mkConfig { enabledModules = [ # List of modules to enable + "dgn-backups" "dgn-fail2ban" "dgn-web" ]; diff --git a/machines/compute01/hedgedoc.nix b/machines/compute01/hedgedoc.nix index abd466b..4bd0d5c 100644 --- a/machines/compute01/hedgedoc.nix +++ b/machines/compute01/hedgedoc.nix @@ -57,4 +57,6 @@ in "hedgedoc" "hedgedoc/uploads" ]; + + dgn-backups.jobs.hedgedoc.settings.paths = [ "/var/lib/hedgedoc" ]; } diff --git a/machines/compute01/secrets/bupstash-put_key b/machines/compute01/secrets/bupstash-put_key new file mode 100644 index 0000000000000000000000000000000000000000..3ea951548d3b4e09d32c5f504b23d16279f54e0b GIT binary patch literal 2319 zcmZXU{hQN-0ml{Ot$-je58k0z228XZNt?83<_$^PG)K3V1<2qmkJlpK&R=KooISL-`cJ$BdaUAm>Sz5^Zs&msk0m=BEpms+0gSWEOX_m?jWPO{=2@M~eHVLlh;eU#cPgT80Wd9{>y%TR1^c zA`L`BO57le42Oqop^yku9Gb!sI>jzo!WBdolZ@(TIX>lr-8Qqs-ohFLfp(b7A#J zHCn@vG9@d16I1t^G}&a46boF)Np`5rn4&7^K%z15M_NgV>2sy9ouYLWoQNTL72{iA zoOc!_L?N;im|?++EoLqUal)*m6`0^tpps1(;Tlf+LS!HdNvy?C$l;m}0=<-=)*>}( zKpcY>!m`CCg5^*t$=eH3lvG(J5eZk&s;UGGd>UuML4a_JEmdPcu4ikAjw)NztS_Ff zmZeMt7OY;<41hd?c;!$e1P8c)R0)NUh#ge%j2DS`c@uzEtt`npI9x%cjwc zX!ZksyR&E{QBOcjiaf)yw2cugRy-Qanl&28n$1?mJOw1-tP}0LD}ac6IKYT3TcZ_hr`K| zVh@Cak(7gTU^)|9qBy`;t&r(zowCL#U?57az-Hqj1SA6roI^F#l#SP5{B9b^pvb^V zGInFcDkS-eT>;=ip2YG(Jnc5JZmXur{-Vv9^{Pfl1w{zfc`_cE^f+izD_2^4X-qPt z@&etW80mC57;>AvajMFzcFqf7chlTN4e<>;00x7Q6LbU!yQ>n6r2}ZHm@G=1V0Xer z2Wx?VARzk`gOtZ~fFl}=D@I%@)?iaTLhvD1oh=h)DG4|cFT=(L>fuLBBxv>CO*020 zh=}lmdCqGSC@SHl?A0Qvb;&Wx&hB1GyOh&8XEitpN6RwlR1kj7_UUiqBWdIC%LdcNmuwnB_9zKB23qD-8SF+Ge6ATboIc9b)9X` zLpSH#yJ#OvO>4U+wGN9-TV*=1;L$Btb{$+avTt?A+|hBXdm~xse?FP&>)SeSB;U07 zgY)AbpVP}w6RywNJ$U0(cd>ukZ{NG;#+28^)SzWQtX;8U{hrq5+cReWQnDP(-d^=O zH)-?Y^RJvr+<55p0}n1dN6bnN`}51e(`{=;O&2aD-Xv!H zs@)rg?cBR1x>&yU*;@1KBekA4MxTjYxsbtk-1_*VQ-5F3^O<|Y)Cu7Bhlxv%joIH_ zc;w5MUb>?lxWxW(?CJ0e-_lQRtM~tV+~^@I-{|U|TC6>Te!t;`73{_3$6pzio*z4} z=Z4w2%FoB%*-JO-%QUuUyq#_YFD=zUW%;9Wf-?+5W}M!}l6?j5(NX>wu08KDVm*FB7Ne zZcV<{armkJ)(NfqR(8&~-bhLNKHbf{F!bxwZ4>LIxl0Fq)5U!9spsL3Tz++~y_$*0jDwqBOT zJyHApw_Wg=$k@&!;O2{~CzSfH8vEGEKU?$db;GJq=TXen(fSW)E-QR``Kv~^&aQQR z?i#do{pOcWIaYLzS}3jk*SohKwBNV&tr>s1`RIpPG`L0F|1^1q(E5{2bhg>+>c)l>^-S?Wu z4V^Y?t={C_a@epBQ9|HWe$*ZaH|KACa?dwAXPzizr89{D_&9d19{wSHwb_jX&? z8x1F)L^A!azMU=%S(VsvSm^!g>E9e5-n_J@`^4?Z);ZAO-plKnCy#u8(PItt-lF&A z#uKkT!JePHY4NYuef`m~rhm58qF0wSpS#)d%_jX(D6gj=J++y2+HGtWG+7iheU-r9nV+a?^{({QcOHK`t6G+rAq{r}W~eZ2qx literal 0 HcmV?d00001 diff --git a/machines/compute01/secrets/secrets.nix b/machines/compute01/secrets/secrets.nix index 3264fab..2b057cc 100644 --- a/machines/compute01/secrets/secrets.nix +++ b/machines/compute01/secrets/secrets.nix @@ -4,6 +4,7 @@ let in lib.setDefault { inherit publicKeys; } [ + "bupstash-put_key" "ds-fr-secret_file" "grafana-smtp_password_file" "grafana-oauth_client_secret_file" diff --git a/machines/compute01/vaultwarden.nix b/machines/compute01/vaultwarden.nix index 0f9c25b..abc2f47 100644 --- a/machines/compute01/vaultwarden.nix +++ b/machines/compute01/vaultwarden.nix @@ -71,4 +71,6 @@ in ]; }; }; + + dgn-backups.jobs.vaultwarden.settings.paths = [ "/var/lib/bitwarden_rs" ]; } diff --git a/machines/geo01/_configuration.nix b/machines/geo01/_configuration.nix index 8f2a118..92482e7 100644 --- a/machines/geo01/_configuration.nix +++ b/machines/geo01/_configuration.nix @@ -3,6 +3,7 @@ lib.extra.mkConfig { enabledModules = [ # List of modules to enable + "dgn-backups" ]; enabledServices = [ diff --git a/machines/geo02/_configuration.nix b/machines/geo02/_configuration.nix index 8f2a118..92482e7 100644 --- a/machines/geo02/_configuration.nix +++ b/machines/geo02/_configuration.nix @@ -3,6 +3,7 @@ lib.extra.mkConfig { enabledModules = [ # List of modules to enable + "dgn-backups" ]; enabledServices = [ diff --git a/machines/storage01/_configuration.nix b/machines/storage01/_configuration.nix index 241238b..a3d257f 100644 --- a/machines/storage01/_configuration.nix +++ b/machines/storage01/_configuration.nix @@ -3,6 +3,7 @@ lib.extra.mkConfig { enabledModules = [ # List of modules to enable + "dgn-backups" "dgn-fail2ban" "dgn-web" ]; diff --git a/modules/default.nix b/modules/default.nix index cb364e1..df7b033 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -39,6 +39,7 @@ (lib.extra.mkImports ./. [ "dgn-access-control" "dgn-acme" + "dgn-backups" "dgn-console" "dgn-fail2ban" "dgn-hardware" @@ -55,5 +56,6 @@ "age-secrets" "services/crabfit" "services/forgejo-nix-runners" + "services/bupstash" ]); } diff --git a/modules/dgn-backups/default.nix b/modules/dgn-backups/default.nix new file mode 100644 index 0000000..b306bf8 --- /dev/null +++ b/modules/dgn-backups/default.nix @@ -0,0 +1,125 @@ +{ + config, + lib, + name, + ... +}: + +let + inherit (lib) mkEnableOption mkOption remove; + + inherit (lib.types) + attrs + attrsOf + listOf + str + submodule + ; + + cfg = config.dgn-backups; + + homes = { + compute01 = "/data/slow/bupstash"; + geo01 = "/data/bupstash"; + geo02 = "/data/bupstash"; + storage01 = "/data/slow/bupstash"; + }; + + starts = { + compute01 = "*-*-* *:28:00"; + }; + + mkJobs = builtins.mapAttrs ( + _: + { to, settings }: + { + startAt = starts.${name}; + key = config.age.secrets."bupstash-put_key".path; + repositoryCommands = + lib.extra.mapSingleFuse (host: "ssh -i /etc/ssh/ssh_host_ed25519_key bupstash-repo@${host}.dgnum") + to; + } + // settings + ); + + mkPgJobs = lib.extra.mapFuse (db: { "pg-${db}" = { }; }); +in + +{ + options.dgn-backups = { + enable = mkEnableOption "DGNum backup service."; + + pgDumps = mkOption { + type = listOf str; + default = [ ]; + description = '' + List of postgres databases to dump into bupstash. + ''; + }; + + jobs = mkOption { + type = attrsOf ( + submodule { + options = { + to = mkOption { + type = listOf str; + default = remove name [ + "compute01" + "geo01" + "geo02" + "storage01" + ]; + description = "Hosts to send the backups to."; + }; + + settings = mkOption { + type = attrs; + default = { }; + description = "Base bupstash job config."; + }; + }; + } + ); + default = { }; + description = "List of bupstash jobs."; + }; + }; + + config = { + services.bupstash = { + repositories = { + inherit (cfg) enable; + + home = homes.${name}; + + access = [ + { + repo = "default"; + keys = lib.extra.getAllKeys ( + # Nodes allowed to create backups + builtins.map (host: "machines/${host}") [ + "compute01" + "storage01" + "vault01" + "web01" + ] + ); + allowed = [ "put" ]; + } + ]; + }; + + jobs = (mkPgJobs cfg.pgDumps) // (mkJobs cfg.jobs); + }; + + programs.ssh.knownHosts = + lib.extra.mapFuse + (host: { "${host}.dgnum".publicKey = builtins.head (lib.extra.getKeys "machines/${host}"); }) + [ + "compute01" + "geo01" + "geo02" + "storage01" + ]; + }; +}