nagios2jabber.py : enrichissement des messages Jabber de Nagios
[progfou.git] / nagios / nagios2jabber.py
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 :
14 # - destination JID
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 {
38 # command_name notify-service-by-jabber-jc
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 {
43 # contact_name jc
44 # ...
45 # host_notification_commands notify-host-by-jabber,notify-host-by-email
46 # service_notification_commands notify-service-by-jabber,notify-service-by-email
47 # ...
48 # }
49
50 from __future__ import print_function
51 import sys # argv, stdin
52 import time # strptime, strftime
53 import xmpp
54
55 _CONFIG = {
56 "jid": "nagios.announce@auf.org",
57 "password": "super-secret",
58 }
59
60 if len(sys.argv) != 2 or sys.argv[1] == "-h" or sys.argv[1] == "--help":
61 print("Usage: echo message | {} user@server".format(sys.argv[0]))
62 sys.exit(1)
63
64 dest = sys.argv[1]
65 text = sys.stdin.read()
66
67 # construit un dictionnaire d'informations
68 items = [l.split(":", 1) for l in text.splitlines()]
69 data = {k.strip().lower():v.strip() for k,v in items}
70 #print("data={}".format(data))
71
72 # remanie la date (si possible)
73 if "date" in data:
74 try:
75 dt = time.strptime(data["date"], "%a %b %d %H:%M:%S %Z %Y")
76 data["date"] = time.strftime("%Y-%m-%d %H:%M:%S", dt)
77 except:
78 pass
79
80 # fonction qui renvoie la couleur prévue pour un statut donné
81 def state_color(state):
82 color = "blue"
83 if state == "OK" or state == "UP":
84 color = "green"
85 elif state == "WARNING" or state == "UNKNOWN":
86 color = "orange"
87 elif state == "CRITICAL" or state == "DOWN":
88 color = "red"
89 return color
90
91 # fonction qui renvoie un texte enrichi pour le statut
92 def state_enriched(state):
93 return "<strong>[<span style='color: {0};'>{1}</span>]</strong>"\
94 .format(state_color(state), state)
95
96 # ajout du statut enrichi
97 if "state" in data:
98 data["rich_state"] = state_enriched(data["state"])
99
100 # remaniement des infos (suppression des redondances, gestion des lignes)
101 if "info" in data:
102 if "service" in data and data["info"].startswith(data["service"]):
103 data["info"] = data["info"][len(data["service"]):].strip(" :-")
104 if "state" in data and data["info"].startswith(data["state"]):
105 data["info"] = data["info"][len(data["state"]):].strip(" :-")
106 data["info"] = data["info"].replace("\\n", "\n").strip("\n")
107 # prepare enriched info
108 data["rich_info"] = data["info"].replace("\n", "<br/>")
109 data["rich_info"] = data["rich_info"].replace("WARNING", state_enriched("WARNING"))
110 data["escaped_info"] = data["info"].replace("'", "&#39;").replace("<", "&lt;")
111
112 #print("data={}".format(data))
113
114 # construction des textes
115 if "service" in data:
116 text = "{date}\t{state}\t{service} @{host}[{address}]\n{info}".format(**data)
117 enriched_text = "<span style='color: black;'><span>{date}</span> "\
118 "<a href='void();' title='{escaped_info}'>{rich_state}</a> "\
119 "<span style='color: blue;'>{service}</span> "\
120 "@<span style='color: blue;'>{host}</span>"\
121 "[<span style='color: blue;'>{address}</span>]"\
122 "</span>".format(**data)
123 #"<br/><em>{rich_info}</em></span>".format(**data)
124 else:
125 text = "{date}\t{state}\t{host}\n{info}".format(**data)
126 enriched_text = "<span style='color: black;'><span>{date}</span> "\
127 "<a href='void();' title='{escaped_info}'>{rich_state}</a> "\
128 "<span style='color: blue;'>{host}</span>"\
129 "</span>".format(**data)
130 #"<br/><em>{rich_info}</em></span>".format(**data)
131
132 # construction du message
133 html = xmpp.Node("html", {"xmlns": "http://jabber.org/protocol/xhtml-im"})
134 html.addChild(node=xmpp.simplexml.XML2Node(
135 "<body xmlns='http://www.w3.org/1999/xhtml'>{}</body>".format(enriched_text)))
136 message = xmpp.protocol.Message(to=dest, body=text, typ="chat")
137 message.addChild(node=html)
138
139 # envoi du message
140 jid = xmpp.protocol.JID(_CONFIG["jid"])
141 client = xmpp.Client(jid.getDomain(), debug=[])
142 client.connect()
143 client.auth(jid.getNode(), _CONFIG["password"], "server")
144 client.send(message)