From cbde58e1d8b55c7bc0e54e41d415b7a597950970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Tue, 22 Apr 2025 14:36:13 +0200 Subject: [PATCH] zerotier: migrate from facts to vars --- clanModules/data-mesher/shared.nix | 4 +- clanModules/static-hosts/default.nix | 4 +- .../syncthing-static-peers/default.nix | 9 +- clanModules/zerotier-static-peers/default.nix | 21 ++--- clanModules/zerotier/roles/controller.nix | 4 +- clanModules/zerotier/shared.nix | 17 ++-- docs/site/getting-started/mesh-vpn.md | 2 +- nixosModules/clanCore/zerotier/default.nix | 71 ++++++++------- .../clan_cli/tests/test_secrets_generate.py | 89 ++++++++++++------- .../tests/test_secrets_password_store.py | 35 +++++--- templates/clan/flake-parts/flake.nix | 2 +- .../new-clan/machines/sara/configuration.nix | 2 +- 12 files changed, 148 insertions(+), 112 deletions(-) diff --git a/clanModules/data-mesher/shared.nix b/clanModules/data-mesher/shared.nix index bfeea2989..54db475e9 100644 --- a/clanModules/data-mesher/shared.nix +++ b/clanModules/data-mesher/shared.nix @@ -13,10 +13,10 @@ let defaultBootstrapNodes = builtins.foldl' ( urls: name: if - builtins.pathExists "${config.clan.core.settings.directory}/machines/${name}/facts/zerotier-ip" + builtins.pathExists "${config.clan.core.settings.directory}/vars/per-machine/${name}/zerotier/zerotier-ip/value" then let - ip = builtins.readFile "${config.clan.core.settings.directory}/machines/${name}/facts/zerotier-ip"; + ip = builtins.readFile "${config.clan.core.settings.directory}/vars/per-machine/${name}/zerotier/zerotier-ip/value"; in urls ++ "${ip}:${cfg.network.port}" else diff --git a/clanModules/static-hosts/default.nix b/clanModules/static-hosts/default.nix index 951d4fd54..e214d38d9 100644 --- a/clanModules/static-hosts/default.nix +++ b/clanModules/static-hosts/default.nix @@ -26,8 +26,8 @@ config.networking.hosts = let dir = config.clan.core.settings.directory; - machineDir = dir + "/machines/"; - zerotierIpMachinePath = machines: machineDir + machines + "/facts/zerotier-ip"; + machineDir = "${dir}/vars/per-machine"; + zerotierIpMachinePath = machine: "${machineDir}/${machine}/zerotier/zerotier-ip/value"; machinesFileSet = builtins.readDir machineDir; machines = lib.mapAttrsToList (name: _: name) machinesFileSet; networkIpsUnchecked = builtins.map ( diff --git a/clanModules/syncthing-static-peers/default.nix b/clanModules/syncthing-static-peers/default.nix index 6b853d6af..6a85b3900 100644 --- a/clanModules/syncthing-static-peers/default.nix +++ b/clanModules/syncthing-static-peers/default.nix @@ -6,10 +6,9 @@ }: let dir = config.clan.core.settings.directory; - machineDir = dir + "/machines/"; - machineVarDir = dir + "/vars/per-machine/"; - syncthingPublicKeyPath = machines: machineVarDir + machines + "/syncthing/id/value"; - machinesFileSet = builtins.readDir machineDir; + machineVarDir = "${dir}/vars/per-machine/"; + syncthingPublicKeyPath = machine: "${machineVarDir}/${machine}/syncthing/id/value"; + machinesFileSet = builtins.readDir machineVarDir; machines = lib.mapAttrsToList (name: _: name) machinesFileSet; syncthingPublicKeysUnchecked = builtins.map ( machine: @@ -19,7 +18,7 @@ let if builtins.pathExists fullPath then machine else null ) machines; syncthingPublicKeyMachines = lib.filter (machine: machine != null) syncthingPublicKeysUnchecked; - zerotierIpMachinePath = machines: machineDir + machines + "/facts/zerotier-ip"; + zerotierIpMachinePath = machine: "${machineVarDir}/${machine}/zerotier/zerotier-ip/value"; networkIpsUnchecked = builtins.map ( machine: let diff --git a/clanModules/zerotier-static-peers/default.nix b/clanModules/zerotier-static-peers/default.nix index d9105dcf9..3000dc501 100644 --- a/clanModules/zerotier-static-peers/default.nix +++ b/clanModules/zerotier-static-peers/default.nix @@ -6,15 +6,16 @@ }: let dir = config.clan.core.settings.directory; - machineDir = dir + "/machines/"; + machineDir = "${dir}/vars/per-machine"; + # TODO: This should use the inventory + # However we are probably going to replace this with the network module. machinesFileSet = builtins.readDir machineDir; machines = lib.mapAttrsToList (name: _: name) machinesFileSet; - zerotierNetworkIdPath = machines: machineDir + machines + "/facts/zerotier-network-id"; networkIdsUnchecked = builtins.map ( machine: let - fullPath = zerotierNetworkIdPath machine; + fullPath = "${machineDir}/vars/per-machine/${machine}/zerotier/zerotier-network-id/value"; in if builtins.pathExists fullPath then builtins.readFile fullPath else null ) machines; @@ -45,13 +46,9 @@ in config.systemd.services.zerotier-static-peers-autoaccept = let - zerotierIpMachinePath = machines: machineDir + machines + "/facts/zerotier-ip"; + zerotierIpFor = machine: "${machineDir}/vars/per-machine/${machine}/zerotier/zerotier-ip/value"; networkIpsUnchecked = builtins.map ( - machine: - let - fullPath = zerotierIpMachinePath machine; - in - if builtins.pathExists fullPath then machine else null + machine: if builtins.pathExists (zerotierIpFor machine) then machine else null ) machines; networkIps = lib.filter (machine: machine != null) networkIpsUnchecked; machinesWithIp = lib.filterAttrs (name: _: (lib.elem name networkIps)) machinesFileSet; @@ -60,11 +57,7 @@ in ) machinesWithIp; hosts = lib.mapAttrsToList (host: _: host) ( lib.mapAttrs' ( - machine: _: - let - fullPath = zerotierIpMachinePath machine; - in - lib.nameValuePair (builtins.readFile fullPath) [ machine ] + machine: _: lib.nameValuePair (builtins.readFile (zerotierIpFor machine)) [ machine ] ) filteredMachines ); allHostIPs = config.clan.zerotier-static-peers.networkIps ++ hosts; diff --git a/clanModules/zerotier/roles/controller.nix b/clanModules/zerotier/roles/controller.nix index 2396789e0..c060c0f1d 100644 --- a/clanModules/zerotier/roles/controller.nix +++ b/clanModules/zerotier/roles/controller.nix @@ -23,11 +23,11 @@ in networkIps = builtins.foldl' ( ips: name: if - builtins.pathExists "${config.clan.core.settings.directory}/machines/${name}/facts/zerotier-ip" + builtins.pathExists "${config.clan.core.settings.directory}/vars/per-machine/${name}/zerotier/zerotier-ip/value" then ips ++ [ - (builtins.readFile "${config.clan.core.settings.directory}/machines/${name}/facts/zerotier-ip") + (builtins.readFile "${config.clan.core.settings.directory}/vars/per-machine/${name}/zerotier/zerotier-ip/value") ] else ips diff --git a/clanModules/zerotier/shared.nix b/clanModules/zerotier/shared.nix index 2556222ee..f1504b8f5 100644 --- a/clanModules/zerotier/shared.nix +++ b/clanModules/zerotier/shared.nix @@ -10,17 +10,24 @@ let zeroTierInstance = config.clan.inventory.services.zerotier.${instanceName}; roles = zeroTierInstance.roles; controllerMachine = builtins.head roles.controller.machines; - networkIdPath = "${config.clan.core.settings.directory}/machines/${controllerMachine}/facts/zerotier-network-id"; - networkId = if builtins.pathExists networkIdPath then builtins.readFile networkIdPath else null; + networkIdPath = "${config.clan.core.settings.directory}/vars/per-machine/${controllerMachine}/zerotier/zerotier-network-id/value"; + networkId = + if builtins.pathExists networkIdPath then + builtins.readFile networkIdPath + else + builtins.throw '' + No zerotier network id found for ${controllerMachine}. + Please run `clan vars generate ${controllerMachine}` first. + ''; moons = roles.moon.machines; moonIps = builtins.foldl' ( ips: name: if - builtins.pathExists "${config.clan.core.settings.directory}/machines/${name}/facts/zerotier-ip" + builtins.pathExists "${config.clan.core.settings.directory}/vars/per-machine/${name}/zerotier/zerotier-ip/value" then ips ++ [ - (builtins.readFile "${config.clan.core.settings.directory}/machines/${name}/facts/zerotier-ip") + (builtins.readFile "${config.clan.core.settings.directory}/vars/per-machine/${name}/zerotier/zerotier-ip/value") ] else ips @@ -62,7 +69,7 @@ in clan.core.networking.zerotier.networkId = networkId; clan.core.networking.zerotier.name = instanceName; - # TODO: in future we want to have the node id of our moons in our facts + # TODO: in future we want to have the node id of our moons in our vars systemd.services.zerotierone.serviceConfig.ExecStartPost = lib.mkIf (moonIps != [ ]) ( lib.mkAfter [ "+${pkgs.writeScript "orbit-moons-by-ip" '' diff --git a/docs/site/getting-started/mesh-vpn.md b/docs/site/getting-started/mesh-vpn.md index 9c095702a..9d680f415 100644 --- a/docs/site/getting-started/mesh-vpn.md +++ b/docs/site/getting-started/mesh-vpn.md @@ -86,7 +86,7 @@ This guide shows you how to configure `zerotier` either through `NixOS Options` configuration, substituting `` with the controller machine name: ```nix { config, ... }: { - clan.core.networking.zerotier.networkId = builtins.readFile (config.clan.core.settings.directory + "/machines//facts/zerotier-network-id"); + clan.core.networking.zerotier.networkId = builtins.readFile ../../vars/per-machine//zerotier/zerotier-network-id/value; } ``` 1. **Update the New Machine**: Execute: diff --git a/nixosModules/clanCore/zerotier/default.nix b/nixosModules/clanCore/zerotier/default.nix index 25797db0c..8bd9b9ebf 100644 --- a/nixosModules/clanCore/zerotier/default.nix +++ b/nixosModules/clanCore/zerotier/default.nix @@ -2,15 +2,11 @@ config, lib, pkgs, + options, ... }: let cfg = config.clan.core.networking.zerotier; - facts = config.clan.core.facts.services.zerotier.public or { }; - genMoonScript = pkgs.runCommand "genmoon" { nativeBuildInputs = [ pkgs.python3 ]; } '' - install -Dm755 ${./genmoon.py} $out/bin/genmoon - patchShebangs $out/bin/genmoon - ''; in { options.clan.core.networking.zerotier = { @@ -89,15 +85,14 @@ in }; }; config = lib.mkMerge [ - ({ + { # Override license so that we can build zerotierone without # having to re-import nixpkgs. services.zerotierone.package = lib.mkDefault (pkgs.callPackage ../../../pkgs/zerotierone { }); - }) - (lib.mkIf ((facts.zerotier-ip.value or null) != null) { - environment.etc."zerotier/ip".text = facts.zerotier-ip.value; - }) + } (lib.mkIf (cfg.networkId != null) { + environment.etc."zerotier/ip".text = + config.clan.core.vars.generators.zerotier.files.zerotier-ip.value; systemd.network.networks."09-zerotier" = { matchConfig.Name = "zt*"; @@ -112,12 +107,12 @@ in "+${pkgs.writeShellScript "init-zerotier" '' # compare hashes of the current identity secret and the one in the config hash1=$(sha256sum /var/lib/zerotier-one/identity.secret | cut -d ' ' -f 1) - hash2=$(sha256sum ${config.clan.core.facts.services.zerotier.secret.zerotier-identity-secret.path} | cut -d ' ' -f 1) + hash2=$(sha256sum ${config.clan.core.vars.generators.zerotier.files.zerotier-identity-secret.path} | cut -d ' ' -f 1) if [[ "$hash1" != "$hash2" ]]; then echo "Identity secret has changed, backing up old identity to /var/lib/zerotier-one/identity.secret.bac" cp /var/lib/zerotier-one/identity.secret /var/lib/zerotier-one/identity.secret.bac cp /var/lib/zerotier-one/identity.public /var/lib/zerotier-one/identity.public.bac - cp ${config.clan.core.facts.services.zerotier.secret.zerotier-identity-secret.path} /var/lib/zerotier-one/identity.secret + cp ${config.clan.core.vars.generators.zerotier.files.zerotier-identity-secret.path} /var/lib/zerotier-one/identity.secret zerotier-idtool getpublic /var/lib/zerotier-one/identity.secret > /var/lib/zerotier-one/identity.public fi @@ -129,7 +124,12 @@ in if [[ ! -f /var/lib/zerotier-one/moon.json ]]; then zerotier-idtool initmoon /var/lib/zerotier-one/identity.public > /var/lib/zerotier-one/moon.json fi - ${genMoonScript}/bin/genmoon /var/lib/zerotier-one/moon.json ${builtins.toFile "moon.json" (builtins.toJSON cfg.moon.stableEndpoints)} /var/lib/zerotier-one/moons.d + ${ + pkgs.runCommand "genmoon" { nativeBuildInputs = [ pkgs.python3 ]; } '' + install -Dm755 ${./genmoon.py} $out/bin/genmoon + patchShebangs $out/bin/genmoon + '' + }/bin/genmoon /var/lib/zerotier-one/moon.json ${builtins.toFile "moon.json" (builtins.toJSON cfg.moon.stableEndpoints)} /var/lib/zerotier-one/moons.d ''} # cleanup old networks @@ -181,22 +181,26 @@ in services.zerotierone.localConf.settings.tcpFallbackRelay = "65.21.12.51/4443"; }) (lib.mkIf cfg.controller.enable { + environment.etc."zerotier/ip".text = + config.clan.core.vars.generators.zerotier.files.zerotier-ip.value; + # only the controller needs to have the key in the repo, the other clients can be dynamic # we generate the zerotier code manually for the controller, since it's part of the bootstrap command - clan.core.facts.services.zerotier = { - public.zerotier-ip = { }; - public.zerotier-network-id = { }; - secret.zerotier-identity-secret = { }; - generator.path = [ + clan.core.vars.generators.zerotier = { + migrateFact = "zerotier"; + files.zerotier-ip.secret = false; + files.zerotier-network-id.secret = false; + files.zerotier-identity-secret = { }; + runtimeInputs = [ config.services.zerotierone.package pkgs.python3 ]; - generator.script = '' + script = '' source ${(pkgs.callPackage ../../../pkgs/minifakeroot { })}/share/minifakeroot/rc python3 ${./generate.py} --mode network \ - --ip "$facts/zerotier-ip" \ - --identity-secret "$secrets/zerotier-identity-secret" \ - --network-id "$facts/zerotier-network-id" + --ip "$out/zerotier-ip" \ + --identity-secret "$out/zerotier-identity-secret" \ + --network-id "$out/zerotier-network-id" ''; }; clan.core.state.zerotier.folders = [ "/var/lib/zerotier-one" ]; @@ -204,23 +208,25 @@ in environment.systemPackages = [ config.clan.core.clanPkgs.zerotier-members ]; }) (lib.mkIf (!cfg.controller.enable && cfg.networkId != null) { - clan.core.facts.services.zerotier = { - public.zerotier-ip = { }; - secret.zerotier-identity-secret = { }; - generator.path = [ + clan.core.vars.generators.zerotier = { + migrateFact = "zerotier"; + files.zerotier-ip.secret = false; + files.zerotier-identity-secret = { }; + runtimeInputs = [ config.services.zerotierone.package pkgs.python3 ]; - generator.script = '' + script = '' python3 ${./generate.py} --mode identity \ - --ip "$facts/zerotier-ip" \ - --identity-secret "$secrets/zerotier-identity-secret" \ + --ip "$out/zerotier-ip" \ + --identity-secret "$out/zerotier-identity-secret" \ --network-id ${cfg.networkId} ''; }; }) - (lib.mkIf (cfg.controller.enable && (facts.zerotier-network-id.value or null) != null) { - clan.core.networking.zerotier.networkId = facts.zerotier-network-id.value; + (lib.mkIf (cfg.controller.enable && config.clan.core.vars.generators ? zerotier) { + clan.core.networking.zerotier.networkId = + config.clan.core.vars.generators.zerotier.files.zerotier-network-id.value; clan.core.networking.zerotier.settings = { authTokens = [ null ]; authorizationEndpoint = ""; @@ -259,7 +265,8 @@ in zt = false; }; }; - environment.etc."zerotier/network-id".text = facts.zerotier-network-id.value; + environment.etc."zerotier/network-id".text = + config.clan.core.vars.generators.zerotier.files.zerotier-network-id.value; systemd.services.zerotierone.serviceConfig.ExecStartPost = [ "+${pkgs.writeShellScript "whitelist-controller" '' ${config.clan.core.clanPkgs.zerotier-members}/bin/zerotier-members allow ${ diff --git a/pkgs/clan-cli/clan_cli/tests/test_secrets_generate.py b/pkgs/clan-cli/clan_cli/tests/test_secrets_generate.py index a49aa2d71..bdf383b79 100644 --- a/pkgs/clan-cli/clan_cli/tests/test_secrets_generate.py +++ b/pkgs/clan-cli/clan_cli/tests/test_secrets_generate.py @@ -4,7 +4,6 @@ from typing import TYPE_CHECKING import pytest from clan_cli.facts.secret_modules.sops import SecretStore from clan_cli.flake import Flake -from clan_cli.machines.facts import machine_get_fact from clan_cli.machines.machines import Machine from clan_cli.secrets.folders import sops_secrets_folder from clan_cli.tests.fixtures_flakes import FlakeForTest @@ -45,66 +44,90 @@ def test_generate_secret( "user1", ] ) - cmd = ["facts", "generate", "--flake", str(test_flake_with_core.path), "vm1"] + cmd = [ + "vars", + "generate", + "--flake", + str(test_flake_with_core.path), + "vm1", + "--generator", + "zerotier", + ] cli.run(cmd) + store1 = SecretStore( Machine(name="vm1", flake=Flake(str(test_flake_with_core.path))) ) assert store1.exists("", "age.key") - assert store1.exists("", "zerotier-identity-secret") - network_id = machine_get_fact( - test_flake_with_core.path, "vm1", "zerotier-network-id" - ) + network_id = ( + test_flake_with_core.path + / "vars" + / "per-machine" + / "vm1" + / "zerotier" + / "zerotier-network-id" + / "value" + ).read_text() assert len(network_id) == 16 secrets_folder = sops_secrets_folder(test_flake_with_core.path) age_key = secrets_folder / "vm1-age.key" / "secret" - identity_secret = secrets_folder / "vm1-zerotier-identity-secret" / "secret" + identity_secret = ( + test_flake_with_core.path + / "vars" + / "per-machine" + / "vm1" + / "zerotier" + / "zerotier-identity-secret" + / "secret" + ) age_key_mtime = age_key.lstat().st_mtime_ns secret1_mtime = identity_secret.lstat().st_mtime_ns # Assert that the age key is valid age_secret = store1.get("", "age.key").decode() - assert age_secret.isprintable() assert is_valid_age_key(age_secret) # test idempotency for vm1 and also generate for vm2 - cli.run(["facts", "generate", "--flake", str(test_flake_with_core.path)]) + cli.run( + [ + "vars", + "generate", + "--flake", + str(test_flake_with_core.path), + "--generator", + "zerotier", + ] + ) assert age_key.lstat().st_mtime_ns == age_key_mtime assert identity_secret.lstat().st_mtime_ns == secret1_mtime - assert ( - secrets_folder / "vm1-zerotier-identity-secret" / "machines" / "vm1" - ).exists() - store2 = SecretStore( Machine(name="vm2", flake=Flake(str(test_flake_with_core.path))) ) - # clan vars generate - # TODO: Test vars - # varsStore = VarsSecretStore( - # machine=Machine(name="vm2", flake=FlakeId(str(test_flake_with_core.path))) - # ) - # generators = get_generators(str(test_flake_with_core.path), "vm2") - # generator = next((gen for gen in generators if gen.name == "root-password"), None) - - # if not generator: - # raise Exception("Generator not found") - - # password_update = GeneratorUpdate( - # generator=generator.name, prompt_values={"password": "1234"} - # ) - # set_prompts(str(test_flake_with_core.path), "vm2", [password_update]) - # assert varsStore.exists(generator, "root-password") - assert store2.exists("", "age.key") - assert store2.exists("", "zerotier-identity-secret") + ( + test_flake_with_core.path + / "vars" + / "per-machine" + / "vm2" + / "zerotier" + / "zerotier-identity-secret" + / "secret" + ).exists() - ip = machine_get_fact(test_flake_with_core.path, "vm1", "zerotier-ip") + ip = ( + test_flake_with_core.path + / "vars" + / "per-machine" + / "vm2" + / "zerotier" + / "zerotier-ip" + / "value" + ).read_text() assert ipaddress.IPv6Address(ip).is_private # Assert that the age key is valid age_secret = store2.get("", "age.key").decode() - assert age_secret.isprintable() assert is_valid_age_key(age_secret) diff --git a/pkgs/clan-cli/clan_cli/tests/test_secrets_password_store.py b/pkgs/clan-cli/clan_cli/tests/test_secrets_password_store.py index 92c8b6443..24c3130f3 100644 --- a/pkgs/clan-cli/clan_cli/tests/test_secrets_password_store.py +++ b/pkgs/clan-cli/clan_cli/tests/test_secrets_password_store.py @@ -2,10 +2,6 @@ import subprocess from pathlib import Path import pytest -from clan_cli.facts.secret_modules.password_store import SecretStore -from clan_cli.flake import Flake -from clan_cli.machines.facts import machine_get_fact -from clan_cli.machines.machines import Machine from clan_cli.nix import nix_shell from clan_cli.ssh.host import Host from clan_cli.tests.fixtures_flakes import ClanFlake @@ -32,6 +28,8 @@ def test_upload_secret( config["clan"]["core"]["networking"]["targetHost"] = addr config["clan"]["user-password"]["user"] = "alice" config["clan"]["user-password"]["prompt"] = False + vars_config = config["clan"]["core"]["vars"] + vars_config["settings"]["secretStore"] = "password-store" facts = config["clan"]["core"]["facts"] facts["secretStore"] = "password-store" facts["secretUploadDirectory"]["_type"] = "override" @@ -62,23 +60,32 @@ def test_upload_secret( check=True, ) subprocess.run(nix_shell(["pass"], ["pass", "init", "test@local"]), check=True) - cli.run(["facts", "generate", "vm1", "--flake", str(flake.path)]) + cli.run(["vars", "generate", "vm1", "--flake", str(flake.path), "--generator", "zerotier"]) - store = SecretStore(Machine(name="vm1", flake=Flake(str(flake.path)))) - - network_id = machine_get_fact(flake.path, "vm1", "zerotier-network-id") + network_id = ( + flake.path + / "vars" + / "per-machine" + / "vm1" + / "zerotier" + / "zerotier-network-id" + / "value" + ).read_text() assert len(network_id) == 16 identity_secret = ( - temporary_home / "pass" / "machines" / "vm1" / "zerotier-identity-secret.gpg" + temporary_home + / "pass" + / "clan-vars" + / "per-machine" + / "vm1" + / "zerotier" + / "zerotier-identity-secret.gpg" ) secret1_mtime = identity_secret.lstat().st_mtime_ns # test idempotency - cli.run(["facts", "generate", "vm1"]) + cli.run(["vars", "generate", "vm1", "--generator", "zerotier"]) assert identity_secret.lstat().st_mtime_ns == secret1_mtime - cli.run(["facts", "upload", "vm1"]) + cli.run(["vars", "upload", "vm1"]) zerotier_identity_secret = flake.path / "secrets" / "zerotier-identity-secret" assert zerotier_identity_secret.exists() - assert store.exists("", "zerotier-identity-secret") - - assert store.exists("", "zerotier-identity-secret") diff --git a/templates/clan/flake-parts/flake.nix b/templates/clan/flake-parts/flake.nix index e141aba1f..60c7982ad 100644 --- a/templates/clan/flake-parts/flake.nix +++ b/templates/clan/flake-parts/flake.nix @@ -100,7 +100,7 @@ This will allow sara to share the VPN overlay network with jon The networkId is generated by the first deployment of jon */ - # clan.core.networking.zerotier.networkId = builtins.readFile ../jon/facts/zerotier-network-id; + # clan.core.networking.zerotier.networkId = builtins.readFile ../../vars/per-machine/jon/zerotier/zerotier-network-id/value; }; }; }; diff --git a/templates/clan/new-clan/machines/sara/configuration.nix b/templates/clan/new-clan/machines/sara/configuration.nix index b68885d4e..66da728a1 100644 --- a/templates/clan/new-clan/machines/sara/configuration.nix +++ b/templates/clan/new-clan/machines/sara/configuration.nix @@ -30,5 +30,5 @@ This will allow sara to share the VPN overlay network with jon The networkId is generated by the first deployment of jon */ - # clan.core.networking.zerotier.networkId = builtins.readFile ../jon/facts/zerotier-network-id; + # clan.core.networking.zerotier.networkId = builtins.readFile ../../vars/per-machine/jon/zerotier/zerotier-network-id/value; }