Commit | Line | Data |
---|---|---|
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 : | |
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("'", "'").replace("<", "<") | |
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) |