From bee57f08583de70eb5c715cc91a851b37142a7db Mon Sep 17 00:00:00 2001 From: jordi Date: Mon, 22 Apr 2024 20:32:51 +0100 Subject: [PATCH] Create alias for certain operations This commit improves the name of certain operations. This change has effect on v1beta1. However, to be able to consume configs written with v1alph1, we're keeping the old names. The operations that now have a new alias are: - "and" -> "all" - "or" -> "any" - "forEach" -> "map" Appart from that, we're changing the behaviour of "or" (and "any) when they have no operands. Before, the result was true, but now it's false. This makes this operation consistent with `any([])` in Python. The intention is to make it's output more intuitive for Python users. --- .../config_parser/entrypoint.py | 3 ++ .../config_parser/operator_parser.py | 42 +++++++++++++++++++ generic_k8s_webhook/operators.py | 4 +- tests/conditions_test.yaml | 37 ++++++++++++++++ 4 files changed, 85 insertions(+), 1 deletion(-) diff --git a/generic_k8s_webhook/config_parser/entrypoint.py b/generic_k8s_webhook/config_parser/entrypoint.py index daa853e..9d1f970 100644 --- a/generic_k8s_webhook/config_parser/entrypoint.py +++ b/generic_k8s_webhook/config_parser/entrypoint.py @@ -100,12 +100,15 @@ def _parse_v1beta1(self, raw_list_webhook_config: dict) -> list[Webhook]: meta_op_parser=op_parser.MetaOperatorParser( list_op_parser_classes=[ op_parser.AndParser, + op_parser.AllParser, op_parser.OrParser, + op_parser.AnyParser, op_parser.EqualParser, op_parser.SumParser, op_parser.NotParser, op_parser.ListParser, op_parser.ForEachParser, + op_parser.MapParser, op_parser.ContainParser, op_parser.ConstParser, op_parser.GetValueParser, diff --git a/generic_k8s_webhook/config_parser/operator_parser.py b/generic_k8s_webhook/config_parser/operator_parser.py index e3b5016..2835973 100644 --- a/generic_k8s_webhook/config_parser/operator_parser.py +++ b/generic_k8s_webhook/config_parser/operator_parser.py @@ -100,6 +100,10 @@ def get_operator_cls(cls) -> operators.BinaryOp: class AndParser(BinaryOpParser): + """ + Deprecated. Use "all" instead + """ + @classmethod def get_name(cls) -> str: return "and" @@ -109,7 +113,21 @@ def get_operator_cls(cls) -> operators.BinaryOp: return operators.And +class AllParser(AndParser): + """ + Just an alias for "and". In the future, we'll deprecate "and" in favour of "all" + """ + + @classmethod + def get_name(cls) -> str: + return "all" + + class OrParser(BinaryOpParser): + """ + Deprecated. Use "any" instead + """ + @classmethod def get_name(cls) -> str: return "or" @@ -119,6 +137,16 @@ def get_operator_cls(cls) -> operators.BinaryOp: return operators.Or +class AnyParser(OrParser): + """ + Just an alias for "or". In the future, we'll deprecate "or" in favour of "all" + """ + + @classmethod + def get_name(cls) -> str: + return "any" + + class EqualParser(BinaryOpParser): @classmethod def get_name(cls) -> str: @@ -180,6 +208,10 @@ def parse(self, op_inputs: dict | list, path_op: str) -> operators.List: class ForEachParser(OperatorParser): + """ + Deprecated. Use "map" instead of "forEach" + """ + @classmethod def get_name(cls) -> str: return "forEach" @@ -197,6 +229,16 @@ def parse(self, op_inputs: dict | list, path_op: str) -> operators.ForEach: raise ParsingException(f"Error when parsing {path_op}") from e +class MapParser(ForEachParser): + """ + It's an alias of ForEachParser. In the future, we'll deprecate "forEach" in favour of "map" + """ + + @classmethod + def get_name(cls) -> str: + return "map" + + class ContainParser(OperatorParser): @classmethod def get_name(cls) -> str: diff --git a/generic_k8s_webhook/operators.py b/generic_k8s_webhook/operators.py index 437fe72..23f27ec 100644 --- a/generic_k8s_webhook/operators.py +++ b/generic_k8s_webhook/operators.py @@ -110,6 +110,7 @@ def _op(self, lhs, rhs): return lhs and rhs def _zero_args_result(self): + # This follows the default behaviour in Python when executing `all([])` return True @@ -118,7 +119,8 @@ def _op(self, lhs, rhs): return lhs or rhs def _zero_args_result(self): - return True + # This follows the default behaviour in Python when executing `any([])` + return False class ArithOp(BinaryOp): diff --git a/tests/conditions_test.yaml b/tests/conditions_test.yaml index df3ec52..7d5b87a 100644 --- a/tests/conditions_test.yaml +++ b/tests/conditions_test.yaml @@ -31,6 +31,16 @@ test_suites: - condition: and: [] expected_result: true + # Just check we can parse "all", since it's the same as "and" + - name: ALL + tests: + - schemas: [v1beta1] + cases: + - condition: + all: + - const: true + - const: true + expected_result: true - name: OR tests: - schemas: [v1alpha1] @@ -49,6 +59,19 @@ test_suites: or: - const: true expected_result: true + - condition: + or: [] + expected_result: false + # Just check we can parse "any", since it's the same as "or" + - name: ANY + tests: + - schemas: [v1beta1] + cases: + - condition: + any: + - const: false + - const: false + expected_result: false - name: NOT tests: - schemas: [v1alpha1] @@ -143,6 +166,20 @@ test_suites: - maxCPU: 1 - maxCPU: 2 expected_result: [2, 3] + # Just check we can parse "map", since it's the same as "forEach" + - name: MAP + tests: + - schemas: [v1beta1] + cases: + - condition: + map: + elements: + const: [1, 2] + op: + sum: + - const: 10 + - getValue: "." + expected_result: [11, 12] - name: CONTAIN tests: - schemas: [v1alpha1]