Inventory/constraints: add id's to inventory constraints to make them more observable

This commit is contained in:
Johannes Kirschbauer
2024-11-13 13:58:43 +01:00
parent 527769e060
commit 280878e30a
6 changed files with 255 additions and 229 deletions

View File

@@ -2,53 +2,51 @@
lib,
config,
resolvedRoles,
instanceName,
moduleName,
...
}:
let
inherit (config) roles;
in
{
imports = [
./interface.nix
];
config.assertions = lib.foldl' (
ass: roleName:
let
roleConstraints = config.roles.${roleName};
members = resolvedRoles.${roleName}.machines;
memberCount = builtins.length members;
# Checks
eqCheck =
if roleConstraints.eq != null then
[
{
assertion = memberCount == roleConstraints.eq;
message = "The ${moduleName} module requires exactly ${builtins.toString roleConstraints.eq} '${roleName}', but found ${builtins.toString memberCount}: ${builtins.toString members}";
}
]
else
[ ];
minCheck =
if roleConstraints.min > 0 then
[
{
# Role assertions
{
config.assertions = lib.foldlAttrs (
ass: roleName: roleConstraints:
let
members = resolvedRoles.${roleName}.machines;
memberCount = builtins.length members;
# Checks
minCheck = lib.optionalAttrs (roleConstraints.min > 0) {
"${moduleName}.${instanceName}.roles.${roleName}.min" = {
assertion = memberCount >= roleConstraints.min;
message = "The ${moduleName} module requires at least ${builtins.toString roleConstraints.min} '${roleName}'s, but found ${builtins.toString memberCount}: ${builtins.toString members}";
}
]
else
[ ];
message = ''
The ${moduleName} module requires at least ${builtins.toString roleConstraints.min} '${roleName}'s
but found '${builtins.toString memberCount}' within instance '${instanceName}':
maxCheck =
if roleConstraints.max != null then
[
{
${lib.concatLines members}
'';
};
};
maxCheck = lib.optionalAttrs (roleConstraints.max != null) {
"${moduleName}.${instanceName}.roles.${roleName}.max" = {
assertion = memberCount <= roleConstraints.max;
message = "The ${moduleName} module allows at most for ${builtins.toString roleConstraints.max} '${roleName}'s, but found ${builtins.toString memberCount}: ${builtins.toString members}";
}
]
else
[ ];
in
eqCheck ++ minCheck ++ maxCheck ++ ass
) [ ] (lib.attrNames config.roles);
message = ''
The ${moduleName} module allows at most for ${builtins.toString roleConstraints.max} '${roleName}'s
but found '${builtins.toString memberCount}' within instance '${instanceName}':
${lib.concatLines members}
'';
};
};
in
ass // maxCheck // minCheck
) { } roles;
}
];
}

View File

@@ -1,9 +1,19 @@
{ lib, allRoles, ... }:
{
lib,
allRoles,
moduleName,
...
}:
let
inherit (lib) mkOption types;
rolesAttrs = builtins.groupBy lib.id allRoles;
in
{
options.serviceName = mkOption {
type = types.str;
default = moduleName;
readOnly = true;
};
options.roles = lib.mapAttrs (
_name: _:
mkOption {
@@ -20,10 +30,6 @@ in
type = types.int;
default = 0;
};
eq = mkOption {
type = types.nullOr types.int;
default = null;
};
};
}
];
@@ -31,10 +37,26 @@ in
}
) rolesAttrs;
options.instances = mkOption {
default = { };
type = types.submoduleWith {
modules = [
{
options = {
max = mkOption {
type = types.nullOr types.int;
default = null;
};
};
}
];
};
};
# The resulting assertions
options.assertions = mkOption {
default = [ ];
type = types.listOf (
default = { };
type = types.attrsOf (
types.submoduleWith {
modules = [
{