From 24ea67934e927fb49a3d069db702729cabdfd426 Mon Sep 17 00:00:00 2001 From: Jordi Pique Date: Mon, 22 Apr 2024 23:40:29 +0100 Subject: [PATCH] Add ability to do implicit nested loops on a "getValue" The implicit nested loops are defined using a "*". For example, we can now iterate over all the container names by doing ".spec.containers.*.name" --- generic_k8s_webhook/operators.py | 15 +++++++++++++++ tests/conditions_test.yaml | 30 ++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/generic_k8s_webhook/operators.py b/generic_k8s_webhook/operators.py index 23f27ec..627fd0a 100644 --- a/generic_k8s_webhook/operators.py +++ b/generic_k8s_webhook/operators.py @@ -319,6 +319,9 @@ def _get_value_from_json(self, data: Union[list, dict], path: list): if len(path) == 0 or path[0] == "": return data + if path[0] == "*": + return self._evaluate_wildcard(data, path) + if isinstance(data, dict): key = path[0] if key in data: @@ -332,6 +335,18 @@ def _get_value_from_json(self, data: Union[list, dict], path: list): return None + def _evaluate_wildcard(self, data: Union[list, dict], path: list): + if not isinstance(data, list): + raise RuntimeError(f"Expected list when evaluating '*', but got {data}") + l = [] + for elem in data: + sublist = self._get_value_from_json(elem, path[1:]) + if isinstance(sublist, list): + l.extend(sublist) + else: + l.append(sublist) + return l + def input_type(self) -> type | None: return None diff --git a/tests/conditions_test.yaml b/tests/conditions_test.yaml index 7d5b87a..c2310ef 100644 --- a/tests/conditions_test.yaml +++ b/tests/conditions_test.yaml @@ -138,6 +138,36 @@ test_suites: spec: {} - name: bar expected_result: foo + # Evaluate a wildcard (1) + - condition: + getValue: .nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution.*.preference.matchExpressions + context: + - nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: key1 + - preference: + matchExpressions: + - key: key2 + expected_result: + - key: key1 + - key: key2 + # Evaluate a wildcard (2) + - condition: + getValue: .nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution.*.preference.matchExpressions.*.key + context: + - nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: key1 + - preference: + matchExpressions: + - key: key2 + expected_result: + - key1 + - key2 - name: FOR_EACH tests: - schemas: [v1alpha1]