Ansible: enviar e-mail no host inacessível

0

Gostaria de receber um email sempre que um dos hosts em ansible não puder ser acessado por meio do SSH.

Eu tentei escrever um playbook para fazer isso (veja abaixo). Depois de coletar fatos, qualquer host inacessível é descartado, então minha tarefa enviando o email nunca é executada para os hosts inacessíveis.

-name: Check host accessibility
  hosts: all
  tasks:
    - local_action: shell ssh deploy@{{ansible_hostname}} echo OK
      register: check_ssh
    - local_action: debug msg="{{check_ssh.stdout}}"
      when: check_ssh.stdout != "OK"

Muito obrigado.

    
por Lluís Vilanova 09.11.2015 / 17:23

2 respostas

0

Descobri que usar um script Python é a solução mais fácil (mais fácil do que um plug-in de retorno de chamada, pelo menos na minha versão ansible 1.7):

#!/usr/bin/env python

from __future__ import print_function
import ansible.inventory
import ansible.runner                                                                                   
from subprocess import Popen, PIPE
import sys


TO = "root"


def message(subject, body):
    p = Popen(["mail", "-s", subject, TO], stdin=PIPE)                                                  
    p.communicate(input=body)                                                                           
    res = p.wait()                                                                                      
    if res != 0:
        print("Failed to send message", file=sys.stderr)                                                


def main():
    im = ansible.inventory.Inventory()                                                                  
    runner = ansible.runner.Runner(                                                                     
        module_name='command',                                                                          
        module_args='sh -c "echo OK"',                                                                  
        sudo=True,
    )                                                                                                   
    run = runner.run()
    nosudo = set(run["dark"].keys())

    runner = ansible.runner.Runner(
        module_name='command',
        module_args='sh -c "echo OK"',                                                                  
        sudo=False,
        inventory=ansible.inventory.Inventory(list(nosudo)),                                            
    )   
    run = runner.run()                                                                                  
    nonet = set(run["dark"].keys()) 

    nosudo = nosudo - nonet

    for host in nosudo:                                                                                 
        message("Host check: %s" % host,
                "Cannot execute 'sudo -u root ...' as user 'deploy'.")                                  
    for host in nonet:
        message("Host check: %s" % host,
                "Cannot login into the machine.")


if __name__ == '__main__':                                                                              
    main()      
    
por 09.11.2015 / 19:08
0

Aqui está a minha solução para ansible > 2.0 :

- name: Check host accessibility
  hosts: all
  user: deploy
  gather_facts: no
  tasks:
    - block:
        - command: echo OK

        - assert:
            that:
              - ansible_play_hosts == ansible_play_hosts_all
      rescue:

        - name: send email when something goes wrong (pe, cannot reach a machine)
          local_action:
            module: mail
            host: localhost
            to: < email here >
            from: < email here >
            subject: 'Host check - {{ (ansible_play_hosts_all | difference(ansible_play_hosts)) | first }}'
            body: 'Cannot login into the machine'
          when: inventory_hostname == "< hostname of main server here >"

Essa é a melhor solução que consegui produzir até agora. É uma pena que ansible não considere unreachable hosts como failed , então uma rescue nunca é chamada. Eu superei esse problema contando o número de host que executou a última tarefa em relação à quantidade total de hosts. Se for diferente, significa que pelo menos um host é unreachable , executando assim a declaração e indo para a seção rescue . Então, o segundo problema é que a declaração se aplica a todos os hosts, então temos que escolher apenas um host para enviar o email (nesse caso eu escolhi o servidor onde o ansible está instalado).

    
por 30.01.2018 / 17:49

Tags