From d4d14535242ae8d63db127e28e2dd99e24393aa6 Mon Sep 17 00:00:00 2001 From: Vishwanath S Date: Tue, 8 Sep 2026 13:01:37 +0530 Subject: [PATCH] validator: allow pack values.yaml to add cpu/memory resource limits check-values-structure.py rejected any key present in a pack's values.yaml but absent from the chart's own values.yaml, including the common case of a pack adding a resources.limits.cpu or resources.limits.memory override that the chart doesn't define by default. Tightening resource limits at the pack level is an intentional, allowed override, not a structural defect, so it should not fail validation. Ported from the same fix in spectrocloud/pax (PR #4635). Co-Authored-By: Claude Sonnet 5 --- validator/check-values-structure.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/validator/check-values-structure.py b/validator/check-values-structure.py index 93636395..fa06bcce 100644 --- a/validator/check-values-structure.py +++ b/validator/check-values-structure.py @@ -46,10 +46,13 @@ def is_empty_map(node): def check_subset(pack, chart, path, errs): - """Structural subset: every path in pack must exist in chart. Exception: + """Structural subset: every path in pack must exist in chart. Exceptions: when the chart node at any level is an empty sequence or an empty mapping (a Helm user-extension point like podLabels: {}, tolerations: [], etc.), - everything under the corresponding pack path is accepted.""" + everything under the corresponding pack path is accepted; and a pack may + add a 'cpu' or 'memory' key under any 'limits' mapping even if the chart + doesn't define it there, since tightening resource limits beyond what a + chart ships is an intentional, allowed pack-level override.""" if chart is None: errs.append(f"path '{path}' present in pack values.yaml but not in chart's values.yaml") return @@ -62,12 +65,16 @@ def check_subset(pack, chart, path, errs): f"{chart.tag}" ) return + is_limits_map = path.rsplit(".", 1)[-1] == "limits" for k_node, v_node in pack.value: if not isinstance(k_node, yaml.ScalarNode): continue key = k_node.value child_path = f"{path}.{key}" if path else key - check_subset(v_node, get_child(chart, key), child_path, errs) + child_chart = get_child(chart, key) + if child_chart is None and is_limits_map and key in ("cpu", "memory"): + continue + check_subset(v_node, child_chart, child_path, errs) elif isinstance(pack, yaml.SequenceNode): if not isinstance(chart, yaml.SequenceNode): errs.append(