From 242a48d7ad20b825c550b6f157efe5e89e9c08bd Mon Sep 17 00:00:00 2001 From: Felix Scheinost Date: Tue, 21 Nov 2023 19:13:53 +0100 Subject: [PATCH] fix ConfigMap data with leading underscore (#44) --- modules/k8s.nix | 26 +++++++++++++++++++------- tests/default.nix | 1 + tests/k8s/configmap.nix | 20 ++++++++++++++++++++ 3 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 tests/k8s/configmap.nix diff --git a/modules/k8s.nix b/modules/k8s.nix index 601ed2e..c412826 100644 --- a/modules/k8s.nix +++ b/modules/k8s.nix @@ -16,12 +16,24 @@ with lib; let ) cfg.api.defaults); - moduleToAttrs = value: - if isAttrs value - then mapAttrs (_n: moduleToAttrs) (filterAttrs (n: v: v != null && !(hasPrefix "_" n)) value) - else if isList value - then map moduleToAttrs value - else value; + moduleToAttrs = objType: propertyPath: value: + if isAttrs value then + let + # Fix https://github.com/hall/kubenix/issues/44 + # The check for names starting with leading '_' has been here since forever. + # Not sure where it makes sense, but it definitely doesn't make sense for ConfigMap -> data/binaryData + # => To get a minimal invasive fix we added `objType` and `propertyPath` to make `moduleToAttrs` "context-aware". + # This way we can allow names with leading underscore exactly for ConfigMap -> data/binaryData + allowLeadingUnderscore = objType.group == "core" && objType.version == "v1" && objType.kind == "ConfigMap" && + (propertyPath == [ "data" ] || propertyPath == [ "binaryData" ]); + filterName = name: allowLeadingUnderscore || !(hasPrefix "_" name); + filteredAttrs = filterAttrs (n: v: v != null && filterName n) value; + in + mapAttrs (_n: moduleToAttrs objType (propertyPath ++ [ _n ])) filteredAttrs + else if isList value then + map (moduleToAttrs objType propertyPath) value + else + value; apiOptions = { config, ... }: { options = { @@ -536,7 +548,7 @@ in kubernetes.objects = flatten (mapAttrsToList (_: type: - mapAttrsToList (_name: moduleToAttrs) + mapAttrsToList (_name: moduleToAttrs type [ ]) (optionalHashedNames' cfg.api.resources.${type.group}.${type.version}.${type.kind} type.kind) ) cfg.api.types); diff --git a/tests/default.nix b/tests/default.nix index 1f01019..0984b74 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -21,6 +21,7 @@ let ./k8s/defaults.nix ./k8s/order.nix ./k8s/submodule.nix + ./k8s/configmap.nix # TODO: `importYaml` uses IFD which fails during `nix flake check` as it evaluates # for all systems, not only the current one: https://github.com/hall/kubenix/issues/12 # ./k8s/imports.nix diff --git a/tests/k8s/configmap.nix b/tests/k8s/configmap.nix new file mode 100644 index 0000000..7dbe823 --- /dev/null +++ b/tests/k8s/configmap.nix @@ -0,0 +1,20 @@ +{ config, kubenix, ... }: +let + configMapData = (builtins.head config.kubernetes.objects).data; +in +{ + imports = [ kubenix.modules.test kubenix.modules.k8s ]; + + test = { + name = "k8s-simple"; + description = "Test that ConfigMap data keys can have a leading underscore (https://github.com/hall/kubenix/issues/44)"; + assertions = [ + { + message = "leading underscore in ConfigMap key should be preserved"; + assertion = configMapData == { _FOO = "_bar"; }; + } + ]; + }; + + kubernetes.resources.configMaps.foo.data._FOO = "_bar"; +}