From 038083bece33bd8fe2528f45c322ac5b8afbd8c5 Mon Sep 17 00:00:00 2001 From: Pablo Ovelleiro Corral Date: Mon, 13 Jan 2025 22:38:13 +0100 Subject: [PATCH] Migrate borgbackup module to vars --- checks/backups/flake-module.nix | 7 ++--- checks/borgbackup/default.nix | 7 +++-- clanModules/borgbackup/roles/client.nix | 29 ++++++++++--------- clanModules/borgbackup/roles/server.nix | 7 +++-- flake.lock | 23 ++++++++------- flake.nix | 2 +- .../clanCore/vars/secret/sops/default.nix | 8 ++--- pkgs/clan-cli/clan_cli/vars/prompt.py | 2 +- pkgs/clan-cli/tests/test_modules.py | 24 ++++++++++++--- 9 files changed, 64 insertions(+), 45 deletions(-) diff --git a/checks/backups/flake-module.nix b/checks/backups/flake-module.nix index a46f2c0aa..c94fac5a8 100644 --- a/checks/backups/flake-module.nix +++ b/checks/backups/flake-module.nix @@ -62,14 +62,14 @@ user = "root"; }; }; - "/etc/secrets/borgbackup.ssh" = { + "/etc/secrets/borgbackup/borgbackup.ssh" = { C.argument = "${../lib/ssh/privkey}"; z = { mode = "0400"; user = "root"; }; }; - "/etc/secrets/borgbackup.repokey" = { + "/etc/secrets/borgbackup/borgbackup.repokey" = { C.argument = builtins.toString (pkgs.writeText "repokey" "repokey12345"); z = { mode = "0400"; @@ -78,8 +78,7 @@ }; }; clan.core.facts.secretStore = "vm"; - # TODO: set this backend as well, once we have implemented it. - #clan.core.vars.settings.secretStore = "vm"; + clan.core.vars.settings.secretStore = "vm"; environment.systemPackages = [ self.packages.${pkgs.system}.clan-cli ]; environment.etc.install-closure.source = "${closureInfo}/store-paths"; diff --git a/checks/borgbackup/default.nix b/checks/borgbackup/default.nix index c3b3fb9f9..142b16f31 100644 --- a/checks/borgbackup/default.nix +++ b/checks/borgbackup/default.nix @@ -21,14 +21,14 @@ clan.core.state.testState.folders = [ "/etc/state" ]; environment.etc.state.text = "hello world"; systemd.tmpfiles.settings."vmsecrets" = { - "/etc/secrets/borgbackup.ssh" = { + "/etc/secrets/borgbackup/borgbackup.ssh" = { C.argument = "${../lib/ssh/privkey}"; z = { mode = "0400"; user = "root"; }; }; - "/etc/secrets/borgbackup.repokey" = { + "/etc/secrets/borgbackup/borgbackup.repokey" = { C.argument = builtins.toString (pkgs.writeText "repokey" "repokey12345"); z = { mode = "0400"; @@ -36,7 +36,8 @@ }; }; }; - clan.core.facts.secretStore = "vm"; + # clan.core.facts.secretStore = "vm"; + clan.core.vars.settings.secretStore = "vm"; clan.borgbackup.destinations.test.repo = "borg@localhost:."; } diff --git a/clanModules/borgbackup/roles/client.nix b/clanModules/borgbackup/roles/client.nix index 1a8e14d6a..35b022c28 100644 --- a/clanModules/borgbackup/roles/client.nix +++ b/clanModules/borgbackup/roles/client.nix @@ -63,9 +63,9 @@ in rsh = lib.mkOption { type = lib.types.str; default = "ssh -i ${ - config.clan.core.facts.services.borgbackup.secret."borgbackup.ssh".path + config.clan.core.vars.generators.borgbackup.files."borgbackup.ssh".path } -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=Yes"; - defaultText = "ssh -i \${config.clan.core.facts.services.borgbackup.secret.\"borgbackup.ssh\".path} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"; + defaultText = "ssh -i \${config.clan.core.vars.generators.borgbackup.files.\"borgbackup.ssh\".path} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"; description = "the rsh to use for the backup"; }; }; @@ -126,7 +126,7 @@ in encryption = { mode = "repokey"; - passCommand = "cat ${config.clan.core.facts.services.borgbackup.secret."borgbackup.repokey".path}"; + passCommand = "cat ${config.clan.core.vars.generators.borgbackup.files."borgbackup.repokey".path}"; }; prune.keep = { @@ -177,20 +177,21 @@ in }) ]; - # Facts generation. So the client can authenticate to the server - clan.core.facts.services.borgbackup = { - public."borgbackup.ssh.pub" = { }; - secret."borgbackup.ssh" = { }; - secret."borgbackup.repokey" = { }; - generator.path = [ - pkgs.openssh + clan.core.vars.generators.borgbackup = { + + files."borgbackup.ssh.pub".secret = false; + files."borgbackup.ssh" = { }; + files."borgbackup.repokey" = { }; + + migrateFact = "borgbackup"; + runtimeInputs = [ pkgs.coreutils + pkgs.openssh pkgs.xkcdpass ]; - generator.script = '' - ssh-keygen -t ed25519 -N "" -f "$secrets"/borgbackup.ssh - mv "$secrets"/borgbackup.ssh.pub "$facts"/borgbackup.ssh.pub - xkcdpass -n 4 -d - > "$secrets"/borgbackup.repokey + script = '' + ssh-keygen -t ed25519 -N "" -f $out/borgbackup.ssh + xkcdpass -n 4 -d - > $out/borgbackup.repokey ''; }; diff --git a/clanModules/borgbackup/roles/server.nix b/clanModules/borgbackup/roles/server.nix index cb510ad29..a68551866 100644 --- a/clanModules/borgbackup/roles/server.nix +++ b/clanModules/borgbackup/roles/server.nix @@ -1,7 +1,7 @@ { config, lib, ... }: let dir = config.clan.core.settings.directory; - machineDir = dir + "/machines/"; + machineDir = dir + "/vars/per-machine/"; machineName = config.clan.core.settings.machine.name; # Instances might be empty, if the module is not used via the inventory @@ -33,7 +33,8 @@ in }; config.services.borgbackup.repos = let - borgbackupIpMachinePath = machines: machineDir + machines + "/facts/borgbackup.ssh.pub"; + borgbackupIpMachinePath = machine: machineDir + machine + "/borgbackup/borgbackup.ssh.pub/value"; + machinesMaybeKey = builtins.map ( machine: let @@ -44,7 +45,7 @@ in else lib.warn '' Machine ${machine} does not have a borgbackup key at ${fullPath}, - run `clan facts generate ${machine}` to generate it. + run `clan var generate ${machine}` to generate it. '' null ) allClients; diff --git a/flake.lock b/flake.lock index 1b2189bb3..8aa599fc8 100644 --- a/flake.lock +++ b/flake.lock @@ -42,11 +42,11 @@ }, "nixos-facter-modules": { "locked": { - "lastModified": 1734596637, - "narHash": "sha256-MRqwVAe3gsb88u4ME1UidmZFVCx+FEnoob0zkpO9DMY=", + "lastModified": 1736931726, + "narHash": "sha256-aY55yiifyo1XPPpbpH0kWlV1g2dNGBlx6622b7OK8ks=", "owner": "numtide", "repo": "nixos-facter-modules", - "rev": "536472754982bf03079b4b4e0261838a760587c0", + "rev": "fa11d87b61b2163efbb9aed7b7a5ae0299e5ab9c", "type": "github" }, "original": { @@ -57,11 +57,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1736657626, - "narHash": "sha256-FWlPMUzp0lkQBdhKlPqtQdqmp+/C+1MBiEytaYfrCTY=", + "lastModified": 1736881310, + "narHash": "sha256-5BlVeikKoJVrUXBdr1kSrcRQ8o20Kl+ZU2pEzpE5sUw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "2f9e2f85cb14a46410a1399aa9ea7ecf433e422e", + "rev": "733994ea06585b76621073160e87b0bfac7fc5ae", "type": "github" }, "original": { @@ -89,15 +89,16 @@ ] }, "locked": { - "lastModified": 1736515725, - "narHash": "sha256-4P99yL8vGehwzytkpP87eklBePt6aqeEC5JFsIzhfUs=", - "owner": "Mic92", + "lastModified": 1736953253, + "narHash": "sha256-shJxzy7qypjq9hpETQ3gJsBZXO5E3KR0INca/xwiVp4=", + "owner": "pinpox", "repo": "sops-nix", - "rev": "f214c1b76c347a4e9c8fb68c73d4293a6820d125", + "rev": "a7c6e64401b6dde13c0de90230cb64087c9d9693", "type": "github" }, "original": { - "owner": "Mic92", + "owner": "pinpox", + "ref": "lazy-assertions", "repo": "sops-nix", "type": "github" } diff --git a/flake.nix b/flake.nix index 37091c8e9..902ba1e03 100644 --- a/flake.nix +++ b/flake.nix @@ -12,7 +12,7 @@ nixos-facter-modules.url = "github:numtide/nixos-facter-modules"; - sops-nix.url = "github:Mic92/sops-nix"; + sops-nix.url = "github:pinpox/sops-nix/lazy-assertions"; sops-nix.inputs.nixpkgs.follows = "nixpkgs"; systems.url = "github:nix-systems/default"; diff --git a/nixosModules/clanCore/vars/secret/sops/default.nix b/nixosModules/clanCore/vars/secret/sops/default.nix index b05c91be1..06d0c88de 100644 --- a/nixosModules/clanCore/vars/secret/sops/default.nix +++ b/nixosModules/clanCore/vars/secret/sops/default.nix @@ -6,8 +6,6 @@ }: let - inherit (lib) flip; - inherit (import ./funcs.nix { inherit lib; }) collectFiles; machineName = config.clan.core.settings.machine.name; @@ -38,16 +36,18 @@ in }; config.sops = lib.mkIf (config.clan.core.vars.settings.secretStore == "sops") { + secrets = lib.listToAttrs ( - flip map vars (secret: { + map (secret: { name = "vars/${secret.generator}/${secret.name}"; value = { inherit (secret) owner group neededForUsers; sopsFile = secretPath secret; format = "binary"; }; - }) + }) (builtins.filter (x: builtins.pathExists (secretPath x)) vars) ); + # To get proper error messages about missing secrets we need a dummy secret file that is always present defaultSopsFile = lib.mkIf config.sops.validateSopsFiles ( lib.mkDefault (builtins.toString (pkgs.writeText "dummy.yaml" "")) diff --git a/pkgs/clan-cli/clan_cli/vars/prompt.py b/pkgs/clan-cli/clan_cli/vars/prompt.py index 0278a6ba4..5fc174170 100644 --- a/pkgs/clan-cli/clan_cli/vars/prompt.py +++ b/pkgs/clan-cli/clan_cli/vars/prompt.py @@ -32,7 +32,7 @@ class Prompt: name=data["name"], description=data["description"], prompt_type=PromptType(data["type"]), - create_file=data.get("persist", data["createFile"]), + create_file=data.get("persist", data["persist"]), previous_value=data.get("previousValue"), ) diff --git a/pkgs/clan-cli/tests/test_modules.py b/pkgs/clan-cli/tests/test_modules.py index 3f101553d..842e30aa0 100644 --- a/pkgs/clan-cli/tests/test_modules.py +++ b/pkgs/clan-cli/tests/test_modules.py @@ -18,7 +18,8 @@ from fixtures_flakes import FlakeForTest if TYPE_CHECKING: from age_keys import KeyPair -from clan_cli.machines.facts import machine_get_fact +# from clan_cli.vars.var import machine_get_fact +from clan_cli.machines.machines import Machine as MachineMachine from helpers import cli @@ -86,10 +87,25 @@ def test_add_module_to_inventory( set_inventory(inventory, base_path, "Add borgbackup service") - cmd = ["facts", "generate", "--flake", str(test_flake_with_core.path), "machine1"] + # cmd = ["facts", "generate", "--flake", str(test_flake_with_core.path), "machine1"] + cmd = ["vars", "generate", "--flake", str(test_flake_with_core.path), "machine1"] + cli.run(cmd) - ssh_key = machine_get_fact(base_path, "machine1", "borgbackup.ssh.pub") + machine = MachineMachine( + name="machine1", flake=FlakeId(str(test_flake_with_core.path)) + ) + + generator = None + + for gen in machine.vars_generators: + if gen.name == "borgbackup": + generator = gen + break + + assert generator + + ssh_key = machine.public_vars_store.get(generator, "borgbackup.ssh.pub") cmd = nix_eval( [ @@ -100,4 +116,4 @@ def test_add_module_to_inventory( proc = run_no_stdout(cmd) res = json.loads(proc.stdout.strip()) - assert res["machine1"]["authorizedKeys"] == [ssh_key] + assert res["machine1"]["authorizedKeys"] == [ssh_key.decode()]