From ecf531aeb4a6e98c07590bbb56290dc1361f5201 Mon Sep 17 00:00:00 2001 From: Jaka Hudoklin Date: Mon, 25 Feb 2019 17:14:48 +0100 Subject: [PATCH] feat: implement k8s-submodules --- default.nix | 1 + k8s/submodule.nix | 52 ++++++++++++++++++++++++++++++++++ tests/k8s/submodule.nix | 62 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 k8s/submodule.nix create mode 100644 tests/k8s/submodule.nix diff --git a/default.nix b/default.nix index f635e4b..7ba1e46 100644 --- a/default.nix +++ b/default.nix @@ -26,6 +26,7 @@ let lib = lib'; submodules = ./submodules.nix; k8s = ./k8s; + k8s-submodules = ./k8s/submodule.nix; istio = ./istio; testing = ./testing; }; diff --git a/k8s/submodule.nix b/k8s/submodule.nix new file mode 100644 index 0000000..143682f --- /dev/null +++ b/k8s/submodule.nix @@ -0,0 +1,52 @@ +{ config, lib, kubenix, ... }: + +with lib; + +let + globalConfig = config; +in { + imports = [ kubenix.submodules ]; + + options = { + kubernetes.propagateDefaults = mkOption { + description = "Whehter 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.all.metadata.namespace = + mkDefault config.namespace; + }; + })); + }; + }; + + config = { + submodules.defaults = mkMerge [{ + imports = [ kubenix.k8s ]; + kubernetes.version = mkDefault config.kubernetes.version; + kubernetes.api.defaults = + mkIf config.kubernetes.propagateDefaults config.kubernetes.api.defaults; + } ({config, ...}: { + kubernetes.api.defaults.all.metadata.labels = { + "kubenix/module-name" = config.submodule.name; + "kubenix/module-version" = config.submodule.version; + }; + })]; + + kubernetes.objects = mkMerge (mapAttrsToList (_: submodule: + submodule.config.kubernetes.objects + ) config.submodules.instances); + }; +} diff --git a/tests/k8s/submodule.nix b/tests/k8s/submodule.nix new file mode 100644 index 0000000..6fb68f4 --- /dev/null +++ b/tests/k8s/submodule.nix @@ -0,0 +1,62 @@ +{ name, config, lib, kubenix, images, ... }: + +with lib; + +let + cfg = config.submodules.instances.test.config; + deployment = cfg.kubernetes.api.deployments.nginx; + image = images.nginx; +in { + imports = [ + kubenix.k8s-submodules + ]; + + test = { + name = "k8s-submodules"; + description = "Simple k8s submodule test"; + assertions = [{ + message = "Namespace not propagated"; + assertion = deployment.metadata.namespace == "test"; + } { + message = "Version not propagated"; + assertion = cfg.kubernetes.version == config.kubernetes.version; + }]; + testScript = '' + $kube->waitUntilSucceeds("docker load < ${image}"); + $kube->waitUntilSucceeds("kubectl apply -f ${toYAML config.kubernetes.generated}"); + + $kube->succeed("kubectl get deployment -n test | grep -i test-nginx"); + $kube->waitUntilSucceeds("kubectl get deployment -n test -o go-template test-nginx --template={{.status.readyReplicas}} | grep 1"); + ''; + }; + + submodules.imports = [{ + module = {name, config, ...}: { + submodule.name = "nginx"; + kubernetes.api.deployments.nginx = { + metadata = { + name = "${name}-nginx"; + labels.app = name; + }; + spec = { + replicas = 1; + selector.matchLabels.app = "nginx"; + template.metadata.labels.app = "nginx"; + template.spec = { + containers.nginx = { + image = "${image.imageName}:${image.imageTag}"; + imagePullPolicy = "Never"; + }; + }; + }; + }; + }; + }]; + + kubernetes.api.namespaces.test = {}; + + submodules.instances.test = { + submodule = "nginx"; + namespace = "test"; + }; +}