Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

keep_keys: fix keeping all lists, even wrong ones #379

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 28 additions & 29 deletions plugins/plugin_utils/keep_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,41 +29,40 @@ def _raise_error(msg):


def keep_keys_from_dict_n_list(data, target, matching_parameter):
match = False
if isinstance(data, list):
list_data = [keep_keys_from_dict_n_list(each, target, matching_parameter) for each in data]
return list_data
return [d[0] for d in list_data], any([d[1] for d in list_data])
if isinstance(data, dict):
keep = {}
for k, val in data.items():
match = False
for key in target:
if k == key:
keep[k], match = val, True
elif not isinstance(val, (list, dict)):
if matching_parameter == "regex":
if re.match(key, k):
keep[k], match = val, True
elif matching_parameter == "starts_with":
if k.startswith(key):
keep[k], match = val, True
elif matching_parameter == "ends_with":
if k.endswith(key):
keep[k], match = val, True
else:
if k == key:
keep[k], match = val, True
# We start by looking for partial nested keys match if its a list or a dict
if isinstance(val, (list, dict)):
nested_keep, has_some_match = keep_keys_from_dict_n_list(
val,
target,
matching_parameter,
)
if has_some_match:
keep[k] = nested_keep
match = has_some_match
# We then check current key against comparator, as we want to keep it fully
# If current key is valid
if matching_parameter == "regex":
if re.match(key, k):
keep[k], match = val, True
elif matching_parameter == "starts_with":
if k.startswith(key):
keep[k], match = val, True
elif matching_parameter == "ends_with":
if k.endswith(key):
keep[k], match = val, True
else:
list_data = keep_keys_from_dict_n_list(val, target, matching_parameter)
if isinstance(list_data, list):
list_data = [r for r in list_data if r not in ([], {})]
if list_data not in ([], {}):
keep[k], match = list_data, True
if not match and isinstance(val, (list, dict)):
nested_keep = keep_keys_from_dict_n_list(val, target, matching_parameter)
if nested_keep not in ([], {}):
keep[k] = nested_keep
return keep
return data
if k == key:
keep[k], match = val, True
return keep, match
return data, match


def keep_keys(data, target, matching_parameter="equality"):
Expand All @@ -79,4 +78,4 @@ def keep_keys(data, target, matching_parameter="equality"):
if not isinstance(data, (list, dict)):
_raise_error("Input is not valid for keep operation")
data = keep_keys_from_dict_n_list(data, target, matching_parameter)
return data
return data[0]
8 changes: 4 additions & 4 deletions tests/integration/targets/utils_keep_keys/tasks/simple.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,12 @@
tomcat3:
name: tomcattest
checktomcat3: stringinput
tomcats_block:
- tomcat1
- tomcat2
tomcats_block:
- tomcat1
- tomcat2
- name: Debug
ansible.builtin.debug:
msg: "{{ tomcat_data | ansible.utils.keep_keys(target=['tomcats_block']) }}"
msg: "{{ tomcat_data['tomcat'] | ansible.utils.keep_keys(target=['tomcats_block']) }}"
register: result

- name: Assert result dicts
Expand Down