diff --git a/clanServices/data-mesher/default.nix b/clanServices/data-mesher/default.nix index 2c0562c04..5b4e3c1f3 100644 --- a/clanServices/data-mesher/default.nix +++ b/clanServices/data-mesher/default.nix @@ -1,4 +1,7 @@ -{ ... }: +{ + clanLib, + ... +}: let sharedInterface = { lib, ... }: @@ -51,15 +54,15 @@ let builtins.foldl' ( urls: name: let - ipPath = "${config.clan.core.settings.directory}/vars/per-machine/${name}/zerotier/zerotier-ip/value"; + ip = clanLib.vars.getPublicValue { + flake = config.clan.core.settings.directory; + machine = name; + generator = "zerotier"; + file = "zerotier-ip"; + default = null; + }; in - if builtins.pathExists ipPath then - let - ip = builtins.readFile ipPath; - in - urls ++ [ "[${ip}]:${builtins.toString settings.network.port}" ] - else - urls + if ip != null then urls ++ [ "[${ip}]:${builtins.toString settings.network.port}" ] else urls ) [ ] (builtins.attrNames ((roles.admin.machines or { }) // (roles.signer.machines or { }))) ); @@ -156,9 +159,14 @@ in readHostKey = machine: let - path = "${config.clan.core.settings.directory}/vars/per-machine/${machine}/data-mesher-host-key/public_key/value"; + publicKey = clanLib.vars.getPublicValue { + flake = config.clan.core.settings.directory; + inherit machine; + generator = "data-mesher-host-key"; + file = "public_key"; + }; in - builtins.elemAt (lib.splitString "\n" (builtins.readFile path)) 1; + builtins.elemAt (lib.splitString "\n" publicKey) 1; in { enable = true; diff --git a/clanServices/wireguard/default.nix b/clanServices/wireguard/default.nix index 9188660d3..6d1e7be47 100644 --- a/clanServices/wireguard/default.nix +++ b/clanServices/wireguard/default.nix @@ -54,7 +54,10 @@ - For other controllers: The controller's /56 subnet */ -{ ... }: +{ + clanLib, + ... +}: let # Shared module for extraHosts configuration extraHostsModule = @@ -74,10 +77,12 @@ let controllerHosts = lib.mapAttrsToList ( name: _value: let - prefix = builtins.readFile ( - config.clan.core.settings.directory - + "/vars/per-machine/${name}/wireguard-network-${instanceName}/prefix/value" - ); + prefix = clanLib.vars.getPublicValue { + flake = config.clan.core.settings.directory; + machine = name; + generator = "wireguard-network-${instanceName}"; + file = "prefix"; + }; # Controller IP is always ::1 in their subnet ip = prefix + "::1"; in @@ -88,20 +93,24 @@ let peerHosts = lib.mapAttrsToList ( peerName: peerValue: let - peerSuffix = builtins.readFile ( - config.clan.core.settings.directory - + "/vars/per-machine/${peerName}/wireguard-network-${instanceName}/suffix/value" - ); + peerSuffix = clanLib.vars.getPublicValue { + flake = config.clan.core.settings.directory; + machine = peerName; + generator = "wireguard-network-${instanceName}"; + file = "suffix"; + }; # Determine designated controller designatedController = if (builtins.length (builtins.attrNames roles.controller.machines) == 1) then (builtins.head (builtins.attrNames roles.controller.machines)) else peerValue.settings.controller; - controllerPrefix = builtins.readFile ( - config.clan.core.settings.directory - + "/vars/per-machine/${designatedController}/wireguard-network-${instanceName}/prefix/value" - ); + controllerPrefix = clanLib.vars.getPublicValue { + flake = config.clan.core.settings.directory; + machine = designatedController; + generator = "wireguard-network-${instanceName}"; + file = "prefix"; + }; peerIP = controllerPrefix + ":" + peerSuffix; in "${peerIP} ${peerName}.${domain}" @@ -220,10 +229,12 @@ in lib.mapAttrsToList ( ctrlName: _: let - controllerPrefix = builtins.readFile ( - config.clan.core.settings.directory - + "/vars/per-machine/${ctrlName}/wireguard-network-${instanceName}/prefix/value" - ); + controllerPrefix = clanLib.vars.getPublicValue { + flake = config.clan.core.settings.directory; + machine = ctrlName; + generator = "wireguard-network-${instanceName}"; + file = "prefix"; + }; peerIP = controllerPrefix + ":" + peerSuffix; in "${peerIP}/56" @@ -234,20 +245,22 @@ in # Connect to all controllers peers = lib.mapAttrsToList (name: value: { - publicKey = ( - builtins.readFile ( - config.clan.core.settings.directory - + "/vars/per-machine/${name}/wireguard-keys-${instanceName}/publickey/value" - ) - ); + publicKey = clanLib.vars.getPublicValue { + flake = config.clan.core.settings.directory; + machine = name; + generator = "wireguard-keys-${instanceName}"; + file = "publickey"; + }; # Allow each controller's /56 subnet allowedIPs = [ "${ - builtins.readFile ( - config.clan.core.settings.directory - + "/vars/per-machine/${name}/wireguard-network-${instanceName}/prefix/value" - ) + clanLib.vars.getPublicValue { + flake = config.clan.core.settings.directory; + machine = name; + generator = "wireguard-network-${instanceName}"; + file = "prefix"; + } }::/56" ]; @@ -349,25 +362,29 @@ in if allPeers ? ${name} then # For peers: they now have our entire /56 subnet { - publicKey = ( - builtins.readFile ( - config.clan.core.settings.directory - + "/vars/per-machine/${name}/wireguard-keys-${instanceName}/publickey/value" - ) - ); + publicKey = clanLib.vars.getPublicValue { + flake = config.clan.core.settings.directory; + machine = name; + generator = "wireguard-keys-${instanceName}"; + file = "publickey"; + }; # Allow the peer's /96 range in ALL controller subnets allowedIPs = lib.mapAttrsToList ( ctrlName: _: let - controllerPrefix = builtins.readFile ( - config.clan.core.settings.directory - + "/vars/per-machine/${ctrlName}/wireguard-network-${instanceName}/prefix/value" - ); - peerSuffix = builtins.readFile ( - config.clan.core.settings.directory - + "/vars/per-machine/${name}/wireguard-network-${instanceName}/suffix/value" - ); + controllerPrefix = clanLib.vars.getPublicValue { + flake = config.clan.core.settings.directory; + machine = ctrlName; + generator = "wireguard-network-${instanceName}"; + file = "prefix"; + }; + peerSuffix = clanLib.vars.getPublicValue { + flake = config.clan.core.settings.directory; + machine = name; + generator = "wireguard-network-${instanceName}"; + file = "suffix"; + }; in "${controllerPrefix}:${peerSuffix}/96" ) roles.controller.machines; @@ -377,19 +394,21 @@ in else # For other controllers: use their /56 subnet { - publicKey = ( - builtins.readFile ( - config.clan.core.settings.directory - + "/vars/per-machine/${name}/wireguard-keys-${instanceName}/publickey/value" - ) - ); + publicKey = clanLib.vars.getPublicValue { + flake = config.clan.core.settings.directory; + machine = name; + generator = "wireguard-keys-${instanceName}"; + file = "publickey"; + }; allowedIPs = [ "${ - builtins.readFile ( - config.clan.core.settings.directory - + "/vars/per-machine/${name}/wireguard-network-${instanceName}/prefix/value" - ) + clanLib.vars.getPublicValue { + flake = config.clan.core.settings.directory; + machine = name; + generator = "wireguard-network-${instanceName}"; + file = "prefix"; + } }::/56" ]; diff --git a/clanServices/zerotier/default.nix b/clanServices/zerotier/default.nix index 89e075818..770023f4b 100644 --- a/clanServices/zerotier/default.nix +++ b/clanServices/zerotier/default.nix @@ -1,4 +1,7 @@ -{ ... }: +{ + clanLib, + ... +}: { _class = "clan.service"; manifest.name = "clan-core/zerotier"; @@ -39,6 +42,7 @@ imports = [ (import ./shared.nix { inherit + clanLib instanceName roles config @@ -90,6 +94,7 @@ imports = [ (import ./shared.nix { inherit + clanLib instanceName roles config @@ -142,6 +147,7 @@ imports = [ (import ./shared.nix { inherit + clanLib instanceName roles config @@ -160,15 +166,16 @@ ); networkIps = builtins.foldl' ( ips: name: - if - builtins.pathExists "${config.clan.core.settings.directory}/vars/per-machine/${name}/zerotier/zerotier-ip/value" - then - ips - ++ [ - (builtins.readFile "${config.clan.core.settings.directory}/vars/per-machine/${name}/zerotier/zerotier-ip/value") - ] - else - ips + let + ztIp = clanLib.vars.getPublicValue { + flake = config.clan.core.settings.directory; + machine = name; + generator = "zerotier"; + file = "zerotier-ip"; + default = null; + }; + in + if ztIp != null then ips ++ [ ztIp ] else ips ) [ ] machines; allHostIPs = settings.allowedIps ++ networkIps; in diff --git a/clanServices/zerotier/shared.nix b/clanServices/zerotier/shared.nix index da70d0214..678ddae00 100644 --- a/clanServices/zerotier/shared.nix +++ b/clanServices/zerotier/shared.nix @@ -1,4 +1,5 @@ { + clanLib, lib, config, pkgs, @@ -8,20 +9,26 @@ }: let controllerMachine = builtins.head (lib.attrNames roles.controller.machines or { }); - 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 null; + networkId = clanLib.vars.getPublicValue { + flake = config.clan.core.settings.directory; + machine = controllerMachine; + generator = "zerotier"; + file = "zerotier-network-id"; + default = null; + }; moons = lib.attrNames (roles.moon.machines or { }); moonIps = builtins.foldl' ( ips: name: - if - builtins.pathExists "${config.clan.core.settings.directory}/vars/per-machine/${name}/zerotier/zerotier-ip/value" - then - ips - ++ [ - (builtins.readFile "${config.clan.core.settings.directory}/vars/per-machine/${name}/zerotier/zerotier-ip/value") - ] - else - ips + let + moonIp = clanLib.vars.getPublicValue { + flake = config.clan.core.settings.directory; + machine = name; + generator = "zerotier"; + file = "zerotier-ip"; + default = null; + }; + in + if moonIp != null then ips ++ [ moonIp ] else ips ) [ ] moons; in { diff --git a/lib/default.nix b/lib/default.nix index d84860a1f..672b08515 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -30,6 +30,8 @@ lib.fix ( jsonschema = import ./jsonschema { inherit lib; }; docs = import ./docs.nix { inherit lib; }; + vars = import ./vars.nix { inherit lib; }; + # flakes flakes = clanLib.callLib ./flakes.nix { }; diff --git a/lib/inventory/distributed-service/all-services-wrapper.nix b/lib/inventory/distributed-service/all-services-wrapper.nix index d250ed517..7da8d68b6 100644 --- a/lib/inventory/distributed-service/all-services-wrapper.nix +++ b/lib/inventory/distributed-service/all-services-wrapper.nix @@ -37,6 +37,10 @@ in { name, ... }: { _module.args._ctx = [ name ]; + _module.args.clanLib = specialArgs.clanLib; + _module.args.exports = config.exports; + _module.args.directory = directory; + } ) ./service-module.nix diff --git a/lib/tests.nix b/lib/tests.nix index ee4950e15..74afb8238 100644 --- a/lib/tests.nix +++ b/lib/tests.nix @@ -212,6 +212,57 @@ in }; }; + test_get_var_machine = + let + varsLib = import ./vars.nix { }; + in + { + expr = varsLib.getPublicValue { + backend = "in_repo"; + default = "test"; + shared = false; + generator = "test-generator"; + machine = "test-machine"; + file = "test-file"; + flake = ./vars-test-flake; + }; + expected = "foo-machine"; + }; + + test_get_var_shared = + let + varsLib = import ./vars.nix { }; + in + { + expr = varsLib.getPublicValue { + backend = "in_repo"; + default = "test"; + shared = true; + generator = "test-generator"; + machine = "test-machine"; + file = "test-file"; + flake = ./vars-test-flake; + }; + expected = "foo-shared"; + }; + + test_get_var_default = + let + varsLib = import ./vars.nix { }; + in + { + expr = varsLib.getPublicValue { + backend = "in_repo"; + default = "test-default"; + shared = true; + generator = "test-generator-wrong"; + machine = "test-machine"; + file = "test-file"; + flake = ./vars-test-flake; + }; + expected = "test-default"; + }; + test_clan_all_machines_laziness = let eval = clan { diff --git a/lib/vars-test-flake/vars/per-machine/test-machine/test-generator/test-file/value b/lib/vars-test-flake/vars/per-machine/test-machine/test-generator/test-file/value new file mode 100644 index 000000000..9a78fe08b --- /dev/null +++ b/lib/vars-test-flake/vars/per-machine/test-machine/test-generator/test-file/value @@ -0,0 +1 @@ +foo-machine \ No newline at end of file diff --git a/lib/vars-test-flake/vars/shared/test-generator/test-file/value b/lib/vars-test-flake/vars/shared/test-generator/test-file/value new file mode 100644 index 000000000..2b77bf5c1 --- /dev/null +++ b/lib/vars-test-flake/vars/shared/test-generator/test-file/value @@ -0,0 +1 @@ +foo-shared \ No newline at end of file diff --git a/lib/vars.nix b/lib/vars.nix new file mode 100644 index 000000000..539d215e0 --- /dev/null +++ b/lib/vars.nix @@ -0,0 +1,25 @@ +_: { + getPublicValue = + { + + backend ? "in_repo", + default ? throw "getPublicValue: Public value ${machine}/${generator}/${file} not found!", + shared ? false, + generator, + machine, + file, + flake, + }: + + if backend == "in_repo" then + let + path = + if shared then + "${flake}/vars/shared/${generator}/${file}/value" + else + "${flake}/vars/per-machine/${machine}/${generator}/${file}/value"; + in + if builtins.pathExists path then builtins.readFile path else default + else + throw "backend ${backend} does not implement getPublicValue"; +} diff --git a/lib/vars_test.nix b/lib/vars_test.nix new file mode 100644 index 000000000..0db3279e4 --- /dev/null +++ b/lib/vars_test.nix @@ -0,0 +1,3 @@ +{ + +} diff --git a/modules/inventoryClass/inventory.nix b/modules/inventoryClass/inventory.nix index 833de5f1b..c26390b62 100644 --- a/modules/inventoryClass/inventory.nix +++ b/modules/inventoryClass/inventory.nix @@ -167,7 +167,7 @@ in ''; type = types.submoduleWith { specialArgs = { - inherit (config) machines; + inherit (config) machines clanLib; }; modules = [ {