Migrate borgbackup module to vars

This commit is contained in:
Pablo Ovelleiro Corral
2025-01-13 22:38:13 +01:00
committed by Jörg Thalheim
parent 89890d34af
commit 038083bece
9 changed files with 64 additions and 45 deletions

View File

@@ -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";

View File

@@ -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:.";
}

View File

@@ -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
'';
};

View File

@@ -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;

23
flake.lock generated
View File

@@ -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"
}

View File

@@ -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";

View File

@@ -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" ""))

View File

@@ -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"),
)

View File

@@ -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()]