对于一些文件types,简单的统一差异不是很有帮助。 一个明显的例子是二进制文件,但是甚至某些表面上的文本文件(如SSL证书( .pem ))也属于这个类别。
那么,一个任务可以指定自己的显示差异的方法吗? 就像是:
- name: Update SSL certificate copy: src: etc/ssl/mycert.pem dest: /etc/ssl/mycert.pem diff: exec: > openssl x509 -in {{ old }} -noout -text > {{ old }}.txt openssl x509 -in {{ new }} -noout -text > {{ new }}.txt diff -U2 {{ old }}.txt {{ new }}.txt rm -f {{ old }}.txt {{ new }}.txt
?
@ konstantin-suvorov的“黑客”非常棒,但它似乎只适用于模块,而这些模块已经有了一个diff方法。 不幸的是,我的另一个用例涉及一个模块( command ),而不是。
特别是,我在Ubuntu上调用了/usr/bin/apt-get update ,它更新了apt的caching文件。 我想转储caching的内容在文本forms之前和之后,看看,什么更新已经改变 – 如果有的话…
没有现成的解决scheme。 我很好奇挑战这个。
这里是自定义的stdoutcallback(放在./callback_plugins/diffhack.py )。
它基于默认的标准输出callbackdefault.py 。
from ansible.plugins.callback.default import CallbackModule as DefaultCallback from subprocess import check_output, CalledProcessError, STDOUT from tempfile import mkstemp import os try: from __main__ import display except ImportError: display = None class CallbackModule(DefaultCallback): def v2_on_file_diff(self, result): def process_diff(diff, cmd): for d in diff: for ab in ('after','before'): fd, fn = mkstemp() print fn with open(fn, 'w') as f: f.write(d[ab]) try: new_cmd = cmd.replace('%s',fn) res = check_output(new_cmd, stderr=STDOUT, shell=True) except CalledProcessError as e: display.warning('Error occured while calling prediff_cmd "{}": (Code {}) {}'.format(cmd, e.returncode, e.output)) res = None os.unlink(fn) if res: d[ab] = res return diff if 'prediff_cmd' in result._task_fields['vars']: prediff_cmd = result._task_fields['vars']['prediff_cmd'] if result._task.loop and 'results' in result._result: for res in result._result['results']: if 'diff' in res and res['diff'] and res.get('changed', False): res['diff'] = process_diff(res['diff'], prediff_cmd) elif 'diff' in result._result and result._result['diff'] and result._result.get('changed', False): result._result['diff'] = process_diff(result._result['diff'], prediff_cmd) return super(CallbackModule, self).v2_on_file_diff(result)
然后,您可以将prediff_cmd设置为任务的variables,将%sreplace为临时文件:
- copy: src: cert.pem dest: /tmp/cert.pem vars: prediff_cmd: openssl x509 -in %s -noout -text | head -n 10
并设置默认callback,例如:
ANSIBLE_STDOUT_CALLBACK=diffhack ansible-playbook -vv --check --diff test.yml
看到这个结果:
TASK [copy] *************************** /var/folders/4c/4t2731dn3csd9b4sv4d2xm5m0000gn/T/tmpS5fOdj /var/folders/4c/4t2731dn3csd9b4sv4d2xm5m0000gn/T/tmpS4UM7N --- before: /tmp/cert.pem +++ after: /path/to/local/cert.pem @@ -2,9 +2,9 @@ Data: Version: 3 (0x2) Serial Number: - aa:fc:53:d8:29:d2:8a:58 + d2:05:f8:5c:61:ff:9e:d3 Signature Algorithm: sha256WithRSAEncryption Issuer: CN=localhost Validity - Not Before: Oct 13 07:32:01 2017 GMT - Not After : Oct 13 07:32:01 2018 GMT + Not Before: Oct 13 07:32:25 2017 GMT + Not After : Oct 13 07:32:25 2018 GMT