diff --git a/meta/options.nix b/meta/options.nix index 98b2375..d8eed9b 100644 --- a/meta/options.nix +++ b/meta/options.nix @@ -1,4 +1,4 @@ -{ lib, ... }@args: +{ config, lib, ... }@args: let inherit (lib) @@ -16,6 +16,7 @@ let nullOr str submodule + unspecified ; addressType = @@ -32,6 +33,8 @@ let }; }; }; + + org = config.organization; in { @@ -301,5 +304,52 @@ in Network configuration for the different machines. ''; }; + + assertions = mkOption { + type = listOf unspecified; + internal = true; + default = [ ]; + description = '' + This option allows modules to express conditions that must + hold for the evaluation of the system configuration to + succeed, along with associated error messages for the user. + ''; + }; }; + + config = + let + members = builtins.attrNames org.members; + groups = builtins.attrNames org.groups; + + nameExists = + list: f: groups: + builtins.attrValues ( + builtins.mapAttrs (name: members: { + assertion = builtins.all (x: builtins.elem x list) members; + message = f name; + }) groups + ); + + membersExists = nameExists members; + groupsExists = nameExists groups; + in + { + assertions = builtins.concatLists [ + # Check that all group members exist + (membersExists ( + name: "A member of the ${name} group was not found in the members list." + ) org.groups) + + # Check that all node admins exist + (membersExists (name: "A member of the ${name} admins was not found in the members list.") ( + builtins.mapAttrs (_: builtins.getAttr "admins") config.nodes + )) + + # Check that all node adminGroups exist + (groupsExists (name: "A member of the ${name} adminGroups was not found in the groups list.") ( + builtins.mapAttrs (_: builtins.getAttr "adminGroups") config.nodes + )) + ]; + }; } diff --git a/meta/verify.nix b/meta/verify.nix index 1393f11..39da415 100644 --- a/meta/verify.nix +++ b/meta/verify.nix @@ -14,7 +14,18 @@ let in { - meta = pkgs.writers.writeJSON "meta.json" ((import ./.) pkgs.lib); + meta = + let + config = (import ./.) pkgs.lib; + failed = builtins.map (x: "- ${x.message}") (builtins.filter (x: !x.assertion) config.assertions); + in + if (failed != [ ]) then + throw '' + Failed assertions: + ${builtins.concatStringsSep "\n" failed} + '' + else + pkgs.writers.writeJSON "meta.json" config; dns = dns.util.${builtins.currentSystem}.writeZone "dgnum.eu" ( pkgs.lib.recursiveUpdate { SOA.serial = 0; } (import ./dns.nix { inherit dns lib; })