]> git.pld-linux.org Git - packages/nagios-alert-jabber.git/blob - nagios-jabber.alert
0b8c33913e41ff188cf486c013bdb7e514986f05
[packages/nagios-alert-jabber.git] / nagios-jabber.alert
1 #!/usr/bin/python -u
2 # arekm@pld-linux.org, 2006-01
3 # glen@pld-linux.org, 2006-03-14
4 # glen@pld-linux.org,arekm@pld-linux.org, 2006-10-30 - added ssl support (for gmail.com)
5 # glen@pld-linux.org 2006-11-03 - made it work with jabber.pld-linux.org again
6 # glen@pld-linux.org,arekm@pld-linux.org, 2006-11-13 - added config file support
7 # glen@pld-linux.org, 2006-12-07 - added html messages support (-x), thx goes to to jajcus
8 # luzik@pld-linux.org, 2007-03 - added digest auth method(jabber.gda.pl)
9 # arekm@pld-linux.org, 2009-07 - added fallback accounts support
10 # usage:
11 #   jabber.alert [-x] [-c config] [-a account_id][,otheraccount_id] [-t timeout ] [-J from_jid -P password] to_jid1 to_jid2 to_jid3
12
13 import os
14 import hashlib
15 import re
16 import sys
17 import getopt
18 import logging
19 import socket
20 import string
21 import time
22 import libxml2
23
24 from pyxmpp.jid import JID
25 from pyxmpp.message import Message
26 from pyxmpp.jabber.client import JabberClient
27 from pyxmpp.streamtls import TLSSettings
28
29 try:
30         opts, args = getopt.getopt(sys.argv[1:], "J:P:a:c:dt:x")
31 except getopt.GetoptError, e:
32         print >> sys.stderr, "%s: %s " % (sys.argv[0], e)
33         sys.exit(1)
34
35 jids = []
36 html = False
37 debug = False
38 timeout = 20
39 cfg = "/etc/nagios/jabber-notify.ini"
40 tjid = None
41 for o, a in opts:
42         if o == '-d':
43                 debug = True
44         if o == '-t':
45                 timeout = float(a)
46         if o == '-x':
47                 html = True
48         if o == '-J':
49                 tjid = a
50         if o == '-P':
51                 jids.append({ 'jid': tjid, 'password': a })
52         if o == '-a':
53                 import ConfigParser
54
55                 config = ConfigParser.ConfigParser()
56                 config.read(cfg)
57
58                 for section in a.split(','):
59                         jids.append({ 'jid': config.get(section, 'jid'), 'password': config.get(section, 'password')})
60
61 socket.setdefaulttimeout(timeout)
62
63 recpt = args
64
65 for section in jids:
66         if not section['jid'] or not section['password']:
67                 print >> sys.stderr, "%s: jid (-J) and password (-P) are required for `%s'" % (sys.argv[0], section)
68                 sys.exit(1)
69
70 if not jids:
71         print >> sys.stderr, "%s: no configured jid accounts found" % sys.argv[0]
72         sys.exit(1)
73
74 if not recpt:
75         print >> sys.stderr, "%s: recipient jids are required" % sys.argv[0]
76         sys.exit(1)
77
78 if debug:
79         logger=logging.getLogger()
80         logger.addHandler(logging.StreamHandler())
81         logger.setLevel(logging.DEBUG)
82
83 subject = "Nagios alert"
84
85 body = ""
86 stdin_body = ""
87 do_print = True
88 for line in sys.stdin.readlines():
89         stdin_body += line
90
91 body += stdin_body
92
93 if len(body.strip()) == 0:
94         body = "(nagios-jabber.alert warning: missing message body)";
95
96 message_type = 'chat'
97
98 class XMPPStreamError(Exception):
99         def __init__(self, msg):
100                 self.msg = msg
101         def __str__(self):
102                 return self.msg
103
104 class Client(JabberClient):
105         def session_started(self):
106                 if (html == True):
107                         import re
108                         message = re.sub('<.*?>', '', body)
109                         doc = libxml2.parseDoc('<body>' + body + '</body>')
110                         doc_element = doc.getRootElement().children
111                 else:
112                         message = body
113
114                 for r in recpt:
115                         jid_r = JID(r)
116                         msg = Message(to_jid = jid_r, body = message, subject = subject,
117                                         stanza_type = message_type, thread = "Nagios")
118
119                         if (html == True):
120                                 node = msg.add_new_content('http://jabber.org/protocol/xhtml-im', 'html')
121                                 xbody = node.newChild(None, "body", None)
122                                 html_ns = xbody.newNs('http://www.w3.org/1999/xhtml', None)
123                                 xbody.setNs(html_ns)
124                                 xbody.addChildList(doc_element.docCopyNodeList(xbody.doc))
125
126                         self.stream.send(msg)
127                 self.disconnect()
128
129         def stream_state_changed(self,state,arg):
130                 if debug:
131                         print "*** State changed: %s %r ***" % (state,arg)
132
133         def stream_error(self,err):
134                 raise XMPPStreamError(err.get_message())
135
136
137 err = []
138 for section in jids:
139         for attempt in ('first', 'second'):
140                 jid = JID(section['jid'])
141                 resource = "Nagios/" + hashlib.md5(''.join(recpt)).hexdigest()[:10]
142                 if attempt == 'second':
143                         # if something went wrong the second time around, it's
144                         # most likely a resource name conflict on login, so let's
145                         # wait a bit, randomize the resource name and try again
146                         resource = resource + '/' + repr(os.getpid())
147                         time.sleep(0.8)
148                 if not jid.resource:
149                         jid = JID(jid.node, jid.domain, resource)
150
151                 c = Client(jid, section['password'], auth_methods = ['sasl:DIGEST-MD5', 'sasl:PLAIN', 'digest'],
152                                 tls_settings = TLSSettings(require = False, verify_peer = False))
153                 try:
154                         c.connect()
155                         try:
156                                 c.loop(1)
157                         except XMPPStreamError, e:
158                                 # Most likely a duplicate stream problem
159                                 # don't log anything, just try again
160                                 c.disconnect()
161                                 continue
162                         except Exception, e:
163                                 err.append("ERROR1: %s: %s" % (section['jid'], e))
164                                 c.disconnect()
165                                 # don't try another attempt, jump straigt to
166                                 # another section
167                                 break
168                         c.disconnect()
169                         # stop after first successful attempt at sending the msg
170                         sys.exit(0)
171                 except Exception, e:
172                         err.append("ERROR2: %s: %s" % (section['jid'], e))
173
174 print >> sys.stderr, "\n".join(err)
175 sys.exit(1)
This page took 0.07696 seconds and 2 git commands to generate.