diff --git a/lib/default.nix b/lib/default.nix index 086fcce8..91a23d6d 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -6,8 +6,9 @@ }: { evalClanModules = import ./eval-clan-modules { inherit clan-core nixpkgs lib; }; + buildClan = import ./build-clan { inherit clan-core lib nixpkgs; }; + facts = import ./facts.nix { inherit lib; }; inventory = import ./inventory { inherit lib clan-core; }; jsonschema = import ./jsonschema { inherit lib; }; modules = import ./description.nix { inherit clan-core lib; }; - buildClan = import ./build-clan { inherit clan-core lib nixpkgs; }; } diff --git a/lib/facts.nix b/lib/facts.nix new file mode 100644 index 00000000..5ba36b5d --- /dev/null +++ b/lib/facts.nix @@ -0,0 +1,72 @@ +{ lib, ... }: +machineDir: +let + + allMachineNames = lib.mapAttrsToList (name: _: name) (builtins.readDir machineDir); + + getFactPath = fact: machine: "${machineDir}/${machine}/facts/${fact}"; + + readFact = + fact: machine: + let + path = getFactPath fact machine; + in + if builtins.pathExists path then builtins.readFile path else null; + + # Example: + # + # readFactFromAllMachines zerotier-ip + # => { + # machineA = "1.2.3.4"; + # machineB = "5.6.7.8"; + # }; + readFactFromAllMachines = + fact: + let + machines = allMachineNames; + facts = lib.genAttrs machines (readFact fact); + filteredFacts = lib.filterAttrs (_machine: fact: fact != null) facts; + in + filteredFacts; + + # all given facts are are set and factvalues are never null. + # + # Example: + # + # readFactsFromAllMachines [ "zerotier-ip" "syncthing.pub" ] + # => { + # machineA = + # { + # "zerotier-ip" = "1.2.3.4"; + # "synching.pub" = "1234"; + # }; + # machineB = + # { + # "zerotier-ip" = "5.6.7.8"; + # "synching.pub" = "23456719"; + # }; + # }; + readFactsFromAllMachines = + facts: + let + # machine -> fact -> factvalue + machinesFactsAttrs = lib.genAttrs allMachineNames ( + machine: lib.genAttrs facts (fact: readFact fact machine) + ); + # remove all machines which don't have all facts set + filteredMachineFactAttrs = lib.filterAttrs ( + _machine: values: builtins.all (fact: values.${fact} != null) facts + ) machinesFactsAttrs; + in + filteredMachineFactAttrs; + +in +{ + inherit + allMachineNames + getFactPath + readFact + readFactFromAllMachines + readFactsFromAllMachines + ; +}