ansible-collections/ansible.utils

sub_plugins/fact_diff/native.py does not process dict objects properly

joshinryz opened this issue · 1 comments

SUMMARY

When passing facts to fact_diff, if you add ignore_lines the process treats the dict like a list and adds its keys as strings (removing values).

Specifically these lines: (60-69):

self._before = [ line for line in self._before if not any(regex.match(str(line)) for regex in self._skip_lines) ] self._after = [ line for line in self._after if not any(regex.match(str(line)) for regex in self._skip_lines) ]

ISSUE TYPE
  • Bug Report
COMPONENT NAME

sub_plugins/fact_diff/native.py

ANSIBLE VERSION
ansible [core 2.13.1]
STEPS TO REPRODUCE
- name: Show the difference in json format
  ansible.utils.fact_diff:
    before: "{{ before }}"
    after: "{{ after }}"
    plugin:
      name: ansible.utils.native
      vars:
         skip_lines:
            - '^example.*'
EXPECTED RESULTS

Should properly handle dicts, instead it will break if skip_lines is included (causing two different facts to appear the same).
As it will only compare key names and not their values.

Example change to remedy:

if isinstance(self._before, dict):
    self._before = {k:self._before[k] for k in self._before if not any(regex.match("{}: {}".format(k, self._before[k])) for regex in self._skip_lines) }
else:
    self._before = [
        line 
        for line in self._before 
        if not any(regex.match(str(line)) for regex in self._skip_lines)    
    ]

if isinstance(self._after, dict):
    self._after = {k:self._after[k] for k in self._after if not any(regex.match("{}: {}".format(k, self._after[k])) for regex in self._skip_lines) }
else:
    self._after = [
        line
        for line in self._after
        if not any(regex.match(str(line)) for regex in self._skip_lines)
    ]
                ```