mirror of
https://github.com/TECHNOFAB11/kubenix.git
synced 2026-02-03 01:45:10 +01:00
Initial refactoring for kubenix 2.0
Implemented features: - Improved and reimplemented submodule system, independent of kubernetes module definitions - Pre-generated kubernetes module definitions with explicit API versioning support
This commit is contained in:
parent
7287c4ed9e
commit
3dc1e615c4
20 changed files with 207916 additions and 751 deletions
225
submodules.nix
Normal file
225
submodules.nix
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
{ config, kubenix, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.submodules;
|
||||
|
||||
submoduleWithSpecialArgs = opts: specialArgs:
|
||||
let
|
||||
opts' = toList opts;
|
||||
inherit (lib.modules) evalModules;
|
||||
in
|
||||
mkOptionType rec {
|
||||
name = "submodule";
|
||||
check = x: isAttrs x || isFunction x;
|
||||
merge = loc: defs:
|
||||
let
|
||||
coerce = def: if isFunction def then def else { config = def; };
|
||||
modules = opts' ++ map (def: { _file = def.file; imports = [(coerce def.value)]; }) defs;
|
||||
in (evalModules {
|
||||
inherit modules specialArgs;
|
||||
args.name = last loc;
|
||||
prefix = loc;
|
||||
}).config;
|
||||
getSubOptions = prefix: (evalModules
|
||||
{ modules = opts'; inherit prefix specialArgs;
|
||||
# This is a work-around due to the fact that some sub-modules,
|
||||
# such as the one included in an attribute set, expects a "args"
|
||||
# attribute to be given to the sub-module. As the option
|
||||
# evaluation does not have any specific attribute name, we
|
||||
# provide a default one for the documentation.
|
||||
#
|
||||
# This is mandatory as some option declaration might use the
|
||||
# "name" attribute given as argument of the submodule and use it
|
||||
# as the default of option declarations.
|
||||
#
|
||||
# Using lookalike unicode single angle quotation marks because
|
||||
# of the docbook transformation the options receive. In all uses
|
||||
# > and < wouldn't be encoded correctly so the encoded values
|
||||
# would be used, and use of `<` and `>` would break the XML document.
|
||||
# It shouldn't cause an issue since this is cosmetic for the manual.
|
||||
args.name = "‹name›";
|
||||
}).options;
|
||||
getSubModules = opts';
|
||||
substSubModules = m: submoduleWithSpecialArgs m specialArgs;
|
||||
functor = (defaultFunctor name) // {
|
||||
# Merging of submodules is done as part of mergeOptionDecls, as we have to annotate
|
||||
# each submodule with its location.
|
||||
payload = [];
|
||||
binOp = lhs: rhs: [];
|
||||
};
|
||||
};
|
||||
|
||||
submoduleDefinitionOptions = {
|
||||
options = {
|
||||
name = mkOption {
|
||||
description = "Module name";
|
||||
type = types.str;
|
||||
};
|
||||
|
||||
description = mkOption {
|
||||
description = "Module description";
|
||||
type = types.str;
|
||||
default = "";
|
||||
};
|
||||
|
||||
version = mkOption {
|
||||
description = "Module version";
|
||||
type = types.str;
|
||||
default = "0.0.0";
|
||||
};
|
||||
|
||||
passthru = mkOption {
|
||||
description = "Submodule passthru";
|
||||
type = types.coercedTo types.attrs (value: [value]) (types.listOf types.attrs);
|
||||
default = [];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
submoduleOptions = {
|
||||
options.submodule = mkOption {
|
||||
description = "Submodule options";
|
||||
type = types.submodule submoduleDefinitionOptions;
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
|
||||
specialArgs = cfg.specialArgs // {
|
||||
parentConfig = config;
|
||||
};
|
||||
|
||||
findModule = {name, version ? null, latest ? true}: let
|
||||
matchingSubmodules = filter (el:
|
||||
el.definition.name == name &&
|
||||
(if version != null then el.definition.version == version else true)
|
||||
) cfg.imports;
|
||||
|
||||
versionSortedSubmodules = sort (s1: s2:
|
||||
if builtins.compareVersions s1.definition.version s2.definition.version > 0
|
||||
then true else false
|
||||
) matchingSubmodules;
|
||||
|
||||
matchingModule =
|
||||
if length versionSortedSubmodules == 0
|
||||
then throw "No module found ${name}/${if version == null then "latest" else version}"
|
||||
else head versionSortedSubmodules;
|
||||
in matchingModule;
|
||||
in {
|
||||
options = {
|
||||
submodules.specialArgs = mkOption {
|
||||
description = "Special args to pass to submodules. These arguments can be used for imports";
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
};
|
||||
|
||||
submodules.defaults = mkOption {
|
||||
description = "Submodule defaults";
|
||||
type = types.coercedTo types.unspecified (value: [value]) (types.listOf types.unspecified);
|
||||
example = literalExample ''{config, ...}: {
|
||||
kubernetes.version = config.kubernetes.version;
|
||||
}'';
|
||||
default = [];
|
||||
};
|
||||
|
||||
submodules.propagateDefaults = mkOption {
|
||||
description = "Whether to propagate defaults to submodules";
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
submodules.propagate = mkOption {
|
||||
description = "Whether to propagate defaults and imports to submodule's submodules";
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
|
||||
submodules.imports = mkOption {
|
||||
description = "List of submodule imports";
|
||||
type = types.listOf (
|
||||
types.coercedTo
|
||||
types.path
|
||||
(module: {inherit module;})
|
||||
(types.submodule ({name, config, ...}: let
|
||||
submoduleDefinition = (evalModules {
|
||||
inherit specialArgs;
|
||||
modules = config.modules ++ [submoduleOptions];
|
||||
check = false;
|
||||
}).config.submodule;
|
||||
in {
|
||||
options = {
|
||||
module = mkOption {
|
||||
description = "Module defining submodule";
|
||||
};
|
||||
|
||||
modules = mkOption {
|
||||
description = "List of modules defining submodule";
|
||||
type = types.listOf types.unspecified;
|
||||
default = [config.module];
|
||||
};
|
||||
|
||||
definition = mkOption {
|
||||
type = types.submodule submoduleDefinitionOptions;
|
||||
default = submoduleDefinition;
|
||||
};
|
||||
};
|
||||
})
|
||||
)
|
||||
);
|
||||
default = [];
|
||||
};
|
||||
|
||||
submodules.instances = mkOption {
|
||||
description = "Attribute set of submodule instances";
|
||||
type = types.attrsOf (types.submodule ({name, config, ...}: let
|
||||
submodule = findModule {
|
||||
name = config.submodule;
|
||||
version = config.version;
|
||||
};
|
||||
|
||||
submoduleDefinition = submodule.definition;
|
||||
in {
|
||||
options = {
|
||||
name = mkOption {
|
||||
description = "Submodule instance name";
|
||||
type = types.str;
|
||||
default = name;
|
||||
};
|
||||
|
||||
submodule = mkOption {
|
||||
description = "Name of the submodule to use";
|
||||
type = types.str;
|
||||
default = name;
|
||||
};
|
||||
|
||||
version = mkOption {
|
||||
description = "Version of submodule to use";
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
};
|
||||
|
||||
config = mkOption {
|
||||
description = "Submodule instance ${config.name} for ${submoduleDefinition.name}:${submoduleDefinition.version} config";
|
||||
type = submoduleWithSpecialArgs ({...}: {
|
||||
imports = submodule.modules ++ cfg.defaults ++ [submoduleOptions ./submodules.nix];
|
||||
_module.args.submodule = {
|
||||
name = config.name;
|
||||
};
|
||||
}) specialArgs;
|
||||
default = {};
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
default = {};
|
||||
};
|
||||
|
||||
config = {
|
||||
submodules.specialArgs.kubenix = kubenix;
|
||||
submodules.defaults = mkIf cfg.propagate {
|
||||
submodules.defaults = cfg.defaults;
|
||||
submodules.imports = cfg.imports;
|
||||
};
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue