diff --git a/plugins/plugin_utils/keep_keys.py b/plugins/plugin_utils/keep_keys.py index de77ade5..3e827943 100644 --- a/plugins/plugin_utils/keep_keys.py +++ b/plugins/plugin_utils/keep_keys.py @@ -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"): @@ -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] diff --git a/tests/integration/targets/utils_keep_keys/tasks/simple.yaml b/tests/integration/targets/utils_keep_keys/tasks/simple.yaml index 6ef0506e..f0073481 100644 --- a/tests/integration/targets/utils_keep_keys/tasks/simple.yaml +++ b/tests/integration/targets/utils_keep_keys/tasks/simple.yaml @@ -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