list2form : gestion des erreurs et des petits fichiers (merci cgi.py…)
[progfou.git] / nagios / nagios2jabber.py
CommitLineData
c187e616
P
1#!/usr/bin/python
2# -*- coding: utf-8 -*
3# Copyright: Agence universitaire de la Francophonie -- www.auf.org
4# Licence: GPL-3
5# Author: Jean Christophe André
6# Created: 2015-10-23
7#
8# Debian-Depends: python-xmpp
9#
10#
11# Exploite la norme XEP-0071 pour enrichir le message d'alerte envoyé par Nagios.
12#
13# Paramètres d'appel du script :
c5171941 14# - JID du destinataire
c187e616
P
15#
16# Informations transmises via l'entrée standard (stdin):
17# - dans le cas d'une annonce concernant un hôte :
18# Host: $HOSTALIAS$
19# State: $HOSTSTATE$
20# Info: $HOSTOUTPUT$
21# Date: $LONGDATETIME$
22# - dans le cas d'une annonce concernant un service :
23# Service: $SERVICEDESC$
24# Host: $HOSTNAME$
25# Address: $HOSTADDRESS$
26# State: $SERVICESTATE$
27# Info: $SERVICEOUTPUT$
28# Date: $LONGDATETIME$
29#
30# Mise en place :
31# - installation de ce script dans /usr/local/lib/nagios2jabber.py
32# - configuration de l'appel au script dans /etc/nagios3/commands.cfg :
33# define command {
34# command_name notify-host-by-jabber
35# command_line /usr/bin/printf "%b" "Host: $HOSTALIAS$\nState: $HOSTSTATE$\nInfo: $HOSTOUTPUT$\nDate: $LONGDATETIME$" | /usr/local/lib/nagios2jabber.py $CONTACTPAGER$
36# }
37# define command {
c4f3f6b1 38# command_name notify-service-by-jabber
c187e616
P
39# command_line /usr/bin/printf "%b" "Service: $SERVICEDESC$\nHost: $HOSTNAME$\nAddress: $HOSTADDRESS$\nState: $SERVICESTATE$\nInfo: $SERVICEOUTPUT$\nDate: $LONGDATETIME$" | /usr/local/lib/nagios2jabber.py $CONTACTPAGER$
40# }
41# - configuration des envois de messages jabber dans /etc/nagios3/conf.d/contacts.cfg
42# define contact {
c187e616
P
43# ...
44# host_notification_commands notify-host-by-jabber,notify-host-by-email
45# service_notification_commands notify-service-by-jabber,notify-service-by-email
46# ...
47# }
48
49from __future__ import print_function
50import sys # argv, stdin
51import time # strptime, strftime
52import xmpp
53
54_CONFIG = {
55 "jid": "nagios.announce@auf.org",
56 "password": "super-secret",
57}
58
59if len(sys.argv) != 2 or sys.argv[1] == "-h" or sys.argv[1] == "--help":
60 print("Usage: echo message | {} user@server".format(sys.argv[0]))
61 sys.exit(1)
62
63dest = sys.argv[1]
64text = sys.stdin.read()
c4f3f6b1
P
65rich_text = None
66
67# quelques variables dépendant du client
68client_is_pidgin = dest not in ("jean-christophe.andre@auf.org", )
69want_detailed_info = dest in ("moussa.nombre@auf.org", )
70link_fully_supported = not client_is_pidgin
c187e616
P
71
72# construit un dictionnaire d'informations
73items = [l.split(":", 1) for l in text.splitlines()]
74data = {k.strip().lower():v.strip() for k,v in items}
75#print("data={}".format(data))
76
77# remanie la date (si possible)
78if "date" in data:
79 try:
80 dt = time.strptime(data["date"], "%a %b %d %H:%M:%S %Z %Y")
81 data["date"] = time.strftime("%Y-%m-%d %H:%M:%S", dt)
82 except:
83 pass
84
85# fonction qui renvoie la couleur prévue pour un statut donné
86def state_color(state):
87 color = "blue"
88 if state == "OK" or state == "UP":
89 color = "green"
90 elif state == "WARNING" or state == "UNKNOWN":
91 color = "orange"
92 elif state == "CRITICAL" or state == "DOWN":
93 color = "red"
94 return color
95
96# fonction qui renvoie un texte enrichi pour le statut
97def state_enriched(state):
98 return "<strong>[<span style='color: {0};'>{1}</span>]</strong>"\
99 .format(state_color(state), state)
100
101# ajout du statut enrichi
102if "state" in data:
103 data["rich_state"] = state_enriched(data["state"])
104
105# remaniement des infos (suppression des redondances, gestion des lignes)
106if "info" in data:
107 if "service" in data and data["info"].startswith(data["service"]):
108 data["info"] = data["info"][len(data["service"]):].strip(" :-")
109 if "state" in data and data["info"].startswith(data["state"]):
110 data["info"] = data["info"][len(data["state"]):].strip(" :-")
111 data["info"] = data["info"].replace("\\n", "\n").strip("\n")
112 # prepare enriched info
113 data["rich_info"] = data["info"].replace("\n", "<br/>")
114 data["rich_info"] = data["rich_info"].replace("WARNING", state_enriched("WARNING"))
115 data["escaped_info"] = data["info"].replace("'", "&#39;").replace("<", "&lt;")
116
117#print("data={}".format(data))
118
119# construction des textes
c4f3f6b1
P
120try:
121 rich_text_list = [ "<span style='color: black;'><span>{date}</span> " ]
122 if link_fully_supported:
123 rich_text_list.append("<a href='void();' title='{escaped_info}'>{rich_state}</a>")
124 else:
125 rich_text_list.append("{rich_state}")
126 if "service" in data:
127 text = "{date}\t[{state}]\t{service} @{host}[{address}]\n{info}".format(**data)
128 rich_text_list.append(" <span style='color: blue;'>{service}</span> ")
129 rich_text_list.append("@<span style='color: blue;'>{host}</span>")
130 rich_text_list.append("[<span style='color: blue;'>{address}</span>]")
131 else:
132 text = "{date}\t[{state}]\t{host}\n{info}".format(**data)
133 rich_text_list.append(" <span style='color: blue;'>{host}</span>")
134 rich_text_list.append("</span>")
135 rich_text = ("".join(rich_text_list)).format(**data)
136 if want_detailed_info or not link_fully_supported:
137 rich_text = "<p>{}<br/><em>{rich_info}</em></p>".format(rich_text)
138except KeyError:
139 pass
c187e616
P
140
141# construction du message
c187e616 142message = xmpp.protocol.Message(to=dest, body=text, typ="chat")
c4f3f6b1
P
143if rich_text is not None:
144 html = xmpp.Node("html", {"xmlns": "http://jabber.org/protocol/xhtml-im"})
145 html.addChild(node=xmpp.simplexml.XML2Node(
146 "<body xmlns='http://www.w3.org/1999/xhtml'>{}</body>".format(rich_text)))
147 message.addChild(node=html)
c187e616
P
148
149# envoi du message
150jid = xmpp.protocol.JID(_CONFIG["jid"])
151client = xmpp.Client(jid.getDomain(), debug=[])
152client.connect()
153client.auth(jid.getNode(), _CONFIG["password"], "server")
154client.send(message)