Inventory: generate exact schema for validation & documentation
This commit is contained in:
@@ -15,7 +15,7 @@ let
|
||||
};
|
||||
|
||||
machineRef = lib.mkOptionType {
|
||||
name = "machineRef";
|
||||
name = "str";
|
||||
description = "Machine :: [${builtins.concatStringsSep " | " (builtins.attrNames config.machines)}]";
|
||||
check = v: lib.isString v && builtins.elem v (builtins.attrNames config.machines);
|
||||
merge = lib.mergeEqualOption;
|
||||
@@ -29,20 +29,85 @@ let
|
||||
);
|
||||
|
||||
tagRef = lib.mkOptionType {
|
||||
name = "tagRef";
|
||||
name = "str";
|
||||
description = "Tags :: [${builtins.concatStringsSep " | " allTags}]";
|
||||
check = v: lib.isString v && builtins.elem v allTags;
|
||||
merge = lib.mergeEqualOption;
|
||||
};
|
||||
|
||||
moduleConfig = lib.mkOption {
|
||||
default = { };
|
||||
type = t.attrsOf t.anything;
|
||||
};
|
||||
in
|
||||
{
|
||||
options.assertions = lib.mkOption {
|
||||
type = t.listOf t.unspecified;
|
||||
internal = true;
|
||||
default = [ ];
|
||||
options = {
|
||||
assertions = lib.mkOption {
|
||||
type = t.listOf t.unspecified;
|
||||
internal = true;
|
||||
visible = false;
|
||||
default = [ ];
|
||||
};
|
||||
meta = metaOptions;
|
||||
|
||||
machines = lib.mkOption {
|
||||
default = { };
|
||||
type = t.attrsOf (
|
||||
t.submodule {
|
||||
options = {
|
||||
inherit (metaOptions) name description icon;
|
||||
tags = lib.mkOption {
|
||||
default = [ ];
|
||||
apply = lib.unique;
|
||||
type = t.listOf t.str;
|
||||
};
|
||||
system = lib.mkOption {
|
||||
default = null;
|
||||
type = t.nullOr t.str;
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
services = lib.mkOption {
|
||||
default = { };
|
||||
type = t.attrsOf (
|
||||
t.attrsOf (
|
||||
t.submodule {
|
||||
options.meta = metaOptions;
|
||||
options.config = moduleConfig;
|
||||
options.machines = lib.mkOption {
|
||||
default = { };
|
||||
type = t.attrsOf (t.submodule { options.config = moduleConfig; });
|
||||
};
|
||||
options.roles = lib.mkOption {
|
||||
default = { };
|
||||
type = t.attrsOf (
|
||||
t.submodule {
|
||||
options.machines = lib.mkOption {
|
||||
default = [ ];
|
||||
type = t.listOf machineRef;
|
||||
};
|
||||
options.tags = lib.mkOption {
|
||||
default = [ ];
|
||||
apply = lib.unique;
|
||||
type = t.listOf tagRef;
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
# Smoke validation of the inventory
|
||||
config.assertions =
|
||||
let
|
||||
# Inventory assertions
|
||||
# - All referenced machines must exist in the top-level machines
|
||||
serviceAssertions = lib.foldlAttrs (
|
||||
ass1: serviceName: c:
|
||||
ass1
|
||||
@@ -60,8 +125,11 @@ in
|
||||
ass2 ++ assertions
|
||||
) [ ] c
|
||||
) [ ] config.services;
|
||||
|
||||
# Machine assertions
|
||||
# - A machine must define their host system
|
||||
machineAssertions = map (
|
||||
{ name, value }:
|
||||
{ name }:
|
||||
{
|
||||
assertion = true;
|
||||
message = "Machine ${name} should define its host system in the inventory. ()";
|
||||
@@ -69,68 +137,4 @@ in
|
||||
) (lib.attrsToList (lib.filterAttrs (_n: v: v.system or null == null) config.machines));
|
||||
in
|
||||
machineAssertions ++ serviceAssertions;
|
||||
|
||||
options.meta = metaOptions;
|
||||
|
||||
options.machines = lib.mkOption {
|
||||
default = { };
|
||||
type = t.attrsOf (
|
||||
t.submodule {
|
||||
options = {
|
||||
inherit (metaOptions) name description icon;
|
||||
tags = lib.mkOption {
|
||||
default = [ ];
|
||||
apply = lib.unique;
|
||||
type = t.listOf t.str;
|
||||
};
|
||||
system = lib.mkOption {
|
||||
default = null;
|
||||
type = t.nullOr t.str;
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
options.services = lib.mkOption {
|
||||
default = { };
|
||||
type = t.attrsOf (
|
||||
t.attrsOf (
|
||||
t.submodule {
|
||||
options.meta = metaOptions;
|
||||
options.config = lib.mkOption {
|
||||
default = { };
|
||||
type = t.anything;
|
||||
};
|
||||
options.machines = lib.mkOption {
|
||||
default = { };
|
||||
type = t.attrsOf (
|
||||
t.submodule {
|
||||
options.config = lib.mkOption {
|
||||
default = { };
|
||||
type = t.anything;
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
options.roles = lib.mkOption {
|
||||
default = { };
|
||||
type = t.attrsOf (
|
||||
t.submodule {
|
||||
options.machines = lib.mkOption {
|
||||
default = [ ];
|
||||
type = t.listOf machineRef;
|
||||
};
|
||||
options.tags = lib.mkOption {
|
||||
default = [ ];
|
||||
apply = lib.unique;
|
||||
type = t.listOf tagRef;
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user