switch formatting to nixpkgs-fmt

This commit is contained in:
Bryton Hall 2023-07-07 22:01:34 -04:00
parent 3598716c73
commit 2712e89716
65 changed files with 4839 additions and 5222 deletions

View file

@ -1,4 +1,4 @@
{lib, ...}:
{ lib, ... }:
with lib; {
options = {
kubenix.project = mkOption {
@ -10,7 +10,7 @@ with lib; {
_m.features = mkOption {
description = "List of features exposed by module";
type = types.listOf types.str;
default = [];
default = [ ];
};
_m.propagate = mkOption {
@ -20,17 +20,17 @@ with lib; {
features = mkOption {
description = "List of features that submodule has to have to propagate module";
type = types.listOf types.str;
default = [];
default = [ ];
};
module = mkOption {
description = "Module to propagate";
type = types.unspecified;
default = {};
default = { };
};
};
}));
default = [];
default = [ ];
};
};
}

View file

@ -1,14 +1,9 @@
{
config,
lib,
pkgs,
docker,
...
}:
{ config, lib, pkgs, docker, ... }:
with lib; let
cfg = config.docker;
in {
imports = [./base.nix];
in
{
imports = [ ./base.nix ];
options.docker = {
registry.url = mkOption {
@ -19,11 +14,7 @@ in {
images = mkOption {
description = "Attribute set of docker images that should be published";
type = types.attrsOf (types.submodule ({
name,
config,
...
}: {
type = types.attrsOf (types.submodule ({ name, config, ... }: {
options = {
image = mkOption {
description = "Docker image to publish";
@ -65,13 +56,13 @@ in {
};
};
}));
default = {};
default = { };
};
export = mkOption {
description = "List of images to export";
type = types.listOf types.package;
default = [];
default = [ ];
};
copyScript = mkOption {
@ -86,25 +77,22 @@ in {
config = {
# define docker feature
_m.features = ["docker"];
_m.features = [ "docker" ];
# propagate docker options if docker feature is enabled
_m.propagate = [
{
features = ["docker"];
module = _: {
# propagate registry options
docker.registry = cfg.registry;
};
}
];
_m.propagate = [{
features = [ "docker" ];
module = _: {
# propagate registry options
docker.registry = cfg.registry;
};
}];
# pass docker library as param
_module.args.docker = import ../lib/docker {inherit lib pkgs;};
_module.args.docker = import ../lib/docker { inherit lib pkgs; };
# list of exported docker images
docker.export =
mapAttrsToList (_: i: i.image)
docker.export = mapAttrsToList (_: i: i.image)
(filterAttrs (_: i: i.registry != null) config.docker.images);
};
}

View file

@ -1,12 +1,6 @@
# helm defines kubenix module with options for using helm charts
# with kubenix
{
config,
lib,
pkgs,
helm,
...
}:
{ config, lib, pkgs, helm, ... }:
with lib; let
cfg = config.kubernetes.helm;
@ -16,29 +10,28 @@ with lib; let
name = "recursive-attrs";
description = "recursive attribute set";
check = isAttrs;
merge = _loc: foldl' (res: def: recursiveUpdate res def.value) {};
merge = _loc: foldl' (res: def: recursiveUpdate res def.value) { };
};
parseApiVersion = apiVersion: let
splitted = splitString "/" apiVersion;
in {
group =
if length splitted == 1
then "core"
else head splitted;
version = last splitted;
};
in {
imports = [./k8s.nix];
parseApiVersion = apiVersion:
let
splitted = splitString "/" apiVersion;
in
{
group =
if length splitted == 1
then "core"
else head splitted;
version = last splitted;
};
in
{
imports = [ ./k8s.nix ];
options.kubernetes.helm = {
releases = mkOption {
description = "Attribute set of helm releases";
type = types.attrsOf (types.submodule ({
config,
name,
...
}: {
type = types.attrsOf (types.submodule ({ config, name, ... }: {
options = {
name = mkOption {
description = "Helm release name";
@ -60,7 +53,7 @@ in {
values = mkOption {
description = "Values to pass to chart";
type = recursiveAttrs;
default = {};
default = { };
};
kubeVersion = mkOption {
@ -72,7 +65,7 @@ in {
overrides = mkOption {
description = "Overrides to apply to all chart resources";
type = types.listOf types.unspecified;
default = [];
default = [ ];
};
overrideNamespace = mkOption {
@ -109,42 +102,40 @@ in {
objects = mkOption {
description = "Generated kubernetes objects";
type = types.listOf types.attrs;
default = [];
default = [ ];
};
};
config.overrides = mkIf (config.overrideNamespace && config.namespace != null) [
{
metadata.namespace = config.namespace;
}
];
config.overrides = mkIf (config.overrideNamespace && config.namespace != null) [{
metadata.namespace = config.namespace;
}];
config.objects = importJSON (helm.chart2json {
inherit (config) chart name namespace values kubeVersion includeCRDs noHooks;
});
}));
default = {};
default = { };
};
};
config = {
# expose helm helper methods as module argument
_module.args.helm = import ../lib/helm {inherit pkgs;};
_module.args.helm = import ../lib/helm { inherit pkgs; };
kubernetes.api.resources = mkMerge (flatten (mapAttrsToList
(
_: release:
map
(object: let
(_: release: map
(object:
let
apiVersion = parseApiVersion object.apiVersion;
inherit (object.metadata) name;
in {
in
{
"${apiVersion.group}"."${apiVersion.version}".${object.kind}."${name}" = mkMerge ([
object
]
++ release.overrides);
object
]
++ release.overrides);
})
release.objects
release.objects
)
cfg.releases));
};

View file

@ -1,19 +1,13 @@
{
lib,
definitions,
}:
{ lib, definitions }:
with lib; {
"istio_networking_v1alpha3_StringMatch" =
recursiveUpdate
(
recursiveUpdate
"istio_networking_v1alpha3_StringMatch" = recursiveUpdate
(recursiveUpdate
definitions."istio_networking_v1alpha3_StringMatch_Exact"
definitions."istio_networking_v1alpha3_StringMatch_Prefix"
)
definitions."istio_networking_v1alpha3_StringMatch_Regex";
"istio_networking_v1alpha3_PortSelector" =
recursiveUpdate
"istio_networking_v1alpha3_PortSelector" = recursiveUpdate
definitions."istio_networking_v1alpha3_PortSelector_Name"
definitions."istio_networking_v1alpha3_PortSelector_Number";
}

File diff suppressed because it is too large Load diff

View file

@ -1,12 +1,5 @@
# K8S module defines kubernetes definitions for kubenix
{
options,
config,
lib,
pkgs,
k8s,
...
}:
{ options, config, lib, pkgs, k8s, ... }:
with lib; let
versions = (import ../versions.nix).versions;
cfg = config.kubernetes;
@ -15,12 +8,11 @@ with lib; let
getDefaults = resource: group: version: kind:
catAttrs "default" (filter
(
default:
(resource == null || default.resource == null || default.resource == resource)
&& (default.group == null || default.group == group)
&& (default.version == null || default.version == version)
&& (default.kind == null || default.kind == kind)
(default:
(resource == null || default.resource == null || default.resource == resource)
&& (default.group == null || default.group == group)
&& (default.version == null || default.version == version)
&& (default.kind == null || default.kind == kind)
)
cfg.api.defaults);
@ -31,7 +23,7 @@ with lib; let
then map moduleToAttrs value
else value;
apiOptions = {config, ...}: {
apiOptions = { config, ... }: {
options = {
definitions = mkOption {
description = "Attribute set of kubernetes definitions";
@ -74,18 +66,17 @@ with lib; let
default = mkOption {
description = "Default to apply";
type = types.unspecified;
default = {};
default = { };
};
};
}));
default = [];
default = [ ];
apply = unique;
};
types = mkOption {
description = "List of registered kubernetes types";
type =
coerceListOfSubmodulesToAttrs
type = coerceListOfSubmodulesToAttrs
{
options = {
group = mkOption {
@ -115,7 +106,7 @@ with lib; let
};
}
gvkKeyFn;
default = {};
default = { };
};
};
@ -133,20 +124,21 @@ with lib; let
else -1)
lst));
compareVersions = ver1: ver2: let
getVersion = substring 1 10;
splittedVer1 = builtins.splitVersion (getVersion ver1);
splittedVer2 = builtins.splitVersion (getVersion ver2);
compareVersions = ver1: ver2:
let
getVersion = substring 1 10;
splittedVer1 = builtins.splitVersion (getVersion ver1);
splittedVer2 = builtins.splitVersion (getVersion ver2);
v1 =
if length splittedVer1 == 1
then "${getVersion ver1}prod"
else getVersion ver1;
v2 =
if length splittedVer2 == 1
then "${getVersion ver2}prod"
else getVersion ver2;
in
v1 =
if length splittedVer1 == 1
then "${getVersion ver1}prod"
else getVersion ver1;
v2 =
if length splittedVer2 == 1
then "${getVersion ver2}prod"
else getVersion ver2;
in
builtins.compareVersions v1 v2;
customResourceTypesByAttrName = zipAttrs (mapAttrsToList
@ -155,23 +147,20 @@ with lib; let
})
cfg.customTypes);
customResourceTypesByAttrNameSortByVersion =
mapAttrs
(
_: resourceTypes:
reverseList (sort
(
r1: r2:
compareVersions r1.version r2.version > 0
)
resourceTypes)
customResourceTypesByAttrNameSortByVersion = mapAttrs
(_: resourceTypes:
reverseList (sort
(
r1: r2:
compareVersions r1.version r2.version > 0
)
resourceTypes)
)
customResourceTypesByAttrName;
latestCustomResourceTypes =
mapAttrsToList (_: last) customResourceTypesByAttrNameSortByVersion;
latestCustomResourceTypes = mapAttrsToList (_: last) customResourceTypesByAttrNameSortByVersion;
customResourceModuleForType = config: ct: {name, ...}: {
customResourceModuleForType = config: ct: { name, ... }: {
imports = getDefaults ct.name ct.group ct.version ct.kind;
options = {
apiVersion = mkOption {
@ -192,7 +181,7 @@ with lib; let
spec = mkOption {
description = "Module spec";
type = types.either types.attrs (types.submodule ct.module);
default = {};
default = { };
};
};
@ -203,73 +192,74 @@ with lib; let
};
};
customResourceOptions =
(mapAttrsToList
(_: ct: {config, ...}: let
customResourceOptions = (mapAttrsToList
(_: ct: { config, ... }:
let
module = customResourceModuleForType config ct;
in {
in
{
options.resources.${ct.group}.${ct.version}.${ct.kind} = mkOption {
inherit (ct) description;
type = types.attrsOf (types.submodule module);
default = {};
default = { };
};
})
cfg.customTypes)
++ (map
(ct: {
options,
config,
...
}: let
cfg.customTypes)
++ (map
(ct: { options, config, ... }:
let
module = customResourceModuleForType config ct;
in {
in
{
options.resources.${ct.attrName} = mkOption {
inherit (ct) description;
type = types.attrsOf (types.submodule module);
default = {};
default = { };
};
config.resources.${ct.group}.${ct.version}.${ct.kind} =
mkAliasDefinitions options.resources.${ct.attrName};
})
latestCustomResourceTypes);
latestCustomResourceTypes);
coerceListOfSubmodulesToAttrs = submodule: keyFn: let
mergeValuesByFn = keyFn: values:
listToAttrs (map
(
value:
coerceListOfSubmodulesToAttrs = submodule: keyFn:
let
mergeValuesByFn = keyFn: values:
listToAttrs (map
(value:
nameValuePair (toString (keyFn value)) value
)
values);
)
values);
# Either value of type `finalType` or `coercedType`, the latter is
# converted to `finalType` using `coerceFunc`.
coercedTo = coercedType: coerceFunc: finalType:
mkOptionType rec {
name = "coercedTo";
description = "${finalType.description} or ${coercedType.description}";
check = x: finalType.check x || coercedType.check x;
merge = loc: defs: let
coerceVal = val:
if finalType.check val
then val
else let coerced = coerceFunc val; in assert finalType.check coerced; coerced;
in
finalType.merge loc (map (def: def // {value = coerceVal def.value;}) defs);
inherit (finalType) getSubOptions;
inherit (finalType) getSubModules;
substSubModules = m: coercedTo coercedType coerceFunc (finalType.substSubModules m);
typeMerge = _t1: _t2: null;
functor = (defaultFunctor name) // {wrapped = finalType;};
};
in
# Either value of type `finalType` or `coercedType`, the latter is
# converted to `finalType` using `coerceFunc`.
coercedTo = coercedType: coerceFunc: finalType:
mkOptionType rec {
name = "coercedTo";
description = "${finalType.description} or ${coercedType.description}";
check = x: finalType.check x || coercedType.check x;
merge = loc: defs:
let
coerceVal = val:
if finalType.check val
then val
else let coerced = coerceFunc val; in assert finalType.check coerced; coerced;
in
finalType.merge loc (map (def: def // { value = coerceVal def.value; }) defs);
inherit (finalType) getSubOptions;
inherit (finalType) getSubModules;
substSubModules = m: coercedTo coercedType coerceFunc (finalType.substSubModules m);
typeMerge = _t1: _t2: null;
functor = (defaultFunctor name) // { wrapped = finalType; };
};
in
coercedTo
(types.listOf (types.submodule submodule))
(mergeValuesByFn keyFn)
(types.attrsOf (types.submodule submodule));
in {
imports = [./base.nix];
(types.listOf (types.submodule submodule))
(mergeValuesByFn keyFn)
(types.attrsOf (types.submodule submodule));
in
{
imports = [ ./base.nix ];
options.kubernetes = {
kubeconfig = mkOption {
@ -296,7 +286,7 @@ in {
customResources = mkOption {
description = "Setup custom resources";
type = types.listOf types.attrs;
default = [];
default = [ ];
};
resourceOrder = mkOption {
@ -310,25 +300,24 @@ in {
api = mkOption {
type = types.submodule {
imports =
[
./generated/v${cfg.version}.nix
apiOptions
]
++ customResourceOptions;
imports = [
./generated/v${cfg.version}.nix
apiOptions
]
++ customResourceOptions;
};
default = {};
default = { };
};
imports = mkOption {
type = types.listOf (types.either types.package types.path);
description = "List of resources to import";
default = [];
default = [ ];
};
resources = mkOption {
description = "Alias for `config.kubernetes.api.resources` options";
default = {};
default = { };
type = types.attrsOf types.attrs;
};
@ -342,8 +331,7 @@ in {
group = "helm.cattle.io";
};
};
type =
coerceListOfSubmodulesToAttrs
type = coerceListOfSubmodulesToAttrs
{
options = {
group = mkOption {
@ -385,12 +373,12 @@ in {
module = mkOption {
description = "Custom type module";
type = types.unspecified;
default = {};
default = { };
};
};
}
gvkKeyFn;
default = {};
default = { };
};
objects = mkOption {
@ -398,16 +386,15 @@ in {
type = types.listOf types.attrs;
apply = items:
sort
(
r1: r2:
(r1: r2:
if elem r1.kind cfg.resourceOrder && elem r2.kind cfg.resourceOrder
then indexOf cfg.resourceOrder r1.kind < indexOf cfg.resourceOrder r2.kind
else if elem r1.kind cfg.resourceOrder
then true
else false
)
(unique items);
default = [];
)
(unique items);
default = [ ];
};
generated = mkOption {
@ -428,12 +415,12 @@ in {
config = {
# features that module is defining
_m.features = ["k8s"];
_m.features = [ "k8s" ];
# module propagation options
_m.propagate = [
{
features = ["k8s"];
features = [ "k8s" ];
module = _: {
# propagate kubernetes version and namespace
kubernetes.version = mkDefault cfg.version;
@ -441,8 +428,8 @@ in {
};
}
{
features = ["k8s" "submodule"];
module = {config, ...}: {
features = [ "k8s" "submodule" ];
module = { config, ... }: {
# set module defaults
kubernetes.api.defaults =
(filter (default: default.propagate) cfg.api.defaults)
@ -460,40 +447,37 @@ in {
];
# expose k8s helper methods as module argument
_module.args.k8s = import ../lib/k8s {inherit lib;};
_module.args.k8s = import ../lib/k8s { inherit lib; };
kubernetes.api = mkMerge ([
{
# register custom types
types =
mapAttrsToList
(_: cr: {
inherit (cr) name group version kind attrName;
})
cfg.customTypes;
{
# register custom types
types = mapAttrsToList
(_: cr: {
inherit (cr) name group version kind attrName;
})
cfg.customTypes;
defaults = [
{
default = {
# set default kubernetes namespace to all resources
metadata.namespace =
mkIf (config.kubernetes.namespace != null)
(mkDefault config.kubernetes.namespace);
defaults = [{
default = {
# set default kubernetes namespace to all resources
metadata.namespace = mkIf (config.kubernetes.namespace != null)
(mkDefault config.kubernetes.namespace);
# set project name to all resources
metadata.annotations = {
"kubenix/project-name" = config.kubenix.project;
"kubenix/k8s-version" = cfg.version;
};
};
}
];
}
]
++
# import of yaml files
(map
(i: let
# set project name to all resources
metadata.annotations = {
"kubenix/project-name" = config.kubenix.project;
"kubenix/k8s-version" = cfg.version;
};
};
}];
}
]
++
# import of yaml files
(map
(i:
let
# load yaml file
object = importYAML i;
groupVersion = splitString "/" object.apiVersion;
@ -504,15 +488,15 @@ in {
then "core"
else head groupVersion;
inherit (object) kind;
in {
in
{
resources.${group}.${version}.${kind}.${name} = object;
})
cfg.imports));
cfg.imports));
kubernetes.objects = flatten (mapAttrsToList
(
_: type:
mapAttrsToList (_name: moduleToAttrs)
(_: type:
mapAttrsToList (_name: moduleToAttrs)
cfg.api.resources.${type.group}.${type.version}.${type.kind}
)
cfg.api.types);

View file

@ -1,10 +1,6 @@
{
config,
lib,
...
}:
{ config, lib, ... }:
with lib; {
imports = [./base.nix];
imports = [ ./base.nix ];
options.submodule = {
name = mkOption {
@ -27,24 +23,24 @@ with lib; {
tags = mkOption {
description = "List of submodule tags";
type = types.listOf types.str;
default = [];
default = [ ];
};
exports = mkOption {
description = "Attribute set of functions to export";
type = types.attrs;
default = {};
default = { };
};
passthru = mkOption {
description = "Attribute set to passthru";
type = types.attrs;
default = {};
default = { };
};
args._empty = mkOption {};
args._empty = mkOption { };
};
config._module.args.args = config.submodule.args;
config._m.features = ["submodule"];
config._m.features = [ "submodule" ];
}

View file

@ -1,11 +1,4 @@
{
config,
options,
kubenix,
pkgs,
lib,
...
}:
{ config, options, kubenix, pkgs, lib, ... }:
with lib; let
cfg = config.submodules;
parentConfig = config;
@ -18,161 +11,139 @@ with lib; let
else requiredVersion == version
else true;
getDefaults = {
name,
version,
tags,
features,
}:
getDefaults = { name, version, tags, features }:
catAttrs "default" (filter
(
submoduleDefault:
(submoduleDefault.name == null || submoduleDefault.name == name)
&& (matchesVersion submoduleDefault.version version)
&& (
(length submoduleDefault.tags == 0)
|| (length (intersectLists submoduleDefault.tags tags)) > 0
)
&& (
(length submoduleDefault.features == 0)
|| (length (intersectLists submoduleDefault.features features)) > 0
)
(submoduleDefault:
(submoduleDefault.name == null || submoduleDefault.name == name)
&& (matchesVersion submoduleDefault.version version)
&& (
(length submoduleDefault.tags == 0)
|| (length (intersectLists submoduleDefault.tags tags)) > 0
)
&& (
(length submoduleDefault.features == 0)
|| (length (intersectLists submoduleDefault.features features)) > 0
)
)
config.submodules.defaults);
specialArgs =
cfg.specialArgs
// {
parentConfig = config;
};
specialArgs = cfg.specialArgs // {
parentConfig = config;
};
findSubmodule = {
name,
version ? null,
latest ? true,
}: let
matchingSubmodules =
filter
(
el:
findSubmodule = { name, version ? null, latest ? true }:
let
matchingSubmodules = filter
(el:
el.definition.name
== name
&& (matchesVersion version el.definition.version)
)
cfg.imports;
)
cfg.imports;
versionSortedSubmodules =
sort
(
s1: s2:
versionSortedSubmodules = sort
(s1: s2:
if builtins.compareVersions s1.definition.version s2.definition.version > 0
then true
else false
)
matchingSubmodules;
)
matchingSubmodules;
matchingModule =
if length versionSortedSubmodules == 0
then
throw "No module found ${name}/${
matchingModule =
if length versionSortedSubmodules == 0
then
throw "No module found ${name}/${
if version == null
then "latest"
else version
}"
else head versionSortedSubmodules;
in
else head versionSortedSubmodules;
in
matchingModule;
passthruConfig =
mapAttrsToList
passthruConfig = mapAttrsToList
(name: _opt: {
${name} = mkMerge (mapAttrsToList
(
_: inst:
if inst.passthru.enable
then inst.config.submodule.passthru.${name} or {}
else {}
(_: inst:
if inst.passthru.enable
then inst.config.submodule.passthru.${name} or { }
else { }
)
config.submodules.instances);
_module.args = mkMerge (mapAttrsToList
(
_: inst:
if inst.passthru.enable
then inst.config.submodule.passthru._module.args or {}
else {}
(_: inst:
if inst.passthru.enable
then inst.config.submodule.passthru._module.args or { }
else { }
)
config.submodules.instances);
})
(removeAttrs options ["_definedNames" "_module" "_m" "submodules"]);
(removeAttrs options [ "_definedNames" "_module" "_m" "submodules" ]);
submoduleWithSpecialArgs = opts: specialArgs: let
opts' = toList opts;
inherit (lib.modules) evalModules;
in
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
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;
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
# &gt; and &lt; 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;
}).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
# &gt; and &lt; 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: [];
};
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: [ ];
};
};
in {
imports = [./base.nix];
in
{
imports = [ ./base.nix ];
options = {
submodules.specialArgs = mkOption {
description = "Special args to pass to submodules. These arguments can be used for imports";
type = types.attrs;
default = {};
default = { };
};
submodules.defaults = mkOption {
@ -197,23 +168,23 @@ in {
tags = mkOption {
description = "List of tags to apply defaults for";
type = types.listOf types.str;
default = [];
default = [ ];
};
features = mkOption {
description = "List of features that submodule has to have to apply defaults";
type = types.listOf types.str;
default = [];
default = [ ];
};
default = mkOption {
description = "Default to apply to submodule instance";
type = types.unspecified;
default = {};
default = { };
};
};
}));
default = [];
default = [ ];
};
submodules.propagate.enable = mkOption {
@ -226,197 +197,184 @@ in {
description = "List of submodule imports";
type = types.listOf (
types.coercedTo
types.path
(module: {inherit module;})
(
types.submodule ({
name,
config,
...
}: let
evaledSubmodule' = evalModules {
inherit specialArgs;
modules =
config.modules
++ [./base.nix]
++ [
{
types.path
(module: { inherit module; })
(
types.submodule ({ name, config, ... }:
let
evaledSubmodule' = evalModules {
inherit specialArgs;
modules = config.modules
++ [ ./base.nix ]
++ [{
_module.args.check = false;
}
];
};
}];
};
evaledSubmodule =
if (!(elem "submodule" evaledSubmodule'.config._m.features))
then throw "no submodule defined"
else evaledSubmodule';
in {
options = {
module = mkOption {
description = "Module defining submodule";
type = types.unspecified;
};
evaledSubmodule =
if (!(elem "submodule" evaledSubmodule'.config._m.features))
then throw "no submodule defined"
else evaledSubmodule';
in
{
options = {
module = mkOption {
description = "Module defining submodule";
type = types.unspecified;
};
modules = mkOption {
description = "List of modules defining submodule";
type = types.listOf types.unspecified;
default = [config.module];
};
modules = mkOption {
description = "List of modules defining submodule";
type = types.listOf types.unspecified;
default = [ config.module ];
};
features = mkOption {
description = "List of features exposed by submodule";
type = types.listOf types.str;
};
features = mkOption {
description = "List of features exposed by submodule";
type = types.listOf types.str;
};
definition = mkOption {
description = "Submodule definition";
type = types.attrs;
};
definition = mkOption {
description = "Submodule definition";
type = types.attrs;
};
exportAs = mkOption {
description = "Name under which to register exports";
type = types.nullOr types.str;
default = null;
};
};
exportAs = mkOption {
description = "Name under which to register exports";
type = types.nullOr types.str;
default = null;
};
};
config = {
definition = {
inherit (evaledSubmodule.config.submodule) name description version tags exports;
};
config = {
definition = {
inherit (evaledSubmodule.config.submodule) name description version tags exports;
};
inherit (evaledSubmodule.config._m) features;
};
})
)
inherit (evaledSubmodule.config._m) features;
};
})
)
);
default = [];
default = [ ];
};
submodules.instances = mkOption {
description = "Attribute set of submodule instances";
default = {};
type = types.attrsOf (types.submodule ({
name,
config,
options,
...
}: let
# submodule associated with
submodule = findSubmodule {
name = config.submodule;
inherit (config) version;
};
# definition of a submodule
submoduleDefinition = submodule.definition;
# submodule defaults
defaults = getDefaults {
inherit (submoduleDefinition) name;
inherit (submoduleDefinition) version;
inherit (submoduleDefinition) tags;
inherit (submodule) features;
};
in {
options = {
name = mkOption {
description = "Submodule instance name";
type = types.str;
default = name;
default = { };
type = types.attrsOf (types.submodule ({ name, config, options, ... }:
let
# submodule associated with
submodule = findSubmodule {
name = config.submodule;
inherit (config) version;
};
submodule = mkOption {
description = "Name of the submodule to use";
type = types.str;
default = name;
};
# definition of a submodule
submoduleDefinition = submodule.definition;
version = mkOption {
description = ''
Version of submodule to use, if version starts with "~" it is
threated as regex pattern for example "~1.0.*"
'';
type = types.nullOr types.str;
default = null;
# submodule defaults
defaults = getDefaults {
inherit (submoduleDefinition) name;
inherit (submoduleDefinition) version;
inherit (submoduleDefinition) tags;
inherit (submodule) features;
};
in
{
options = {
name = mkOption {
description = "Submodule instance name";
type = types.str;
default = name;
};
passthru.enable = mkOption {
description = "Whether to passthru submodule resources";
type = types.bool;
default = true;
};
submodule = mkOption {
description = "Name of the submodule to use";
type = types.str;
default = name;
};
config = mkOption {
description = "Submodule instance ${config.name} for ${submoduleDefinition.name}:${submoduleDefinition.version} config";
type =
submoduleWithSpecialArgs
({...}: {
imports = submodule.modules ++ defaults ++ [./base.nix];
_module.args.pkgs = pkgs;
_module.args.name = config.name;
_module.args.submodule = config;
submodule.args = mkAliasDefinitions options.args;
})
specialArgs;
default = {};
};
version = mkOption {
description = ''
Version of submodule to use, if version starts with "~" it is
threated as regex pattern for example "~1.0.*"
'';
type = types.nullOr types.str;
default = null;
};
args = mkOption {
description = "Submodule arguments (alias of config.submodule.args)";
passthru.enable = mkOption {
description = "Whether to passthru submodule resources";
type = types.bool;
default = true;
};
config = mkOption {
description = "Submodule instance ${config.name} for ${submoduleDefinition.name}:${submoduleDefinition.version} config";
type = submoduleWithSpecialArgs
({ ... }: {
imports = submodule.modules ++ defaults ++ [ ./base.nix ];
_module.args.pkgs = pkgs;
_module.args.name = config.name;
_module.args.submodule = config;
submodule.args = mkAliasDefinitions options.args;
})
specialArgs;
default = { };
};
args = mkOption {
description = "Submodule arguments (alias of config.submodule.args)";
};
};
};
}));
}));
};
default = {};
default = { };
};
config = mkMerge ([
{
# register exported functions as args
_module.args = mkMerge (map
(submodule: {
${submodule.exportAs} = submodule.definition.exports;
{
# register exported functions as args
_module.args = mkMerge (map
(submodule: {
${submodule.exportAs} = submodule.definition.exports;
})
(filter (submodule: submodule.exportAs != null) cfg.imports));
_m.features = [ "submodules" ];
submodules.specialArgs.kubenix = kubenix;
# passthru kubenix.project to submodules
submodules.defaults = mkMerge [
[{
default = {
kubenix.project = parentConfig.kubenix.project;
};
}]
(map
(propagate: {
inherit (propagate) features;
default = propagate.module;
})
(filter (submodule: submodule.exportAs != null) cfg.imports));
config._m.propagate)
];
}
_m.features = ["submodules"];
submodules.specialArgs.kubenix = kubenix;
# passthru kubenix.project to submodules
submodules.defaults = mkMerge [
[
{
default = {
kubenix.project = parentConfig.kubenix.project;
};
}
]
(map
(propagate: {
inherit (propagate) features;
default = propagate.module;
})
config._m.propagate)
];
}
(mkIf cfg.propagate.enable {
# if propagate is enabled and submodule has submodules included propagage defaults and imports
submodules.defaults = [
{
features = ["submodules"];
default = {
submodules = {
inherit (cfg) defaults;
inherit (cfg) imports;
};
};
}
];
})
]
++ passthruConfig);
(mkIf cfg.propagate.enable {
# if propagate is enabled and submodule has submodules included propagage defaults and imports
submodules.defaults = [{
features = [ "submodules" ];
default = {
submodules = {
inherit (cfg) defaults;
inherit (cfg) imports;
};
};
}];
})
]
++ passthruConfig);
}

View file

@ -1,15 +1,9 @@
{
config,
pkgs,
lib,
kubenix,
...
}:
{ config, pkgs, lib, kubenix, ... }:
with lib; let
cfg = config.testing;
testModule = {
imports = [./evalTest.nix];
imports = [ ./evalTest.nix ];
# passthru testing configuration
config._module.args = {
@ -18,9 +12,9 @@ with lib; let
};
};
isTestEnabled = test:
(cfg.enabledTests == null || elem test.name cfg.enabledTests) && test.enable;
in {
isTestEnabled = test: (cfg.enabledTests == null || elem test.name cfg.enabledTests) && test.enable;
in
{
imports = [
./docker.nix
./driver/kubetest.nix
@ -48,23 +42,23 @@ in {
features = mkOption {
description = "List of features that test has to have to apply options";
type = types.listOf types.str;
default = [];
default = [ ];
};
options = mkOption {
description = "Options to apply to test";
type = types.unspecified;
default = {};
apply = default: {_file = "testing.common";} // default;
default = { };
apply = default: { _file = "testing.common"; } // default;
};
};
}));
default = [];
default = [ ];
};
tests = mkOption {
description = "List of test cases";
default = [];
default = [ ];
type = types.listOf (types.coercedTo types.path
(module: {
inherit module;
@ -88,7 +82,7 @@ in {
args = mkOption {
description = "Attribute set of extra args passed to tests";
type = types.attrs;
default = {};
default = { };
};
success = mkOption {

View file

@ -1,17 +1,13 @@
{
config,
lib,
pkgs,
...
}:
{ config, lib, pkgs, ... }:
with lib;
with import ../../lib/docker {inherit lib pkgs;}; let
with import ../../lib/docker { inherit lib pkgs; }; let
inherit (config) testing;
allImages = unique (flatten (map (t: t.evaled.config.docker.export or []) testing.tests));
allImages = unique (flatten (map (t: t.evaled.config.docker.export or [ ]) testing.tests));
cfg = config.testing.docker;
in {
in
{
options.testing.docker = {
registryUrl = mkOption {
description = "Docker registry url";
@ -38,13 +34,11 @@ in {
};
};
config.testing.common = [
{
features = ["docker"];
options = {
_file = "testing.docker.registryUrl";
docker.registry.url = cfg.registryUrl;
};
}
];
config.testing.common = [{
features = [ "docker" ];
options = {
_file = "testing.docker.registryUrl";
docker.registry.url = cfg.registryUrl;
};
}];
}

View file

@ -1,23 +1,15 @@
{
lib,
config,
pkgs,
...
}:
{ lib, config, pkgs, ... }:
with lib; let
inherit (config) testing;
cfg = testing.driver.kubetest;
kubetest = import ./kubetestdrv.nix {inherit pkgs;};
kubetest = import ./kubetestdrv.nix { inherit pkgs; };
pythonEnv = pkgs.python38.withPackages (ps:
with ps;
[
pytest
kubetest
kubernetes
]
++ cfg.extraPackages);
pythonEnv = pkgs.python38.withPackages (ps: with ps; [
pytest
kubetest
kubernetes
] ++ cfg.extraPackages);
toTestScript = t:
if isString t.script
@ -28,26 +20,29 @@ with lib; let
''
else t.script;
tests = let
# make sure tests are prefixed so that alphanumerical
# sorting reproduces them in the same order as they
# have been declared in the list.
seive = t: t.script != null && t.enabled;
allEligibleTests = filter seive testing.tests;
listLengthPadding = builtins.length (
lib.stringToCharacters (
builtins.toString (
builtins.length allEligibleTests
tests =
let
# make sure tests are prefixed so that alphanumerical
# sorting reproduces them in the same order as they
# have been declared in the list.
seive = t: t.script != null && t.enabled;
allEligibleTests = filter seive testing.tests;
listLengthPadding = builtins.length (
lib.stringToCharacters (
builtins.toString (
builtins.length allEligibleTests
)
)
)
);
op = i: t: {
path = toTestScript t;
name = let
prefix = lib.fixedWidthNumber listLengthPadding i;
in "${prefix}_${t.name}_test.py";
};
in
);
op = i: t: {
path = toTestScript t;
name =
let
prefix = lib.fixedWidthNumber listLengthPadding i;
in
"${prefix}_${t.name}_test.py";
};
in
pkgs.linkFarm "${testing.name}-tests" (
lib.imap0 op allEligibleTests
);
@ -56,7 +51,8 @@ with lib; let
#!/usr/bin/env bash
${pythonEnv}/bin/pytest -p no:cacheprovider ${tests} $@
'';
in {
in
{
options.testing.driver.kubetest = {
defaultHeader = mkOption {
type = types.lines;
@ -69,7 +65,7 @@ in {
extraPackages = mkOption {
type = types.listOf types.package;
description = "Extra packages to pass to tests";
default = [];
default = [ ];
};
};

View file

@ -1,14 +1,14 @@
{pkgs ? import <nixpkgs> {}}:
{ pkgs ? import <nixpkgs> { } }:
with pkgs;
with pkgs.python38Packages;
with pkgs.python38;
pkgs.python38Packages.buildPythonPackage rec {
pname = "kubetest";
version = "0.9.5";
src = fetchPypi {
inherit pname version;
sha256 = "sha256-TqDHMciAEXv4vMWLJY1YdtXsP4ho+INgdFB3xQQNoZU=";
};
propagatedBuildInputs = [pytest kubernetes];
doCheck = false;
}
pkgs.python38Packages.buildPythonPackage rec {
pname = "kubetest";
version = "0.9.5";
src = fetchPypi {
inherit pname version;
sha256 = "sha256-TqDHMciAEXv4vMWLJY1YdtXsP4ho+INgdFB3xQQNoZU=";
};
propagatedBuildInputs = [ pytest kubernetes ];
doCheck = false;
}

View file

@ -1,10 +1,4 @@
{
lib,
config,
testing,
kubenix,
...
}:
{ lib, config, testing, kubenix, ... }:
with lib; let
modules = [
# testing module
@ -29,13 +23,9 @@ with lib; let
# eval without checking
evaled' = kubenix.evalModules {
modules =
modules
++ [
{
_module.args.check = false;
}
];
modules = modules ++ [{
_module.args.check = false;
}];
};
# test configuration
@ -45,13 +35,11 @@ with lib; let
testFeatures = evaled'.config._m.features;
# common options that can be applied on this test
commonOpts =
filter
(
d:
(intersectLists d.features testFeatures)
== d.features
|| (length d.features) == 0
commonOpts = filter
(d:
(intersectLists d.features testFeatures)
== d.features
|| (length d.features) == 0
)
testing.common;
@ -59,17 +47,19 @@ with lib; let
modulesWithCommonOptions = modules ++ (map (d: d.options) commonOpts);
# evaled test
evaled = let
evaled' = kubenix.evalModules {
modules = modulesWithCommonOptions;
};
in
evaled =
let
evaled' = kubenix.evalModules {
modules = modulesWithCommonOptions;
};
in
if testing.doThrowError
then evaled'
else if (builtins.tryEval evaled'.config.test.assertions).success
then evaled'
else null;
in {
in
{
options = {
module = mkOption {
description = "Module defining kubenix test";
@ -112,7 +102,7 @@ in {
description = "Test result";
type = types.unspecified;
internal = true;
default = [];
default = [ ];
};
script = mkOption {

View file

@ -1,9 +1,4 @@
{
lib,
config,
pkgs,
...
}:
{ lib, config, pkgs, ... }:
with lib; let
inherit (config) testing;
@ -34,7 +29,8 @@ with lib; let
echo "--> running tests"
${testing.testScript} --kube-config=$KUBECONFIG
'';
in {
in
{
options.testing.runtime.local = {
script = mkOption {
type = types.package;

View file

@ -1,10 +1,5 @@
# nixos-k8s implements nixos kubernetes testing runtime
{
config,
pkgs,
lib,
...
}:
{ config, pkgs, lib, ... }:
with lib; let
inherit (config) testing;
# kubeconfig = "/etc/${config.services.kubernetes.pki.etcClusterAdminKubeconfig}";
@ -12,15 +7,15 @@ with lib; let
kubecerts = "/var/lib/kubernetes/secrets";
# how we differ from the standard configuration of mkKubernetesBaseTest
extraConfiguration = {config, ...}: {
extraConfiguration = { config, ... }: {
virtualisation = {
memorySize = 2048;
};
networking = {
nameservers = ["10.0.0.254"];
nameservers = [ "10.0.0.254" ];
firewall = {
trustedInterfaces = ["docker0" "cni0"];
trustedInterfaces = [ "docker0" "cni0" ];
};
};
@ -29,26 +24,22 @@ with lib; let
kubelet = {
seedDockerImages = testing.docker.images;
networkPlugin = "cni";
cni.config = [
{
name = "mynet";
type = "bridge";
bridge = "cni0";
addIf = true;
ipMasq = true;
isGateway = true;
ipam = {
type = "host-local";
subnet = "10.1.0.0/16";
gateway = "10.1.0.1";
routes = [
{
dst = "0.0.0.0/0";
}
];
};
}
];
cni.config = [{
name = "mynet";
type = "bridge";
bridge = "cni0";
addIf = true;
ipMasq = true;
isGateway = true;
ipam = {
type = "host-local";
subnet = "10.1.0.0/16";
gateway = "10.1.0.1";
routes = [{
dst = "0.0.0.0/0";
}];
};
}];
};
};
@ -58,8 +49,8 @@ with lib; let
services.copy-certs = {
description = "Share k8s certificates with host";
script = "cp -rf ${kubecerts} /tmp/xchg/; cp -f ${kubeconfig} /tmp/xchg/;";
after = ["kubernetes.target"];
wantedBy = ["multi-user.target"];
after = [ "kubernetes.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
@ -72,16 +63,18 @@ with lib; let
machine1.succeed("${testing.testScript} --kube-config=${kubeconfig}")
'';
test = with import "${pkgs.path}/nixos/tests/kubernetes/base.nix" {
inherit pkgs;
inherit (pkgs) system;
};
test = with import "${pkgs.path}/nixos/tests/kubernetes/base.nix"
{
inherit pkgs;
inherit (pkgs) system;
};
mkKubernetesSingleNodeTest {
inherit extraConfiguration;
inherit (config.testing) name;
test = script;
};
in {
in
{
options.testing.runtime.nixos-k8s = {
driver = mkOption {
description = "Test driver";

View file

@ -1,8 +1,4 @@
{
lib,
config,
...
}:
{ lib, config, ... }:
with lib; {
options.test = {
name = mkOption {
@ -36,13 +32,11 @@ with lib; {
};
};
});
default = [];
example = [
{
assertion = false;
message = "you can't enable this for some reason";
}
];
default = [ ];
example = [{
assertion = false;
message = "you can't enable this for some reason";
}];
description = ''
This option allows modules to express conditions that must
hold for the evaluation of the system configuration to