mirror of
https://github.com/TECHNOFAB11/kubenix.git
synced 2025-12-12 16:10:05 +01:00
Refactor:
- Support for module features - Remove kubenix.module and rather use explicit modules - Make tests framework independent of k8s module - Remove metacontroller submodule, which will go to kubenix-modules - Improved submodule propagation and passthru - Added additional test for k8s-submodule
This commit is contained in:
parent
b670139906
commit
6183fcc190
30 changed files with 513 additions and 508 deletions
|
|
@ -3,4 +3,4 @@ script:
|
||||||
- nix-env -iA nixpkgs.jq
|
- nix-env -iA nixpkgs.jq
|
||||||
- nix build -f ./release.nix test-results --arg e2e false
|
- nix build -f ./release.nix test-results --arg e2e false
|
||||||
- cat result | jq '.'
|
- cat result | jq '.'
|
||||||
- nix eval -f ./release.nix --arg e2e false tests-check
|
- nix eval -f ./release.nix --arg e2e false test-check
|
||||||
|
|
|
||||||
|
|
@ -13,19 +13,20 @@ kubernetes resources very easyly.
|
||||||
### Building tests
|
### Building tests
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
nix-build release.nix -A tests.results --show-trace
|
nix-build release.nix -A tests-results --show-trace
|
||||||
```
|
```
|
||||||
|
|
||||||
**Building single e2e test**
|
**Building single e2e test**
|
||||||
|
|
||||||
```
|
```
|
||||||
nix-build release.nix -A tests.tests.v1_10.testing.testsByName.<name>.script
|
cd tests
|
||||||
|
nix-build release.nix -A tests.k8s-1_10.testsByName.<test-name>.test
|
||||||
```
|
```
|
||||||
|
|
||||||
**Debugging e2e test**
|
**Debugging e2e test**
|
||||||
|
|
||||||
```
|
```
|
||||||
nix-build release.nix -A tests.tests.v1_10.testing.testsByName.<name>.script.driver
|
nix-build release.nix -A tests.k8s-1_10.testsByName.<test-name>.test.driver
|
||||||
resut/bin/nixos-test-driver
|
resut/bin/nixos-test-driver
|
||||||
testScript;
|
testScript;
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,5 @@ let
|
||||||
inherit evalModules modules;
|
inherit evalModules modules;
|
||||||
|
|
||||||
lib = kubenixLib;
|
lib = kubenixLib;
|
||||||
module = modules.module;
|
|
||||||
};
|
};
|
||||||
in kubenix
|
in kubenix
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ with lib;
|
||||||
let
|
let
|
||||||
nginx = pkgs.callPackage ./image.nix { };
|
nginx = pkgs.callPackage ./image.nix { };
|
||||||
in {
|
in {
|
||||||
imports = [ kubenix.module ];
|
imports = with kubenix.modules; [ k8s docker ];
|
||||||
|
|
||||||
docker.images.nginx.image = nginx;
|
docker.images.nginx.image = nginx;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,6 @@ rec {
|
||||||
|
|
||||||
else value;
|
else value;
|
||||||
|
|
||||||
mkOptionDefault = mkOverride 1001;
|
|
||||||
|
|
||||||
mkAllDefault = value: priority:
|
mkAllDefault = value: priority:
|
||||||
if isAttrs value
|
if isAttrs value
|
||||||
then mapAttrs (n: v: mkAllDefault v priority) value
|
then mapAttrs (n: v: mkAllDefault v priority) value
|
||||||
|
|
|
||||||
19
modules/base.nix
Normal file
19
modules/base.nix
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
options._module.features = mkOption {
|
||||||
|
description = "List of features exposed by module";
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
options.kubenix = {
|
||||||
|
project = mkOption {
|
||||||
|
description = "Name of the project";
|
||||||
|
type = types.str;
|
||||||
|
default = "kubenix";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -2,9 +2,9 @@
|
||||||
k8s = ./k8s.nix;
|
k8s = ./k8s.nix;
|
||||||
istio = ./istio.nix;
|
istio = ./istio.nix;
|
||||||
submodules = ./submodules.nix;
|
submodules = ./submodules.nix;
|
||||||
|
submodule = ./submodule.nix;
|
||||||
helm = ./helm.nix;
|
helm = ./helm.nix;
|
||||||
docker = ./docker.nix;
|
docker = ./docker.nix;
|
||||||
metacontroller = ./metacontroller;
|
|
||||||
testing = ./testing.nix;
|
testing = ./testing.nix;
|
||||||
test = ./test.nix;
|
test = ./test.nix;
|
||||||
module = ./module.nix;
|
module = ./module.nix;
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,16 @@
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
globalConfig = config;
|
cfg = config.docker;
|
||||||
in {
|
in {
|
||||||
options.docker.registry.url = mkOption {
|
options.docker = {
|
||||||
|
registry.url = mkOption {
|
||||||
description = "Default registry url where images are published";
|
description = "Default registry url where images are published";
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "";
|
default = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
options.docker.images = mkOption {
|
images = mkOption {
|
||||||
description = "Attribute set of docker images that should be published";
|
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 = {
|
options = {
|
||||||
|
|
@ -36,7 +37,7 @@ in {
|
||||||
registry = mkOption {
|
registry = mkOption {
|
||||||
description = "Docker registry url where image is published";
|
description = "Docker registry url where image is published";
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = globalConfig.docker.registry.url;
|
default = cfg.registry.url;
|
||||||
};
|
};
|
||||||
|
|
||||||
path = mkOption {
|
path = mkOption {
|
||||||
|
|
@ -52,12 +53,27 @@ in {
|
||||||
default = {};
|
default = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
options.docker.export = mkOption {
|
export = mkOption {
|
||||||
description = "List of images to export";
|
description = "List of images to export";
|
||||||
type = types.listOf (types.package);
|
type = types.listOf (types.package);
|
||||||
default = [];
|
default = [];
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
config.docker.export = mapAttrsToList (_: i: i.image)
|
config = {
|
||||||
(filterAttrs (_: i: i.registry != null)config.docker.images);
|
_module.features = ["docker"];
|
||||||
|
|
||||||
|
docker.export = mkMerge [
|
||||||
|
(mapAttrsToList (_: i: i.image)
|
||||||
|
(filterAttrs (_: i: i.registry != null) config.docker.images))
|
||||||
|
|
||||||
|
# passthru of docker exported images if passthru is enabled on submodule
|
||||||
|
# and submodule has docker module loaded
|
||||||
|
(flatten (mapAttrsToList (_: submodule:
|
||||||
|
optionals
|
||||||
|
(submodule.passthru.enable && (elem "docker" submodule.config._module.features))
|
||||||
|
submodule.config.docker.export
|
||||||
|
) config.submodules.instances))
|
||||||
|
];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,6 @@ let
|
||||||
in {
|
in {
|
||||||
imports = [ ./k8s.nix ];
|
imports = [ ./k8s.nix ];
|
||||||
|
|
||||||
# expose helm helper methods as module argument
|
|
||||||
config._module.args.helm = import ../lib/helm { inherit pkgs; };
|
|
||||||
|
|
||||||
options.kubernetes.helm = {
|
options.kubernetes.helm = {
|
||||||
instances = mkOption {
|
instances = mkOption {
|
||||||
description = "Attribute set of helm instances";
|
description = "Attribute set of helm instances";
|
||||||
|
|
@ -84,7 +81,7 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
config.overrides = mkIf (config.overrideNamespace && config.namespace != null) [{
|
config.overrides = mkIf (config.overrideNamespace && config.namespace != null) [{
|
||||||
metadata.namespace = mkDefault config.namespace;
|
metadata.namespace = config.namespace;
|
||||||
}];
|
}];
|
||||||
|
|
||||||
config.objects = importJSON (helm.chart2json {
|
config.objects = importJSON (helm.chart2json {
|
||||||
|
|
@ -94,7 +91,11 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config.kubernetes.api = mkMerge (flatten (mapAttrsToList (_: instance:
|
config = {
|
||||||
|
# expose helm helper methods as module argument
|
||||||
|
_module.args.helm = import ../lib/helm { inherit pkgs; };
|
||||||
|
|
||||||
|
kubernetes.api = mkMerge (flatten (mapAttrsToList (_: instance:
|
||||||
map (object: let
|
map (object: let
|
||||||
apiVersion = parseApiVersion object.apiVersion;
|
apiVersion = parseApiVersion object.apiVersion;
|
||||||
name = object.metadata.name;
|
name = object.metadata.name;
|
||||||
|
|
@ -104,4 +105,5 @@ in {
|
||||||
] ++ instance.overrides);
|
] ++ instance.overrides);
|
||||||
}) instance.objects
|
}) instance.objects
|
||||||
) cfg.instances));
|
) cfg.instances));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,12 @@ let
|
||||||
default = null;
|
default = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
propagate = mkOption {
|
||||||
|
description = "Whether to propagate default";
|
||||||
|
type = types.bool;
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
|
||||||
default = mkOption {
|
default = mkOption {
|
||||||
description = "Default to apply";
|
description = "Default to apply";
|
||||||
type = types.unspecified;
|
type = types.unspecified;
|
||||||
|
|
@ -164,16 +170,22 @@ let
|
||||||
};
|
};
|
||||||
}) cfg.customResources;
|
}) cfg.customResources;
|
||||||
in {
|
in {
|
||||||
# expose k8s helper methods as module argument
|
imports = [ ./base.nix ./submodules.nix ];
|
||||||
config._module.args.k8s = import ../lib/k8s.nix { inherit lib; };
|
|
||||||
|
|
||||||
options.kubernetes.version = mkOption {
|
options.kubernetes = {
|
||||||
|
version = mkOption {
|
||||||
description = "Kubernetes version to use";
|
description = "Kubernetes version to use";
|
||||||
type = types.enum ["1.7" "1.8" "1.9" "1.10" "1.11" "1.12" "1.13"];
|
type = types.enum ["1.7" "1.8" "1.9" "1.10" "1.11" "1.12" "1.13"];
|
||||||
default = "1.13";
|
default = "1.13";
|
||||||
};
|
};
|
||||||
|
|
||||||
options.kubernetes.resourceOrder = mkOption {
|
namespace = mkOption {
|
||||||
|
description = "Default namespace where to deploy kubernetes resources";
|
||||||
|
type = types.str;
|
||||||
|
default = "default";
|
||||||
|
};
|
||||||
|
|
||||||
|
resourceOrder = mkOption {
|
||||||
description = "Preffered resource order";
|
description = "Preffered resource order";
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = [
|
default = [
|
||||||
|
|
@ -182,7 +194,7 @@ in {
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
options.kubernetes.api = mkOption {
|
api = mkOption {
|
||||||
type = types.submodule {
|
type = types.submodule {
|
||||||
imports = [
|
imports = [
|
||||||
(./generated + ''/v'' + cfg.version + ".nix")
|
(./generated + ''/v'' + cfg.version + ".nix")
|
||||||
|
|
@ -192,7 +204,7 @@ in {
|
||||||
default = {};
|
default = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
options.kubernetes.customResources = mkOption {
|
customResources = mkOption {
|
||||||
default = [];
|
default = [];
|
||||||
description = "List of custom resource definitions to make API for";
|
description = "List of custom resource definitions to make API for";
|
||||||
type = types.listOf (types.submodule ({config, ...}: {
|
type = types.listOf (types.submodule ({config, ...}: {
|
||||||
|
|
@ -238,11 +250,7 @@ in {
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
config.kubernetes.api.resources = map (cr: {
|
objects = mkOption {
|
||||||
inherit (cr) group version kind resource;
|
|
||||||
}) cfg.customResources;
|
|
||||||
|
|
||||||
options.kubernetes.objects = mkOption {
|
|
||||||
description = "List of generated kubernetes objects";
|
description = "List of generated kubernetes objects";
|
||||||
type = types.listOf types.attrs;
|
type = types.listOf types.attrs;
|
||||||
apply = items: sort (r1: r2:
|
apply = items: sort (r1: r2:
|
||||||
|
|
@ -253,18 +261,71 @@ in {
|
||||||
default = [];
|
default = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
config.kubernetes.objects = flatten (map (gvk:
|
generated = mkOption {
|
||||||
mapAttrsToList (name: resource:
|
|
||||||
removeKubenixOptions (moduleToAttrs resource)
|
|
||||||
) cfg.api.${gvk.group}.${gvk.version}.${gvk.kind}
|
|
||||||
) cfg.api.resources);
|
|
||||||
|
|
||||||
options.kubernetes.generated = mkOption {
|
|
||||||
description = "Generated kubernetes list object";
|
description = "Generated kubernetes list object";
|
||||||
type = types.attrs;
|
type = types.attrs;
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
config.kubernetes.generated = k8s.mkHashedList {
|
config = {
|
||||||
|
# expose k8s helper methods as module argument
|
||||||
|
_module.args.k8s = import ../lib/k8s.nix { inherit lib; };
|
||||||
|
|
||||||
|
_module.features = [ "k8s" ];
|
||||||
|
|
||||||
|
kubernetes.api.resources = map (cr: {
|
||||||
|
inherit (cr) group version kind resource;
|
||||||
|
}) cfg.customResources;
|
||||||
|
|
||||||
|
kubernetes.objects = mkMerge [
|
||||||
|
# gvk resources
|
||||||
|
(flatten (map (gvk:
|
||||||
|
mapAttrsToList (name: resource:
|
||||||
|
removeKubenixOptions (moduleToAttrs resource)
|
||||||
|
) cfg.api.${gvk.group}.${gvk.version}.${gvk.kind}
|
||||||
|
) cfg.api.resources))
|
||||||
|
|
||||||
|
# passthru of child kubernetes objects if passthru is enabled on submodule
|
||||||
|
# and submodule has k8s module loaded
|
||||||
|
(flatten (mapAttrsToList (_: submodule:
|
||||||
|
optionals
|
||||||
|
(submodule.passthru.enable && (elem "k8s" submodule.config._module.features))
|
||||||
|
submodule.config.kubernetes.objects
|
||||||
|
) config.submodules.instances))
|
||||||
|
];
|
||||||
|
|
||||||
|
kubernetes.generated = k8s.mkHashedList {
|
||||||
items = config.kubernetes.objects;
|
items = config.kubernetes.objects;
|
||||||
|
labels."kubenix/project-name" = config.kubenix.project;
|
||||||
|
};
|
||||||
|
|
||||||
|
kubernetes.api.defaults = [{
|
||||||
|
default = {
|
||||||
|
metadata.namespace = mkDefault config.kubernetes.namespace;
|
||||||
|
metadata.labels = mkMerge [
|
||||||
|
{
|
||||||
|
"kubenix/project-name" = config.kubenix.project;
|
||||||
|
}
|
||||||
|
|
||||||
|
# if we are inside submodule, define additional labels
|
||||||
|
(mkIf (elem "submodule" config._module.features) {
|
||||||
|
"kubenix/module-name" = config.submodule.name;
|
||||||
|
"kubenix/module-version" = config.submodule.version;
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
|
||||||
|
submodules.defaults = [{
|
||||||
|
features = [ "k8s" ];
|
||||||
|
default = { config, name, ... }: {
|
||||||
|
# propagate kubernetes version and namespace
|
||||||
|
kubernetes.version = mkDefault cfg.version;
|
||||||
|
kubernetes.namespace = mkDefault cfg.namespace;
|
||||||
|
|
||||||
|
# propagate defaults if default propagation is enabled
|
||||||
|
kubernetes.api.defaults = filter (default: default.propagate) cfg.api.defaults;
|
||||||
|
};
|
||||||
|
}];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,139 +0,0 @@
|
||||||
{ config, lib, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
{
|
|
||||||
options = {
|
|
||||||
parentResource = {
|
|
||||||
apiVersion = mkOption {
|
|
||||||
description = "Parent resource apiVersion";
|
|
||||||
type = types.str;
|
|
||||||
example = "apps/v1";
|
|
||||||
};
|
|
||||||
|
|
||||||
resource = mkOption {
|
|
||||||
description = "The canonical, lowercase, plural name of the parent resource";
|
|
||||||
type = types.str;
|
|
||||||
example = "deployments";
|
|
||||||
};
|
|
||||||
|
|
||||||
revisionHistory = mkOption {
|
|
||||||
description = "A list of field path strings specifying which parent fields trigger rolling updates of children";
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = ["spec"];
|
|
||||||
example = ["spec.template"];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
childResources = mkOption {
|
|
||||||
description = "A list of resource rules specifying the child resources";
|
|
||||||
type = types.listOf (types.submodule ({ config, ... }: {
|
|
||||||
options = {
|
|
||||||
apiVersion = mkOption {
|
|
||||||
description = "The API group/version of the child resource, or just version for core APIs";
|
|
||||||
type = types.str;
|
|
||||||
example = "apps/v1";
|
|
||||||
};
|
|
||||||
|
|
||||||
resource = mkOption {
|
|
||||||
description = "The canonical, lowercase, plural name of the child resource";
|
|
||||||
type = types.str;
|
|
||||||
example = "deployments";
|
|
||||||
};
|
|
||||||
|
|
||||||
updateStrategy = {
|
|
||||||
method = mkOption {
|
|
||||||
description = ''
|
|
||||||
A string indicating the overall method that should be used for updating this type of child resource.
|
|
||||||
The default is OnDelete, which means don't try to update children that already exist.
|
|
||||||
|
|
||||||
- OnDelete: Don't update existing children unless they get deleted by some other agent.
|
|
||||||
- Recreate: Immediately delete any children that differ from the desired state, and recreate them in the desired state.
|
|
||||||
- InPlace: Immediately update any children that differ from the desired state.
|
|
||||||
- RollingRecreate: Delete each child that differs from the desired state, one at a time,
|
|
||||||
and recreate each child before moving on to the next one.
|
|
||||||
Pause the rollout if at any time one of the children that have already been updated fails one or more status checks.
|
|
||||||
- RollingInPlace: Update each child that differs from the desired state, one at a time. Pause the rollout if at any time
|
|
||||||
one of the children that have already been updated fails one or more status checks.
|
|
||||||
'';
|
|
||||||
type = types.enum [
|
|
||||||
"OnDelete"
|
|
||||||
"Recreate"
|
|
||||||
"InPlace"
|
|
||||||
"RollingRecreate"
|
|
||||||
"RollingInPlace"
|
|
||||||
];
|
|
||||||
default = "OnDelete";
|
|
||||||
};
|
|
||||||
|
|
||||||
statusChecks.conditions = mkOption {
|
|
||||||
description = ''
|
|
||||||
A list of status condition checks that must all pass on already-updated
|
|
||||||
children for the rollout to continue.
|
|
||||||
'';
|
|
||||||
type = types.listOf (types.submodule ({ config, ... }: {
|
|
||||||
options = {
|
|
||||||
type = mkOption {
|
|
||||||
description = "A string specifying the status condition type to check.";
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
status = mkOption {
|
|
||||||
description = ''
|
|
||||||
A string specifying the required status of the given status condition.
|
|
||||||
If none is specified, the condition's status is not checked.
|
|
||||||
'';
|
|
||||||
type = types.str;
|
|
||||||
default = "";
|
|
||||||
};
|
|
||||||
|
|
||||||
reason = mkOption {
|
|
||||||
description = ''
|
|
||||||
A string specifying the required reason of the given status condition.
|
|
||||||
If none is specified, the condition's reason is not checked.
|
|
||||||
'';
|
|
||||||
type = types.str;
|
|
||||||
default = "";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
default = [];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
default = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
resyncPeriodSeconds = mkOption {
|
|
||||||
description = ''
|
|
||||||
How often, in seconds, you want every parent object to be resynced,
|
|
||||||
even if no changes are detected.
|
|
||||||
'';
|
|
||||||
type = types.int;
|
|
||||||
default = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
generateSelector = mkOption {
|
|
||||||
description = ''
|
|
||||||
If true, ignore the selector in each parent object and instead generate
|
|
||||||
a unique selector that prevents overlap with other objects.
|
|
||||||
'';
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
hooks = {
|
|
||||||
sync.webhook.url = mkOption {
|
|
||||||
description = "Webhook URL where to send sync request";
|
|
||||||
type = types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
finalize.webhook.url = mkOption {
|
|
||||||
description = "Webhook URL where to send finalize request";
|
|
||||||
type = types.str;
|
|
||||||
default = "";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
{ config, lib, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
{
|
|
||||||
imports = [ ../k8s.nix ];
|
|
||||||
|
|
||||||
options.metacontroller = {
|
|
||||||
compositeControllers = mkOption {
|
|
||||||
type = types.attrsOf (types.submodule ({ name, config, ... }: {
|
|
||||||
imports = [ ./compositecontroller.nix ];
|
|
||||||
|
|
||||||
options = {
|
|
||||||
name = mkOption {
|
|
||||||
description = "Name of the composite controller";
|
|
||||||
type = types.str;
|
|
||||||
default = name;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
default = {};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
kubernetes.customResources = [{
|
|
||||||
group = "metacontroller.k8s.io";
|
|
||||||
version = "v1alpha1";
|
|
||||||
kind = "CompositeController";
|
|
||||||
resource = "compositecontrollers";
|
|
||||||
description = "Composite controller";
|
|
||||||
alias = "compositecontrollers";
|
|
||||||
module.imports = [ ./compositecontroller.nix ];
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
# module.nix defines default kubenix module with additional helper options
|
|
||||||
# and preincluded kubenix module definitions for kubernetes, docker and
|
|
||||||
# kubenix submodules
|
|
||||||
|
|
||||||
{ config, lib, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
parentConfig = config;
|
|
||||||
in {
|
|
||||||
imports = [ ./k8s.nix ./docker.nix ./submodules.nix ];
|
|
||||||
|
|
||||||
options = {
|
|
||||||
kubenix.release = mkOption {
|
|
||||||
description = "Name of the release";
|
|
||||||
type = types.str;
|
|
||||||
default = "default";
|
|
||||||
};
|
|
||||||
|
|
||||||
kubernetes.propagateDefaults = mkOption {
|
|
||||||
description = "Whether to propagate child defaults to submodules";
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
submodules.instances = mkOption {
|
|
||||||
type = types.attrsOf (types.submodule ({config, ...}: {
|
|
||||||
options = {
|
|
||||||
namespace = mkOption {
|
|
||||||
description = "Default kubernetes namespace";
|
|
||||||
type = types.str;
|
|
||||||
default = "default";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config.config = {
|
|
||||||
kubernetes.api.defaults = [{
|
|
||||||
default.metadata.namespace = mkDefault config.namespace;
|
|
||||||
}];
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
submodules.defaults = [{
|
|
||||||
default = {
|
|
||||||
imports = [ ./module.nix ];
|
|
||||||
kubernetes.version = mkDefault config.kubernetes.version;
|
|
||||||
kubernetes.api.defaults =
|
|
||||||
mkIf config.kubernetes.propagateDefaults config.kubernetes.api.defaults;
|
|
||||||
};
|
|
||||||
} {
|
|
||||||
default = ({config, ...}: {
|
|
||||||
kubenix.release = parentConfig.kubenix.release;
|
|
||||||
kubernetes.api.defaults = [{
|
|
||||||
default.metadata.labels = {
|
|
||||||
"kubenix/release-name" = config.kubenix.release;
|
|
||||||
"kubenix/module-name" = config.submodule.name;
|
|
||||||
"kubenix/module-version" = config.submodule.version;
|
|
||||||
};
|
|
||||||
}];
|
|
||||||
});
|
|
||||||
}];
|
|
||||||
|
|
||||||
kubernetes.objects = mkMerge (mapAttrsToList (_: submodule:
|
|
||||||
submodule.config.kubernetes.objects
|
|
||||||
) config.submodules.instances);
|
|
||||||
|
|
||||||
docker.export = mkMerge (mapAttrsToList (_: submodule:
|
|
||||||
submodule.config.docker.export
|
|
||||||
) config.submodules.instances);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
40
modules/submodule.nix
Normal file
40
modules/submodule.nix
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [ ./base.nix ];
|
||||||
|
|
||||||
|
options.submodule = {
|
||||||
|
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 = "1.0.0";
|
||||||
|
};
|
||||||
|
|
||||||
|
tags = mkOption {
|
||||||
|
description = "List of submodule tags";
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
passthru = mkOption {
|
||||||
|
description = "Attribute set to passthru to parent";
|
||||||
|
default = {};
|
||||||
|
type = types.attrs;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config._module.features = ["submodule"];
|
||||||
|
}
|
||||||
|
|
@ -4,13 +4,18 @@ with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.submodules;
|
cfg = config.submodules;
|
||||||
|
parentConfig = config;
|
||||||
|
|
||||||
getDefaults = name: tags:
|
getDefaults = {name, tags, features}:
|
||||||
catAttrs "default" (filter (submodule:
|
catAttrs "default" (filter (submodule:
|
||||||
(submodule.name == null || submodule.name == name) &&
|
(submodule.name == null || submodule.name == name) &&
|
||||||
(
|
(
|
||||||
(length submodule.tags == 0) ||
|
(length submodule.tags == 0) ||
|
||||||
(length (intersectLists submodule.tags tags)) > 0
|
(length (intersectLists submodule.tags tags)) > 0
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
(length submodule.features == 0) ||
|
||||||
|
(length (intersectLists submodule.features features)) > 0
|
||||||
)
|
)
|
||||||
) config.submodules.defaults);
|
) config.submodules.defaults);
|
||||||
|
|
||||||
|
|
@ -59,35 +64,6 @@ let
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
submoduleDefinitionOptions = {
|
|
||||||
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 = "1.0.0";
|
|
||||||
};
|
|
||||||
|
|
||||||
tags = mkOption {
|
|
||||||
description = "List of submodule tags";
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
submoduleOptions = {
|
|
||||||
options.submodule = submoduleDefinitionOptions;
|
|
||||||
};
|
|
||||||
|
|
||||||
specialArgs = cfg.specialArgs // {
|
specialArgs = cfg.specialArgs // {
|
||||||
parentConfig = config;
|
parentConfig = config;
|
||||||
};
|
};
|
||||||
|
|
@ -113,6 +89,8 @@ let
|
||||||
else head versionSortedSubmodules;
|
else head versionSortedSubmodules;
|
||||||
in matchingModule;
|
in matchingModule;
|
||||||
in {
|
in {
|
||||||
|
imports = [ ./base.nix ];
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
submodules.specialArgs = mkOption {
|
submodules.specialArgs = mkOption {
|
||||||
description = "Special args to pass to submodules. These arguments can be used for imports";
|
description = "Special args to pass to submodules. These arguments can be used for imports";
|
||||||
|
|
@ -136,6 +114,12 @@ in {
|
||||||
default = [];
|
default = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
features = mkOption {
|
||||||
|
description = "List of features that submodule has to have to apply defaults";
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [];
|
||||||
|
};
|
||||||
|
|
||||||
default = mkOption {
|
default = mkOption {
|
||||||
description = "Default to apply to submodule instance";
|
description = "Default to apply to submodule instance";
|
||||||
type = types.unspecified;
|
type = types.unspecified;
|
||||||
|
|
@ -146,10 +130,10 @@ in {
|
||||||
default = [];
|
default = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
submodules.propagate = mkOption {
|
submodules.propagate.enable = mkOption {
|
||||||
description = "Whether to propagate defaults and imports to submodule's submodules";
|
description = "Whether to propagate defaults and imports from parent to child";
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = false;
|
default = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
submodules.imports = mkOption {
|
submodules.imports = mkOption {
|
||||||
|
|
@ -159,11 +143,16 @@ in {
|
||||||
types.path
|
types.path
|
||||||
(module: {inherit module;})
|
(module: {inherit module;})
|
||||||
(types.submodule ({name, config, ...}: let
|
(types.submodule ({name, config, ...}: let
|
||||||
submoduleDefinition = (evalModules {
|
evaledSubmodule' = (evalModules {
|
||||||
inherit specialArgs;
|
inherit specialArgs;
|
||||||
modules = config.modules ++ [submoduleOptions];
|
modules = config.modules ++ [ ./base.nix ];
|
||||||
check = false;
|
check = false;
|
||||||
}).config.submodule;
|
}).config;
|
||||||
|
|
||||||
|
evaledSubmodule =
|
||||||
|
if (!(elem "submodule" evaledSubmodule'._module.features))
|
||||||
|
then throw "no submodule defined"
|
||||||
|
else evaledSubmodule';
|
||||||
in {
|
in {
|
||||||
options = {
|
options = {
|
||||||
module = mkOption {
|
module = mkOption {
|
||||||
|
|
@ -177,11 +166,23 @@ in {
|
||||||
default = [config.module];
|
default = [config.module];
|
||||||
};
|
};
|
||||||
|
|
||||||
definition = submoduleDefinitionOptions;
|
features = mkOption {
|
||||||
|
description = "List of features exposed by submodule";
|
||||||
|
type = types.listOf types.str;
|
||||||
};
|
};
|
||||||
|
|
||||||
config.definition = {
|
definition = mkOption {
|
||||||
inherit (submoduleDefinition) name description version tags;
|
description = "Submodule definition";
|
||||||
|
type = types.attrs;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
definition = {
|
||||||
|
inherit (evaledSubmodule.submodule) name description version tags;
|
||||||
|
};
|
||||||
|
|
||||||
|
features = evaledSubmodule._module.features;
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
@ -203,7 +204,11 @@ in {
|
||||||
submoduleDefinition = submodule.definition;
|
submoduleDefinition = submodule.definition;
|
||||||
|
|
||||||
# submodule defaults
|
# submodule defaults
|
||||||
defaults = getDefaults submoduleDefinition.name submoduleDefinition.tags;
|
defaults = getDefaults {
|
||||||
|
name = submoduleDefinition.name;
|
||||||
|
tags = submoduleDefinition.tags;
|
||||||
|
features = submodule.features;
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
options = {
|
options = {
|
||||||
name = mkOption {
|
name = mkOption {
|
||||||
|
|
@ -227,10 +232,16 @@ in {
|
||||||
default = null;
|
default = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
passthru.enable = mkOption {
|
||||||
|
description = "Whether to passthru submodule resources";
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
config = mkOption {
|
config = mkOption {
|
||||||
description = "Submodule instance ${config.name} for ${submoduleDefinition.name}:${submoduleDefinition.version} config";
|
description = "Submodule instance ${config.name} for ${submoduleDefinition.name}:${submoduleDefinition.version} config";
|
||||||
type = submoduleWithSpecialArgs ({...}: {
|
type = submoduleWithSpecialArgs ({...}: {
|
||||||
imports = submodule.modules ++ defaults ++ [submoduleOptions];
|
imports = submodule.modules ++ defaults ++ [ ./base.nix ];
|
||||||
_module.args.pkgs = pkgs;
|
_module.args.pkgs = pkgs;
|
||||||
_module.args.name = config.name;
|
_module.args.name = config.name;
|
||||||
_module.args.submodule = config;
|
_module.args.submodule = config;
|
||||||
|
|
@ -243,16 +254,31 @@ in {
|
||||||
default = {};
|
default = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = mkMerge [
|
||||||
|
{
|
||||||
|
_module.features = ["submodules"];
|
||||||
|
|
||||||
submodules.specialArgs.kubenix = kubenix;
|
submodules.specialArgs.kubenix = kubenix;
|
||||||
submodules.defaults = [(mkIf cfg.propagate {
|
|
||||||
|
# passthru kubenix.project to submodules
|
||||||
|
submodules.defaults = [{
|
||||||
|
default = {
|
||||||
|
kubenix.project = parentConfig.kubenix.project;
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
(mkIf cfg.propagate.enable {
|
||||||
|
# if propagate is enabled and submodule has submodules included propagage defaults and imports
|
||||||
|
submodules.defaults = [{
|
||||||
|
features = ["submodules"];
|
||||||
default = {
|
default = {
|
||||||
imports = [./submodules.nix];
|
|
||||||
submodules = {
|
submodules = {
|
||||||
defaults = cfg.defaults;
|
defaults = cfg.defaults;
|
||||||
imports = cfg.imports;
|
imports = cfg.imports;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})];
|
}];
|
||||||
};
|
})
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.testing;
|
cfg = config.testing;
|
||||||
parentConfig = config;
|
|
||||||
|
|
||||||
nixosTesting = import <nixpkgs/nixos/lib/testing.nix> {
|
nixosTesting = import <nixpkgs/nixos/lib/testing.nix> {
|
||||||
inherit pkgs;
|
inherit pkgs;
|
||||||
|
|
@ -110,7 +109,9 @@ let
|
||||||
|
|
||||||
testOptions = {config, ...}: let
|
testOptions = {config, ...}: let
|
||||||
modules = [config.module ./test.nix {
|
modules = [config.module ./test.nix {
|
||||||
config._module.args.test = config;
|
config._module.args = {
|
||||||
|
test = config;
|
||||||
|
} // cfg.args;
|
||||||
}] ++ cfg.defaults;
|
}] ++ cfg.defaults;
|
||||||
|
|
||||||
test = (kubenix.evalModules {
|
test = (kubenix.evalModules {
|
||||||
|
|
@ -229,6 +230,12 @@ in {
|
||||||
apply = tests: filter (test: test.enable) tests;
|
apply = tests: filter (test: test.enable) tests;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
testing.args = mkOption {
|
||||||
|
description = "Attribute set of extra args passed to tests";
|
||||||
|
type = types.attrs;
|
||||||
|
default = {};
|
||||||
|
};
|
||||||
|
|
||||||
testing.testsByName = mkOption {
|
testing.testsByName = mkOption {
|
||||||
description = "Tests by name";
|
description = "Tests by name";
|
||||||
type = types.attrsOf types.attrs;
|
type = types.attrsOf types.attrs;
|
||||||
|
|
@ -249,6 +256,7 @@ in {
|
||||||
tests = map (test: {
|
tests = map (test: {
|
||||||
inherit (test) name description success test;
|
inherit (test) name description success test;
|
||||||
assertions = moduleToAttrs test.assertions;
|
assertions = moduleToAttrs test.assertions;
|
||||||
|
generated = test.generated;
|
||||||
}) (filter (test: test.enable) cfg.tests);
|
}) (filter (test: test.enable) cfg.tests);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ in rec {
|
||||||
results = mapAttrs (_: test: test.result) tests;
|
results = mapAttrs (_: test: test.result) tests;
|
||||||
});
|
});
|
||||||
|
|
||||||
tests-check =
|
test-check =
|
||||||
if !(all (test: test.success) (attrValues tests))
|
if !(all (test: test.success) (attrValues tests))
|
||||||
then throw "tests failed"
|
then throw "tests failed"
|
||||||
else true;
|
else true;
|
||||||
|
|
|
||||||
|
|
@ -26,19 +26,16 @@ let
|
||||||
./k8s/1.13/crd.nix
|
./k8s/1.13/crd.nix
|
||||||
./k8s/defaults.nix
|
./k8s/defaults.nix
|
||||||
./k8s/order.nix
|
./k8s/order.nix
|
||||||
|
./k8s/submodule.nix
|
||||||
./helm/simple.nix
|
./helm/simple.nix
|
||||||
./istio/bookinfo.nix
|
./istio/bookinfo.nix
|
||||||
./submodules/simple.nix
|
./submodules/simple.nix
|
||||||
./submodules/defaults.nix
|
./submodules/defaults.nix
|
||||||
./submodules/versioning.nix
|
./submodules/versioning.nix
|
||||||
./module.nix
|
|
||||||
./metacontroller/compositecontroller.nix
|
|
||||||
];
|
];
|
||||||
testing.defaults = ({kubenix, ...}: {
|
testing.args = {
|
||||||
imports = [kubenix.modules.k8s];
|
inherit images k8sVersion;
|
||||||
kubernetes.version = k8sVersion;
|
};
|
||||||
_module.args.images = images;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
args = {
|
args = {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, lib, pkgs, kubenix, helm, ... }:
|
{ config, lib, pkgs, kubenix, helm, k8sVersion, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
with kubenix.lib;
|
with kubenix.lib;
|
||||||
|
|
@ -60,6 +60,8 @@ in {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
kubernetes.version = k8sVersion;
|
||||||
|
|
||||||
kubernetes.api.namespaces.test = {};
|
kubernetes.api.namespaces.test = {};
|
||||||
|
|
||||||
kubernetes.helm.instances.app-psql = {
|
kubernetes.helm.instances.app-psql = {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, kubenix, ... }:
|
{ config, kubenix, k8sVersion, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = with kubenix.modules; [ test k8s istio ];
|
imports = with kubenix.modules; [ test k8s istio ];
|
||||||
|
|
@ -8,6 +8,8 @@
|
||||||
description = "Simple istio bookinfo application (WIP)";
|
description = "Simple istio bookinfo application (WIP)";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
kubernetes.version = k8sVersion;
|
||||||
|
|
||||||
kubernetes.api."networking.istio.io"."v1alpha3" = {
|
kubernetes.api."networking.istio.io"."v1alpha3" = {
|
||||||
Gateway."bookinfo-gateway" = {
|
Gateway."bookinfo-gateway" = {
|
||||||
spec = {
|
spec = {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, lib, kubenix, ... }:
|
{ config, lib, kubenix, k8sVersion, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
|
|
@ -17,6 +17,8 @@ in {
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
kubernetes.version = k8sVersion;
|
||||||
|
|
||||||
kubernetes.api.customresourcedefinitions.crontabs = {
|
kubernetes.api.customresourcedefinitions.crontabs = {
|
||||||
metadata.name = "crontabs.stable.example.com";
|
metadata.name = "crontabs.stable.example.com";
|
||||||
spec = {
|
spec = {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, lib, kubenix, pkgs, ... }:
|
{ config, lib, kubenix, pkgs, k8sVersion, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
|
|
@ -22,6 +22,8 @@ in {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
kubernetes.version = k8sVersion;
|
||||||
|
|
||||||
kubernetes.api.customresourcedefinitions.crontabs = {
|
kubernetes.api.customresourcedefinitions.crontabs = {
|
||||||
metadata.name = "crontabs.stable.example.com";
|
metadata.name = "crontabs.stable.example.com";
|
||||||
spec = {
|
spec = {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, lib, kubenix, ... }:
|
{ config, lib, kubenix, k8sVersion, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
|
|
@ -23,6 +23,8 @@ in {
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
kubernetes.version = k8sVersion;
|
||||||
|
|
||||||
kubernetes.api.pods.pod1 = {};
|
kubernetes.api.pods.pod1 = {};
|
||||||
|
|
||||||
kubernetes.api.pods.pod2 = {
|
kubernetes.api.pods.pod2 = {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, lib, pkgs, kubenix, images, ... }:
|
{ config, lib, pkgs, kubenix, images, k8sVersion, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
|
|
@ -41,6 +41,8 @@ in {
|
||||||
|
|
||||||
docker.images.nginx.image = image;
|
docker.images.nginx.image = image;
|
||||||
|
|
||||||
|
kubernetes.version = k8sVersion;
|
||||||
|
|
||||||
kubernetes.api.deployments.nginx = {
|
kubernetes.api.deployments.nginx = {
|
||||||
spec = {
|
spec = {
|
||||||
replicas = 10;
|
replicas = 10;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, lib, kubenix, pkgs, ... }:
|
{ config, lib, kubenix, pkgs, k8sVersion, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
|
|
@ -20,6 +20,8 @@ in {
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
kubernetes.version = k8sVersion;
|
||||||
|
|
||||||
kubernetes.api.customresourcedefinitions.crontabs = {
|
kubernetes.api.customresourcedefinitions.crontabs = {
|
||||||
metadata.name = "crontabs.stable.example.com";
|
metadata.name = "crontabs.stable.example.com";
|
||||||
spec = {
|
spec = {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, kubenix, ... }:
|
{ config, kubenix, k8sVersion, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
cfg = config.kubernetes.api.pods.nginx;
|
cfg = config.kubernetes.api.pods.nginx;
|
||||||
|
|
@ -17,5 +17,7 @@ in {
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
kubernetes.version = k8sVersion;
|
||||||
|
|
||||||
kubernetes.api.pods.nginx = {};
|
kubernetes.api.pods.nginx = {};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
56
tests/k8s/submodule.nix
Normal file
56
tests/k8s/submodule.nix
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
{ name, config, lib, kubenix, images, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.submodules.instances.passthru;
|
||||||
|
in {
|
||||||
|
imports = with kubenix.modules; [ test submodules k8s docker ];
|
||||||
|
|
||||||
|
test = {
|
||||||
|
name = "k8s-submodule";
|
||||||
|
description = "Simple k8s submodule test";
|
||||||
|
assertions = [{
|
||||||
|
message = "Submodule has correct name set";
|
||||||
|
assertion = (head config.kubernetes.objects).metadata.name == "passthru";
|
||||||
|
} {
|
||||||
|
message = "Should expose docker image";
|
||||||
|
assertion = (head config.docker.export).imageName == "xtruder/nginx";
|
||||||
|
}];
|
||||||
|
};
|
||||||
|
|
||||||
|
kubenix.project = "test-release";
|
||||||
|
|
||||||
|
kubernetes.namespace = "test-namespace";
|
||||||
|
|
||||||
|
submodules.imports = [{
|
||||||
|
module = {name, config, ...}: {
|
||||||
|
imports = with kubenix.modules; [ submodule k8s docker ];
|
||||||
|
|
||||||
|
config = {
|
||||||
|
submodule.name = "test-submodule";
|
||||||
|
|
||||||
|
kubernetes.api.pods.nginx = {
|
||||||
|
metadata.name = name;
|
||||||
|
spec.containers.nginx.image = config.docker.images.nginx.path;
|
||||||
|
};
|
||||||
|
|
||||||
|
docker.images.nginx.image = images.nginx;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
|
||||||
|
kubernetes.api.defaults = [{
|
||||||
|
propagate = true;
|
||||||
|
default.metadata.labels.my-label = "my-value";
|
||||||
|
}];
|
||||||
|
|
||||||
|
submodules.instances.passthru = {
|
||||||
|
submodule = "test-submodule";
|
||||||
|
};
|
||||||
|
|
||||||
|
submodules.instances.no-passthru = {
|
||||||
|
submodule = "test-submodule";
|
||||||
|
passthru.enable = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -9,23 +9,27 @@ let
|
||||||
instance4 = config.submodules.instances.instance4;
|
instance4 = config.submodules.instances.instance4;
|
||||||
instance5 = config.submodules.instances.instance5;
|
instance5 = config.submodules.instances.instance5;
|
||||||
|
|
||||||
module = {name, ...}: {
|
submodule = {name, ...}: {
|
||||||
options.args.value = mkOption {
|
imports = [ kubenix.modules.submodule ];
|
||||||
|
|
||||||
|
options = {
|
||||||
|
args.value = mkOption {
|
||||||
description = "Submodule value";
|
description = "Submodule value";
|
||||||
type = types.str;
|
type = types.str;
|
||||||
};
|
};
|
||||||
|
|
||||||
options.args.defaultValue = mkOption {
|
args.defaultValue = mkOption {
|
||||||
description = "Submodule default value";
|
description = "Submodule default value";
|
||||||
type = types.str;
|
type = types.str;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
in {
|
in {
|
||||||
imports = with kubenix.modules; [ test submodules ];
|
imports = with kubenix.modules; [ test submodules ];
|
||||||
|
|
||||||
test = {
|
test = {
|
||||||
name = "submodules-defatuls";
|
name = "submodules-defaults";
|
||||||
description = "Simple k8s submodule test";
|
description = "Simple submodule test";
|
||||||
assertions = [{
|
assertions = [{
|
||||||
message = "should apply defaults by tag1";
|
message = "should apply defaults by tag1";
|
||||||
assertion = instance1.config.args.value == "value1";
|
assertion = instance1.config.args.value == "value1";
|
||||||
|
|
@ -53,34 +57,34 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
submodules.imports = [{
|
submodules.imports = [{
|
||||||
modules = [module {
|
modules = [submodule {
|
||||||
submodule = {
|
submodule = {
|
||||||
name = "submodule1";
|
name = "submodule1";
|
||||||
tags = ["tag1"];
|
tags = ["tag1"];
|
||||||
};
|
};
|
||||||
}];
|
}];
|
||||||
} {
|
} {
|
||||||
modules = [module {
|
modules = [submodule {
|
||||||
submodule = {
|
submodule = {
|
||||||
name = "submodule2";
|
name = "submodule2";
|
||||||
tags = ["tag2"];
|
tags = ["tag2"];
|
||||||
};
|
};
|
||||||
}];
|
}];
|
||||||
} {
|
} {
|
||||||
modules = [module {
|
modules = [submodule {
|
||||||
submodule = {
|
submodule = {
|
||||||
name = "submodule3";
|
name = "submodule3";
|
||||||
tags = ["tag2"];
|
tags = ["tag2"];
|
||||||
};
|
};
|
||||||
}];
|
}];
|
||||||
} {
|
} {
|
||||||
modules = [module {
|
modules = [submodule {
|
||||||
submodule = {
|
submodule = {
|
||||||
name = "submodule4";
|
name = "submodule4";
|
||||||
};
|
};
|
||||||
}];
|
}];
|
||||||
} {
|
} {
|
||||||
modules = [module {
|
modules = [submodule {
|
||||||
submodule = {
|
submodule = {
|
||||||
name = "submodule5";
|
name = "submodule5";
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -25,22 +25,32 @@ in {
|
||||||
} {
|
} {
|
||||||
message = "Should have submodule name set";
|
message = "Should have submodule name set";
|
||||||
assertion = cfg.config.args.name == "instance";
|
assertion = cfg.config.args.name == "instance";
|
||||||
|
} {
|
||||||
|
message = "should have tag set";
|
||||||
|
assertion = elem "tag" (cfg.config.submodule.tags);
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
submodules.propagate.enable = true;
|
||||||
submodules.imports = [{
|
submodules.imports = [{
|
||||||
module = {name, ...}: {
|
module = {name, ...}: {
|
||||||
config.submodule.name = "submodule";
|
imports = [ kubenix.modules.submodule ];
|
||||||
options.args.value = mkOption {
|
config = {
|
||||||
|
submodule.name = "submodule";
|
||||||
|
submodule.tags = ["tag"];
|
||||||
|
};
|
||||||
|
options = {
|
||||||
|
args.value = mkOption {
|
||||||
description = "Submodule argument";
|
description = "Submodule argument";
|
||||||
type = types.str;
|
type = types.str;
|
||||||
};
|
};
|
||||||
options.args.name = mkOption {
|
args.name = mkOption {
|
||||||
description = "Submodule name";
|
description = "Submodule name";
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = name;
|
default = name;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
}];
|
}];
|
||||||
|
|
||||||
submodules.instances.instance = {
|
submodules.instances.instance = {
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,14 @@ let
|
||||||
inst-latest = config.submodules.instances.inst-latest.config;
|
inst-latest = config.submodules.instances.inst-latest.config;
|
||||||
|
|
||||||
submodule = {
|
submodule = {
|
||||||
config.submodule.name = "subm";
|
imports = [ kubenix.modules.submodule ];
|
||||||
|
|
||||||
options.version = mkOption {
|
options.version = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "undefined";
|
default = "undefined";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
config.submodule.name = "subm";
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
imports = with kubenix.modules; [ test submodules ];
|
imports = with kubenix.modules; [ test submodules ];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue