Skip to content

Commit

Permalink
feat(k8s): add function for injecting names from hashed data objects (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
matejc committed Sep 26, 2023
1 parent 71cb0a2 commit de856f9
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 1 deletion.
17 changes: 17 additions & 0 deletions lib/k8s/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,23 @@ with lib; rec {
} // labels;
};

# Returns "<name>-<hash(data)>"
mkNameHash = { name, data, length ? 10 }:
"${name}-${builtins.substring 0 length (builtins.hashString "sha1" (builtins.toJSON data))}";

# Returns the same resources with addition of injected (or overwritten) metadata.name with hashed data
# name of the resource in Nix does not change for reference reasons
# useful for the ConfigMap and Secret resources
injectHashedNames = attrs:
lib.mapAttrs
(name: o:
recursiveUpdate o {
metadata.name = mkNameHash { inherit name; data = o.data; };
}
)
attrs;


inherit (lib) toBase64;
inherit (lib) octalToDecimal;
}
42 changes: 41 additions & 1 deletion modules/k8s.nix
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,39 @@ with lib; let
(types.listOf (types.submodule submodule))
(mergeValuesByFn keyFn)
(types.attrsOf (types.submodule submodule));

# inject hashed names for referencing inside modules, example:
# pod = {
# containers.nginx = {
# image = "nginx:1.25.1";
# volumeMounts = {
# "/etc/nginx".name = "config";
# "/var/lib/html".name = "static";
# };
# };
# volumes = {
# config.configMap.name = config.kubernetes.resources.configMaps.nginx-config.metadata.name;
# static.configMap.name = config.kubernetes.resources.configMaps.nginx-static.metadata.name;
# };
# };
optionalHashedNames = object:
if cfg.enableHashedNames then
recursiveUpdate object
(mapAttrs
(ks: v:
if builtins.elem ks [ "configMaps" "secrets" ] then
k8s.injectHashedNames v
else
v
)
object)
else object;

# inject hashed names in the output
optionalHashedNames' = object: kind:
if cfg.enableHashedNames && elem kind [ "ConfigMap" "Secret" ] then
k8s.injectHashedNames object
else object;
in
{
imports = [ ./base.nix ];
Expand Down Expand Up @@ -319,6 +352,7 @@ in
description = "Alias for `config.kubernetes.api.resources` options";
default = { };
type = types.attrsOf types.attrs;
apply = optionalHashedNames;
};

customTypes = mkOption {
Expand Down Expand Up @@ -411,6 +445,12 @@ in
description = "Genrated kubernetes YAML file";
type = types.package;
};

enableHashedNames = mkOption {
description = "Enable hashing of resource (ConfigMap,Secret) names";
type = types.bool;
default = false;
};
};

config = {
Expand Down Expand Up @@ -497,7 +537,7 @@ in
kubernetes.objects = flatten (mapAttrsToList
(_: type:
mapAttrsToList (_name: moduleToAttrs)
cfg.api.resources.${type.group}.${type.version}.${type.kind}
(optionalHashedNames' cfg.api.resources.${type.group}.${type.version}.${type.kind} type.kind)
)
cfg.api.types);

Expand Down

0 comments on commit de856f9

Please sign in to comment.