From 547abc0e28bae76a87300f7eafc062023511d263 Mon Sep 17 00:00:00 2001 From: Emanuele Bernardi Date: Fri, 16 Aug 2024 11:37:42 +0000 Subject: [PATCH 1/2] using regex for path split --- changelogs/fragments/update_fact_bracket.yaml | 3 ++ plugins/action/update_fact.py | 44 +++++++------------ .../targets/utils_update_fact/tasks/main.yaml | 13 ++++++ 3 files changed, 32 insertions(+), 28 deletions(-) create mode 100644 changelogs/fragments/update_fact_bracket.yaml diff --git a/changelogs/fragments/update_fact_bracket.yaml b/changelogs/fragments/update_fact_bracket.yaml new file mode 100644 index 00000000..91049ae3 --- /dev/null +++ b/changelogs/fragments/update_fact_bracket.yaml @@ -0,0 +1,3 @@ +--- +bugfixes: + - Fix update_fact to update a fact where a key in the referenced path contains a bracket. diff --git a/plugins/action/update_fact.py b/plugins/action/update_fact.py index 32393ed4..4ad49e94 100644 --- a/plugins/action/update_fact.py +++ b/plugins/action/update_fact.py @@ -70,39 +70,27 @@ def _field_split(path): :return: the individual parts of the path :rtype: list """ - que = list(path) - val = que.pop(0) + que = path fields = [] - try: - while True: - field = "" - # found a '.', move to the next character - if val == ".": - val = que.pop(0) - # found a '[', pop until ']' and then get the next - if val == "[": - val = que.pop(0) - while val != "]": - field += val - val = que.pop(0) - val = que.pop(0) - else: - while val not in [".", "["]: - field += val - val = que.pop(0) - try: - # make numbers numbers - fields.append(ast.literal_eval(field)) - except Exception: - # or strip the quotes - fields.append(re.sub("['\"]", "", field)) - except IndexError: - # pop'ed past the end of the que - # so add the final field + # regex match dotted values and square brackets + regex = re.compile(r'^[^\[\].]+|^\[[\'\"].+?[\'\"]\]|^\[.+?\]') + while (regex.match(que)): + m = regex.match(que) + # remove outer square brackets + field = re.sub(r'(^\[)|(\]$)', "", que[m.start():m.end()]) try: + # make numbers numbers fields.append(ast.literal_eval(field)) except Exception: + # or strip the quotes fields.append(re.sub("['\"]", "", field)) + try: + if que[m.end()] == '.': + que = que[m.end() + 1:] + else: + que = que[m.end():] + except IndexError: + que = '' return fields def set_value(self, obj, path, val): diff --git a/tests/integration/targets/utils_update_fact/tasks/main.yaml b/tests/integration/targets/utils_update_fact/tasks/main.yaml index 8e2a68c0..2f198403 100644 --- a/tests/integration/targets/utils_update_fact/tasks/main.yaml +++ b/tests/integration/targets/utils_update_fact/tasks/main.yaml @@ -6,6 +6,9 @@ c: - 1 - 2 + d: + "[bracket_key]": bracket_value + key: value - name: Update the fact ansible.utils.update_fact: @@ -14,6 +17,10 @@ value: 10 - path: "a['b']['c'][1]" value: 20 + - path: "a['b'][d]['[bracket_key]']" + value: new_bracket_value + - path: "a['b'][d]['key']" + value: new_value register: updated - name: Assert @@ -26,6 +33,9 @@ c: - 10 - 20 + d: + "[bracket_key]": new_bracket_value + key: new_value - name: Update the fact ansible.utils.update_fact: @@ -70,3 +80,6 @@ c: - 1 - 20 + d: + "[bracket_key]": bracket_value + key: value From 428be1f9327857a94dc543697d61bfc2cf60e8ca Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 11:40:25 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- plugins/action/update_fact.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/plugins/action/update_fact.py b/plugins/action/update_fact.py index 4ad49e94..323f9f93 100644 --- a/plugins/action/update_fact.py +++ b/plugins/action/update_fact.py @@ -73,11 +73,11 @@ def _field_split(path): que = path fields = [] # regex match dotted values and square brackets - regex = re.compile(r'^[^\[\].]+|^\[[\'\"].+?[\'\"]\]|^\[.+?\]') - while (regex.match(que)): + regex = re.compile(r"^[^\[\].]+|^\[[\'\"].+?[\'\"]\]|^\[.+?\]") + while regex.match(que): m = regex.match(que) # remove outer square brackets - field = re.sub(r'(^\[)|(\]$)', "", que[m.start():m.end()]) + field = re.sub(r"(^\[)|(\]$)", "", que[m.start() : m.end()]) try: # make numbers numbers fields.append(ast.literal_eval(field)) @@ -85,12 +85,12 @@ def _field_split(path): # or strip the quotes fields.append(re.sub("['\"]", "", field)) try: - if que[m.end()] == '.': - que = que[m.end() + 1:] + if que[m.end()] == ".": + que = que[m.end() + 1 :] else: - que = que[m.end():] + que = que[m.end() :] except IndexError: - que = '' + que = "" return fields def set_value(self, obj, path, val):