diff --git a/lib/facts.nix b/lib/facts.nix new file mode 100644 index 00000000..6f19a6c1 --- /dev/null +++ b/lib/facts.nix @@ -0,0 +1,64 @@ +{ 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; }