Posso sobrescrever, o que 'diff' significa para uma tarefa?

4

Com alguns tipos de arquivo, o diff unificado simples não é muito útil. Um exemplo óbvio são os arquivos binários, mas mesmo certos textos ostensivamente - como os certificados SSL ( .pem ) - também se enquadram nessa categoria.

Então, uma tarefa pode especificar seu próprio método de exibir diferenças? Algo como:

- 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

?

@ O "hack" de konstantin-suvorov é maravilhoso, mas parece que funcionaria apenas para módulos, que já possuem um método diff. Infelizmente, meu outro caso de uso envolve um módulo ( command ), o que não acontece.

Em particular, invoco /usr/bin/apt-get update no Ubuntu, que atualiza os arquivos de cache apt . Eu gostaria de despejar o conteúdo do cache em forma de texto antes e depois para ver, o que a atualização mudou - se alguma coisa ...

    
por Mikhail T. 12.10.2017 / 18:08

1 resposta

4

Não há solução pronta para uso. Eu estava curioso para desafiar isso.

Aqui está o retorno de chamada padrão do stdout (coloque em ./callback_plugins/diffhack.py ).
Ele é baseado no retorno de chamada padrão stdout 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)

Em seguida, você pode definir prediff_cmd como variável da tarefa com %s sendo substituído por arquivo temporário:

- copy:
    src: cert.pem
    dest: /tmp/cert.pem
  vars:
    prediff_cmd: openssl x509 -in %s -noout -text | head -n 10

E defina o retorno de chamada padrão, por exemplo:

ANSIBLE_STDOUT_CALLBACK=diffhack ansible-playbook -vv --check --diff test.yml

Para ver este resultado:

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
    
por 13.10.2017 / 10:08