Skip to content
3 changes: 3 additions & 0 deletions changelogs/fragments/update_fact_bracket.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
bugfixes:
- Fix update_fact to update a fact where a key in the referenced path contains a bracket.
44 changes: 16 additions & 28 deletions plugins/action/update_fact.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
13 changes: 13 additions & 0 deletions tests/integration/targets/utils_update_fact/tasks/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
c:
- 1
- 2
d:
"[bracket_key]": bracket_value
key: value

- name: Update the fact
ansible.utils.update_fact:
Expand All @@ -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
Expand All @@ -26,6 +33,9 @@
c:
- 10
- 20
d:
"[bracket_key]": new_bracket_value
key: new_value

- name: Update the fact
ansible.utils.update_fact:
Expand Down Expand Up @@ -70,3 +80,6 @@
c:
- 1
- 20
d:
"[bracket_key]": bracket_value
key: value
Loading