From a90fdc0eae9d2178b38b29b0fb804031e21d48a3 Mon Sep 17 00:00:00 2001 From: Adrian Date: Thu, 25 May 2023 05:57:03 +0100 Subject: [PATCH] kubenix.submodule example used to create resources in multiple namespaces (#22) --- docs/content/examples/namespaces/_index.md | 11 ++++ docs/content/examples/namespaces/default.nix | 9 +++ docs/content/examples/namespaces/module.nix | 64 +++++++++++++++++++ .../examples/namespaces/namespaced.nix | 64 +++++++++++++++++++ 4 files changed, 148 insertions(+) create mode 100644 docs/content/examples/namespaces/_index.md create mode 100644 docs/content/examples/namespaces/default.nix create mode 100644 docs/content/examples/namespaces/module.nix create mode 100644 docs/content/examples/namespaces/namespaced.nix diff --git a/docs/content/examples/namespaces/_index.md b/docs/content/examples/namespaces/_index.md new file mode 100644 index 0000000..1393acc --- /dev/null +++ b/docs/content/examples/namespaces/_index.md @@ -0,0 +1,11 @@ +This example demonstrates the use of kubenix submodules, which are built atop of nixos submodule system, to create resources in multiple namespaces. + +{{< source "default.nix" >}} + +Here's a definition of a submodule. + +{{< source "namespaced.nix" >}} + +And here's how it can be used. + +{{< source "module.nix" >}} diff --git a/docs/content/examples/namespaces/default.nix b/docs/content/examples/namespaces/default.nix new file mode 100644 index 0000000..4c9c0a0 --- /dev/null +++ b/docs/content/examples/namespaces/default.nix @@ -0,0 +1,9 @@ +{kubenix ? import ../../../..}: +kubenix.evalModules.x86_64-linux { + module = {kubenix, ...}: { + imports = [./module.nix]; + + kubenix.project = "multi-namespace-example"; + kubernetes.version = "1.24"; + }; +} diff --git a/docs/content/examples/namespaces/module.nix b/docs/content/examples/namespaces/module.nix new file mode 100644 index 0000000..4de759e --- /dev/null +++ b/docs/content/examples/namespaces/module.nix @@ -0,0 +1,64 @@ +{ + config, + lib, + pkgs, + kubenix, + ... +}: { + imports = with kubenix.modules; [submodules k8s]; + + # Import submodule. + submodules.imports = [ + ./namespaced.nix + ]; + + # We can now create multiple submodule instances. + submodules.instances.namespace-http = { + # ~~~~~~~~~~~~~~ + # ^ + # ╭-----------------------╯ + # The submodule instance name is injected as the name attribute to + # the submodule function. In this example, it is used as the namespace + # name. + # + # This needs to match config.submodule.name of an imported submodule. + submodule = "namespaced"; + # Now we can set the args options defined in the submodule. + args.kubernetes.resources = { + services.nginx.spec = { + ports = [ + { + name = "http"; + port = 80; + } + ]; + selector.app = "nginx"; + }; + }; + }; + + submodules.instances.namespace-https = { + submodule = "namespaced"; + args.kubernetes.resources = { + services.nginx.spec = { + ports = [ + { + name = "https"; + port = 443; + } + ]; + selector.app = "nginx"; + }; + }; + # Example of how other defaults can be applied to resources + # within a submodule. + args.kubernetes.version = "1.26"; + }; + + # Resources defined in parent context use namespace set at this + # level and are not affected by the above submodules. + kubernetes.namespace = "default"; + kubernetes.resources.services.nginx.spec = { + selector.app = "nginx-default"; + }; +} diff --git a/docs/content/examples/namespaces/namespaced.nix b/docs/content/examples/namespaces/namespaced.nix new file mode 100644 index 0000000..183e407 --- /dev/null +++ b/docs/content/examples/namespaces/namespaced.nix @@ -0,0 +1,64 @@ +{ + config, + kubenix, + lib, + # Name of submodule instance. + name, + # This is a shorthand for config.submodule.args and contains + # final values of the args options. + args, + ... +}: { + imports = with kubenix.modules; [ + # This needs to be imported in order to define a submodule. + submodule + # Importing this so that we can set config.kubernetes + # within the context of this submodule. + k8s + ]; + + # Args are used to pass information from the parent context. + options.submodule.args = { + kubernetes = lib.mkOption { + description = "Kubernetes config to be applied to a specific namespace."; + # We are not given a precise type to this since we are using it + # to set kubernetes options from the k8s module which are already + # precisely typed. + type = lib.types.attrs; + default = {}; + }; + }; + + config = { + submodule = { + # Used to uniquely identify a submodule. Used to select submodule + # "prototype" when instantiating. + name = "namespaced"; + + # Passthru allows a submodule instance to set config of the parent + # context. It's not strictly required but it's useful for combining + # outputs of multiple submodule instances, without having to write + # ad hoc code in the parent context. + + # NOTE: passthru has not effect if given options are not defined + # in the parent context. Therefore in this case we are expecting that + # parent imports kubinex.k8s module. + + # Here we set kubernetes.objects. + # This is a list so even if distinct instances of the submodule contain + # definitions of identical api resources, these will not be merged or + # cause conflicts. Lists of resources from multiple submodule instances + # will simply be concatenated. + passthru.kubernetes.objects = config.kubernetes.objects; + }; + + kubernetes = lib.mkMerge [ + # Use instance name as namespace + { namespace = name; } + # Create namespace object + { resources.namespaces.${name} = {}; } + # All resources defined here will use the above namespace + args.kubernetes + ]; + }; +}