1# Copyright (C) 2016 maxn nikolaev.makc@gmail.com
2# Copyright (c) 2017 Ansible Project
3# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
4
5from __future__ import (absolute_import, division, print_function)
6__metaclass__ = type
7
8DOCUMENTATION = '''
9    callback: jabber
10    type: notification
11    short_description: post task events to a jabber server
12    description:
13      - The chatty part of ChatOps with a Hipchat server as a target
14      - This callback plugin sends status updates to a HipChat channel during playbook execution.
15    version_added: "2.2"
16    requirements:
17      - xmpp (python lib https://github.com/ArchipelProject/xmpppy)
18    options:
19      server:
20        description: connection info to jabber server
21        required: True
22        env:
23          - name: JABBER_SERV
24      user:
25        description: Jabber user to authenticate as
26        required: True
27        env:
28          - name: JABBER_USER
29      password:
30        description: Password for the user to the jabber server
31        required: True
32        env:
33          - name: JABBER_PASS
34      to:
35        description: chat identifier that will recieve the message
36        required: True
37        env:
38          - name: JABBER_TO
39'''
40
41import os
42
43HAS_XMPP = True
44try:
45    import xmpp
46except ImportError:
47    HAS_XMPP = False
48
49from ansible.plugins.callback import CallbackBase
50
51
52class CallbackModule(CallbackBase):
53
54    CALLBACK_VERSION = 2.0
55    CALLBACK_TYPE = 'notification'
56    CALLBACK_NAME = 'jabber'
57    CALLBACK_NEEDS_WHITELIST = True
58
59    def __init__(self, display=None):
60
61        super(CallbackModule, self).__init__(display=display)
62
63        if not HAS_XMPP:
64            self._display.warning("The required python xmpp library (xmpppy) is not installed. "
65                                  "pip install git+https://github.com/ArchipelProject/xmpppy")
66            self.disabled = True
67
68        self.serv = os.getenv('JABBER_SERV')
69        self.j_user = os.getenv('JABBER_USER')
70        self.j_pass = os.getenv('JABBER_PASS')
71        self.j_to = os.getenv('JABBER_TO')
72
73        if (self.j_user or self.j_pass or self.serv or self.j_to) is None:
74            self.disabled = True
75            self._display.warning('Jabber CallBack wants the JABBER_SERV, JABBER_USER, JABBER_PASS and JABBER_TO environment variables')
76
77    def send_msg(self, msg):
78        """Send message"""
79        jid = xmpp.JID(self.j_user)
80        client = xmpp.Client(self.serv, debug=[])
81        client.connect(server=(self.serv, 5222))
82        client.auth(jid.getNode(), self.j_pass, resource=jid.getResource())
83        message = xmpp.Message(self.j_to, msg)
84        message.setAttr('type', 'chat')
85        client.send(message)
86        client.disconnect()
87
88    def v2_runner_on_ok(self, result):
89        self._clean_results(result._result, result._task.action)
90        self.debug = self._dump_results(result._result)
91
92    def v2_playbook_on_task_start(self, task, is_conditional):
93        self.task = task
94
95    def v2_playbook_on_play_start(self, play):
96        """Display Playbook and play start messages"""
97        self.play = play
98        name = play.name
99        self.send_msg("Ansible starting play: %s" % (name))
100
101    def playbook_on_stats(self, stats):
102        name = self.play
103        hosts = sorted(stats.processed.keys())
104        failures = False
105        unreachable = False
106        for h in hosts:
107            s = stats.summarize(h)
108            if s['failures'] > 0:
109                failures = True
110            if s['unreachable'] > 0:
111                unreachable = True
112
113        if failures or unreachable:
114            out = self.debug
115            self.send_msg("%s: Failures detected \n%s \nHost: %s\n Failed at:\n%s" % (name, self.task, h, out))
116        else:
117            out = self.debug
118            self.send_msg("Great! \n Playbook %s completed:\n%s \n Last task debug:\n %s" % (name, s, out))
119