# -*- coding: utf-8 -*- # (c) 2018 Remi Verchere # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # SPDX-License-Identifier: GPL-3.0-or-later # Make coding more python3-ish from __future__ import (absolute_import, division, print_function) __metaclass__ = type DOCUMENTATION = ''' name: nrdp type: notification author: "Remi VERCHERE (@rverchere)" short_description: Post task results to a Nagios server through nrdp description: - This callback send playbook result to Nagios. - Nagios shall use NRDP to recive passive events. - The passive check is sent to a dedicated host/service for Ansible. options: url: description: URL of the nrdp server. required: true env: - name : NRDP_URL ini: - section: callback_nrdp key: url type: string validate_certs: description: Validate the SSL certificate of the nrdp server. (Used for HTTPS URLs.) env: - name: NRDP_VALIDATE_CERTS ini: - section: callback_nrdp key: validate_nrdp_certs - section: callback_nrdp key: validate_certs type: boolean default: false aliases: [ validate_nrdp_certs ] token: description: Token to be allowed to push nrdp events. required: true env: - name: NRDP_TOKEN ini: - section: callback_nrdp key: token type: string hostname: description: Hostname where the passive check is linked to. required: true env: - name : NRDP_HOSTNAME ini: - section: callback_nrdp key: hostname type: string servicename: description: Service where the passive check is linked to. required: true env: - name : NRDP_SERVICENAME ini: - section: callback_nrdp key: servicename type: string ''' import os import json from ansible.module_utils.six.moves.urllib.parse import urlencode from ansible.module_utils.common.text.converters import to_bytes from ansible.module_utils.urls import open_url from ansible.plugins.callback import CallbackBase class CallbackModule(CallbackBase): ''' send ansible-playbook to Nagios server using nrdp protocol ''' CALLBACK_VERSION = 2.0 CALLBACK_TYPE = 'notification' CALLBACK_NAME = 'community.general.nrdp' CALLBACK_NEEDS_WHITELIST = True # Nagios states OK = 0 WARNING = 1 CRITICAL = 2 UNKNOWN = 3 def __init__(self): super(CallbackModule, self).__init__() self.printed_playbook = False self.playbook_name = None self.play = None def set_options(self, task_keys=None, var_options=None, direct=None): super(CallbackModule, self).set_options(task_keys=task_keys, var_options=var_options, direct=direct) self.url = self.get_option('url') if not self.url.endswith('/'): self.url += '/' self.token = self.get_option('token') self.hostname = self.get_option('hostname') self.servicename = self.get_option('servicename') self.validate_nrdp_certs = self.get_option('validate_certs') if (self.url or self.token or self.hostname or self.servicename) is None: self._display.warning("NRDP callback wants the NRDP_URL," " NRDP_TOKEN, NRDP_HOSTNAME," " NRDP_SERVICENAME" " environment variables'." " The NRDP callback plugin is disabled.") self.disabled = True def _send_nrdp(self, state, msg): ''' nrpd service check send XMLDATA like this: somehost someservice 1 WARNING: Danger Will Robinson!|perfdata ''' xmldata = "\n" xmldata += "\n" xmldata += "\n" xmldata += "%s\n" % self.hostname xmldata += "%s\n" % self.servicename xmldata += "%d\n" % state xmldata += "%s\n" % msg xmldata += "\n" xmldata += "\n" body = { 'cmd': 'submitcheck', 'token': self.token, 'XMLDATA': to_bytes(xmldata) } try: response = open_url(self.url, data=urlencode(body), method='POST', validate_certs=self.validate_nrdp_certs) return response.read() except Exception as ex: self._display.warning("NRDP callback cannot send result {0}".format(ex)) def v2_playbook_on_play_start(self, play): ''' Display Playbook and play start messages ''' self.play = play def v2_playbook_on_stats(self, stats): ''' Display info about playbook statistics ''' name = self.play gstats = "" hosts = sorted(stats.processed.keys()) critical = warning = 0 for host in hosts: stat = stats.summarize(host) gstats += "'%s_ok'=%d '%s_changed'=%d \ '%s_unreachable'=%d '%s_failed'=%d " % \ (host, stat['ok'], host, stat['changed'], host, stat['unreachable'], host, stat['failures']) # Critical when failed tasks or unreachable host critical += stat['failures'] critical += stat['unreachable'] # Warning when changed tasks warning += stat['changed'] msg = "%s | %s" % (name, gstats) if critical: # Send Critical self._send_nrdp(self.CRITICAL, msg) elif warning: # Send Warning self._send_nrdp(self.WARNING, msg) else: # Send OK self._send_nrdp(self.OK, msg)