From 1ecc8544f61173a8d3dca16aa2309d989b6ec3f6 Mon Sep 17 00:00:00 2001 From: Tobias Wolf Date: Wed, 27 Jan 2016 12:33:24 +0100 Subject: [PATCH] Add diff for both file contents and file attributes to lineinfile Using the difflist feature added in ansible/ansible@c337293 we can add two diffs to the `diff` dict returned as JSON: A `before` and `after` pair of changed file contents and the diff of the file attributes. n.b.: the difflist handling from the above commit is logically broken. PR will follow. Example output: TASK [change line and mode] ************************************************************ changed: [localhost] --- before: /tmp/sshd_config (content) +++ after: /tmp/sshd_config (content) @@ -65,21 +65,21 @@ X11DisplayOffset 10 PrintMotd no PrintLastLog yes TCPKeepAlive yes #UseLogin no #MaxStartups 10:30:60 #Banner /etc/issue.net # Allow client to pass locale environment variables -AcceptEnv LANG LC_* +AcceptEnv LANG LC_* GF_ENV_* Subsystem sftp /usr/lib/openssh/sftp-server # Set this to 'yes' to enable PAM authentication, account processing, # and session processing. If this is enabled, PAM authentication will # be allowed through the ChallengeResponseAuthentication and # PasswordAuthentication. Depending on your PAM configuration, # PAM authentication via ChallengeResponseAuthentication may bypass # the setting of "PermitRootLogin without-password". # If you just want the PAM account and session checks to run without --- before: /tmp/sshd_config (file attributes) +++ after: /tmp/sshd_config (file attributes) @@ -1,3 +1,3 @@ { - "mode": "0700" + "mode": "0644" } --- lib/ansible/modules/files/lineinfile.py | 52 ++++++++++++++++++++----- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/lib/ansible/modules/files/lineinfile.py b/lib/ansible/modules/files/lineinfile.py index 777f0a498a..59944d4d20 100644 --- a/lib/ansible/modules/files/lineinfile.py +++ b/lib/ansible/modules/files/lineinfile.py @@ -166,10 +166,10 @@ def write_changes(module,lines,dest): if valid: module.atomic_move(tmpfile, os.path.realpath(dest)) -def check_file_attrs(module, changed, message): +def check_file_attrs(module, changed, message, diff): file_args = module.load_file_common_arguments(module.params) - if module.set_fs_attributes_if_different(file_args, False): + if module.set_fs_attributes_if_different(file_args, False, diff=diff): if changed: message += " and " @@ -182,6 +182,11 @@ def check_file_attrs(module, changed, message): def present(module, dest, regexp, line, insertafter, insertbefore, create, backup, backrefs): + diff = {'before': '', + 'after': '', + 'before_header': '%s (content)' % dest, + 'after_header': '%s (content)' % dest} + if not os.path.exists(dest): if not create: module.fail_json(rc=257, msg='Destination %s does not exist !' % dest) @@ -194,7 +199,8 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create, lines = f.readlines() f.close() - msg = "" + if module._diff: + diff['before'] = ''.join(lines) if regexp is not None: mre = re.compile(regexp) @@ -270,6 +276,9 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create, msg = 'line added' changed = True + if module._diff: + diff['after'] = ''.join(lines) + backupdest = "" if changed and not module.check_mode: if backup and os.path.exists(dest): @@ -277,10 +286,16 @@ def present(module, dest, regexp, line, insertafter, insertbefore, create, write_changes(module, lines, dest) if module.check_mode and not os.path.exists(dest): - module.exit_json(changed=changed, msg=msg, backup=backupdest) + module.exit_json(changed=changed, msg=msg, backup=backupdest, diff=diff) - msg, changed = check_file_attrs(module, changed, msg) - module.exit_json(changed=changed, msg=msg, backup=backupdest) + attr_diff = {} + msg, changed = check_file_attrs(module, changed, msg, attr_diff) + + attr_diff['before_header'] = '%s (file attributes)' % dest + attr_diff['after_header'] = '%s (file attributes)' % dest + + difflist = [diff, attr_diff] + module.exit_json(changed=changed, msg=msg, backup=backupdest, diff=difflist) def absent(module, dest, regexp, line, backup): @@ -288,11 +303,19 @@ def absent(module, dest, regexp, line, backup): if not os.path.exists(dest): module.exit_json(changed=False, msg="file not present") - msg = "" + msg = '' + diff = {'before': '', + 'after': '', + 'before_header': '%s (content)' % dest, + 'after_header': '%s (content)' % dest} f = open(dest, 'rb') lines = f.readlines() f.close() + + if module._diff: + diff['before'] = ''.join(lines) + if regexp is not None: cre = re.compile(regexp) found = [] @@ -308,6 +331,10 @@ def absent(module, dest, regexp, line, backup): lines = filter(matcher, lines) changed = len(found) > 0 + + if module._diff: + diff['after'] = ''.join(lines) + backupdest = "" if changed and not module.check_mode: if backup: @@ -317,8 +344,15 @@ def absent(module, dest, regexp, line, backup): if changed: msg = "%s line(s) removed" % len(found) - msg, changed = check_file_attrs(module, changed, msg) - module.exit_json(changed=changed, found=len(found), msg=msg, backup=backupdest) + attr_diff = {} + msg, changed = check_file_attrs(module, changed, msg, attr_diff) + + attr_diff['before_header'] = '%s (file attributes)' % dest + attr_diff['after_header'] = '%s (file attributes)' % dest + + difflist = [diff, attr_diff] + + module.exit_json(changed=changed, found=len(found), msg=msg, backup=backupdest, diff=difflist) def main():