Mik*_* T. 4 ansible ansible-playbook
对于某些文件类型,简单的统一差异不是很有帮助。一个明显的例子是二进制文件,但即使某些表面上是文本的文件——例如 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
Run Code Online (Sandbox Code Playgroud)
?
@konstantin-suvorov 的“hack”很棒,但它似乎只适用于已经有差异方法的模块。不幸的是,我的另一个用例涉及一个模块 ( command
),它没有。
特别是,我/usr/bin/apt-get update
在 Ubuntu 上调用,它更新apt
的缓存文件。我想在之前和之后以文本形式转储缓存的内容,看看更新发生了什么变化——如果有的话......
没有开箱即用的解决方案。我很想挑战这个。
这是自定义标准输出回调(放入./callback_plugins/diffhack.py
)。
它基于默认的标准输出回调default.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)
Run Code Online (Sandbox Code Playgroud)
然后您可以将其设置prediff_cmd
为任务的变量并%s
替换为临时文件:
- copy:
src: cert.pem
dest: /tmp/cert.pem
vars:
prediff_cmd: openssl x509 -in %s -noout -text | head -n 10
Run Code Online (Sandbox Code Playgroud)
并设置默认回调,例如:
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
Run Code Online (Sandbox Code Playgroud)