Ansible: 연결할 수 없는 호스트에서 이메일 보내기

Ansible: 연결할 수 없는 호스트에서 이메일 보내기

Ansible의 호스트에 SSH를 통해 액세스할 수 없게 되면 이메일을 받고 싶습니다.

나는 바로 그 일을 하기 위해 연극을 쓰려고 노력했습니다(아래 참조). 사실을 수집한 후 연결할 수 없는 호스트는 삭제되므로 이메일을 보내는 작업은 연결할 수 없는 호스트에 대해 실행되지 않습니다.

-name: 호스트 접근성 확인
  후원자: 모두
  일:
    - local_action: shell ssh 배포@{{ansible_hostname}} echo OK
      등록: check_ssh
    - local_action: 디버그 메시지 = "{{check_ssh.stdout}}"
      언제: check_ssh.stdout! = "알았어"

감사합니다.

답변1

이것이 내 솔루션입니다 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 >"

이것이 제가 제공할 수 있는 최고의 솔루션입니다. 불행히도 호스트가 이라고 생각 ansible하지 않으므로 섹션이 호출되지 않습니다. 총 호스트 수 대비 마지막 작업을 수행한 호스트 수를 계산하는 문제를 해결했습니다. 다르다면 최소한 하나의 호스트가 있다는 의미 이므로 어설션을 수행하고 해당 섹션으로 이동하세요. 그런 다음 두 번째 문제는 어설션이 모든 호스트에서 작동하므로 이메일을 보낼 호스트를 하나만 선택해야 한다는 것입니다(이 경우 Ansible이 설치된 서버를 선택했습니다).unreachablefailedrescueunreachablerescue

답변2

저는 Python 스크립트를 사용하는 것이 가장 간단한 솔루션이라는 것을 알았습니다(적어도 내 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()      

관련 정보