]> git.pld-linux.org Git - packages/nagios-alert-jabber.git/blob - nagios-jabber.alert
- rel 9; actually use -c path
[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 == '-c':
43                 cfg = a
44         if o == '-d':
45                 debug = True
46         if o == '-t':
47                 timeout = float(a)
48         if o == '-x':
49                 html = True
50         if o == '-J':
51                 tjid = a
52         if o == '-P':
53                 jids.append({ 'jid': tjid, 'password': a })
54         if o == '-a':
55                 import ConfigParser
56
57                 config = ConfigParser.ConfigParser()
58                 config.read(cfg)
59
60                 for section in a.split(','):
61                         jids.append({ 'jid': config.get(section, 'jid'), 'password': config.get(section, 'password')})
62
63 socket.setdefaulttimeout(timeout)
64
65 recpt = args
66
67 for section in jids:
68         if not section['jid'] or not section['password']:
69                 print >> sys.stderr, "%s: jid (-J) and password (-P) are required for `%s'" % (sys.argv[0], section)
70                 sys.exit(1)
71
72 if not jids:
73         print >> sys.stderr, "%s: no configured jid accounts found" % sys.argv[0]
74         sys.exit(1)
75
76 if not recpt:
77         print >> sys.stderr, "%s: recipient jids are required" % sys.argv[0]
78         sys.exit(1)
79
80 if debug:
81         logger=logging.getLogger()
82         logger.addHandler(logging.StreamHandler())
83         logger.setLevel(logging.DEBUG)
84
85 subject = "Nagios alert"
86
87 body = ""
88 stdin_body = ""
89 do_print = True
90 for line in sys.stdin.readlines():
91         stdin_body += line
92
93 body += stdin_body
94
95 if len(body.strip()) == 0:
96         body = "(nagios-jabber.alert warning: missing message body)";
97
98 message_type = 'chat'
99
100 class XMPPStreamError(Exception):
101         def __init__(self, msg):
102                 self.msg = msg
103         def __str__(self):
104                 return self.msg
105
106 class Client(JabberClient):
107         def session_started(self):
108                 if (html == True):
109                         import re
110                         message = re.sub('<.*?>', '', body)
111                         doc = libxml2.parseDoc('<body>' + body + '</body>')
112                         doc_element = doc.getRootElement().children
113                 else:
114                         message = body
115
116                 for r in recpt:
117                         jid_r = JID(r)
118                         msg = Message(to_jid = jid_r, body = message, subject = subject,
119                                         stanza_type = message_type, thread = "Nagios")
120
121                         if (html == True):
122                                 node = msg.add_new_content('http://jabber.org/protocol/xhtml-im', 'html')
123                                 xbody = node.newChild(None, "body", None)
124                                 html_ns = xbody.newNs('http://www.w3.org/1999/xhtml', None)
125                                 xbody.setNs(html_ns)
126                                 xbody.addChildList(doc_element.docCopyNodeList(xbody.doc))
127
128                         self.stream.send(msg)
129                 self.disconnect()
130
131         def stream_state_changed(self,state,arg):
132                 if debug:
133                         print "*** State changed: %s %r ***" % (state,arg)
134
135         def stream_error(self,err):
136                 raise XMPPStreamError(err.get_message())
137
138
139 err = []
140 for section in jids:
141         for attempt in ('first', 'second'):
142                 jid = JID(section['jid'])
143                 resource = "Nagios/" + hashlib.md5(''.join(recpt)).hexdigest()[:10]
144                 if attempt == 'second':
145                         # if something went wrong the second time around, it's
146                         # most likely a resource name conflict on login, so let's
147                         # wait a bit, randomize the resource name and try again
148                         resource = resource + '/' + repr(os.getpid())
149                         time.sleep(0.8)
150                 if not jid.resource:
151                         jid = JID(jid.node, jid.domain, resource)
152
153                 c = Client(jid, section['password'], auth_methods = ['sasl:DIGEST-MD5', 'sasl:PLAIN', 'digest'],
154                                 tls_settings = TLSSettings(require = False, verify_peer = False))
155                 try:
156                         c.connect()
157                         try:
158                                 c.loop(1)
159                         except XMPPStreamError, e:
160                                 # Most likely a duplicate stream problem
161                                 # don't log anything, just try again
162                                 c.disconnect()
163                                 continue
164                         except Exception, e:
165                                 err.append("ERROR1: %s: %s" % (section['jid'], e))
166                                 c.disconnect()
167                                 # don't try another attempt, jump straigt to
168                                 # another section
169                                 break
170                         c.disconnect()
171                         # stop after first successful attempt at sending the msg
172                         sys.exit(0)
173                 except Exception, e:
174                         err.append("ERROR2: %s: %s" % (section['jid'], e))
175
176 print >> sys.stderr, "\n".join(err)
177 sys.exit(1)
This page took 0.051564 seconds and 3 git commands to generate.