Skip to content

Commit

Permalink
kubenix.submodule example used to create resources in multiple namesp…
Browse files Browse the repository at this point in the history
…aces (#22)
  • Loading branch information
adrian-gierakowski committed May 25, 2023
1 parent 20907f5 commit a90fdc0
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 0 deletions.
11 changes: 11 additions & 0 deletions docs/content/examples/namespaces/_index.md
Original file line number Diff line number Diff line change
@@ -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" >}}
9 changes: 9 additions & 0 deletions docs/content/examples/namespaces/default.nix
Original file line number Diff line number Diff line change
@@ -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";
};
}
64 changes: 64 additions & 0 deletions docs/content/examples/namespaces/module.nix
Original file line number Diff line number Diff line change
@@ -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";
};
}
64 changes: 64 additions & 0 deletions docs/content/examples/namespaces/namespaced.nix
Original file line number Diff line number Diff line change
@@ -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
];
};
}

0 comments on commit a90fdc0

Please sign in to comment.