#!/usr/bin/python -u
# arekm@pld-linux.org, 2006-01
# glen@pld-linux.org, 2006-03-14
# glen@pld-linux.org,arekm@pld-linux.org, 2006-10-30 - added ssl support (for gmail.com)
# glen@pld-linux.org 2006-11-03 - made it work with jabber.pld-linux.org again
# glen@pld-linux.org,arekm@pld-linux.org, 2006-11-13 - added config file support
# glen@pld-linux.org, 2006-12-07 - added html messages support (-x), thx goes to to jajcus
# luzik@pld-linux.org, 2007-03 - added digest auth method(jabber.gda.pl)
# arekm@pld-linux.org, 2009-07 - added fallback accounts support
# usage:
#   jabber.alert [-x] [-a account_id][,otheraccount_id] [-t timeout ] [-J from_jid -P password] to_jid1 to_jid2 to_jid3

import os
import re
import sys
import getopt
import logging
import socket
import string
import time
import libxml2

from pyxmpp.jid import JID
from pyxmpp.message import Message
from pyxmpp.jabber.client import JabberClient
from pyxmpp.streamtls import TLSSettings

try:
	opts, args = getopt.getopt(sys.argv[1:], "J:P:a:dt:x")
except getopt.GetoptError, e:
	print >> sys.stderr, "%s: %s " % (sys.argv[0], e)
	sys.exit(1)

jids = []
html = False
debug = False
timeout = 20

tjid = None
for o, a in opts:
	if o == '-d':
		debug = True
	if o == '-t':
		timeout = float(a)
	if o == '-x':
		html = True
	if o == '-J':
		tjid = a
	if o == '-P':
		jids.append({ 'jid': tjid, 'password': a })
	if o == '-a':
		import ConfigParser

		config = ConfigParser.ConfigParser()
		config.read('/etc/nagios/jabber-notify.ini')

		for section in a.split(','):
			jids.append({ 'jid': config.get(section, 'jid'), 'password': config.get(section, 'password')})

socket.setdefaulttimeout(timeout)

recpt = args

for section in jids:
	if not section['jid'] or not section['password']:
		print >> sys.stderr, "%s: jid (-J) and password (-P) are required for `%s'" % (sys.argv[0], section)
		sys.exit(1)

if not jids:
	print >> sys.stderr, "%s: no configured jid accounts found" % sys.argv[0]
	sys.exit(1)

if not recpt:
	print >> sys.stderr, "%s: recipient jids are required" % sys.argv[0]
	sys.exit(1)

if debug:
	logger=logging.getLogger()
	logger.addHandler(logging.StreamHandler())
	logger.setLevel(logging.DEBUG)

subject = "Nagios alert"

body = ""
stdin_body = ""
do_print = True
for line in sys.stdin.readlines():
	stdin_body += line

body += stdin_body

if len(body.strip()) == 0:
	body = "(nagios-jabber.alert warning: missing message body)";

message_type = 'chat'

class Client(JabberClient):
	def session_started(self):
		if (html == True):
			import re
			message = re.sub('<.*?>', '', body)
			doc = libxml2.parseDoc('<body>' + body + '</body>')
			doc_element = doc.getRootElement().children
		else:
			message = body

		for r in recpt:

			jid_r = JID(r)
			msg = Message(to_jid = jid_r, body = message, subject = subject, stanza_type = message_type)

			if (html == True):
				node = msg.add_new_content('http://jabber.org/protocol/xhtml-im', 'html')
				xbody = node.newChild(None, "body", None)
				html_ns = xbody.newNs('http://www.w3.org/1999/xhtml', None)
				xbody.setNs(html_ns)
				xbody.addChildList(doc_element.docCopyNodeList(xbody.doc))

			self.stream.send(msg)
		self.disconnect()

	def stream_state_changed(self,state,arg):
		if debug:
			print "*** State changed: %s %r ***" % (state,arg)

err = []
for section in jids:
	jid = JID(section['jid'])
	if not jid.resource:
		jid = JID(jid.node, jid.domain, "Nagios")

	c = Client(jid, section['password'], auth_methods = ['sasl:DIGEST-MD5', 'sasl:PLAIN', 'digest'],
			tls_settings = TLSSettings(require = False, verify_peer = False))
	try:
		c.connect()
		try:
			c.loop(1)
		except Exception, e:
			err.append("ERROR1: %s: %s" % (section['jid'], e))
			c.disconnect()
			continue
		c.disconnect()
		# stop after first succeeded attempt
		sys.exit(0)
	except Exception, e:
		err.append("ERROR2: %s: %s" % (section['jid'], e))

print >> sys.stderr, "\n".join(err)
sys.exit(1)
