Code

Rework http2nagios (and xml2nagios) and add SSL
[nagixsc.git] / nagixsc.py
index be3613d8d57ead1a9907bd52ed4bcb17516d8907..191d26e2f0a1e90b9f6197f450a8c2f53cc61ac4 100644 (file)
@@ -1,8 +1,14 @@
+import BaseHTTPServer
 import ConfigParser
+import SocketServer
 import base64
 import datetime
 import libxml2
+import os
+import random
 import shlex
+import socket
+import string
 import subprocess
 import sys
 
@@ -116,6 +122,83 @@ def conf2dict(config, opt_host=None, opt_service=None):
        return checks
 
 
+##############################################################################
+
+def dict2out_passive(checks, xmltimestamp, opt_pipe, opt_verb=0):
+       FORMAT_HOST = '[%s] PROCESS_HOST_CHECK_RESULT;%s;%s;%s'
+       FORMAT_SERVICE = '[%s] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%s;%s'
+       count_services = 0
+       now = datetime.datetime.now().strftime('%s')
+
+       # Prepare
+       if opt_verb <= 2:
+               pipe = open(opt_pipe, "w")
+       else:
+               pipe = None
+
+       # Output
+       for check in checks:
+               count_services += 1
+               if check.has_key('timestamp'):
+                       timestamp = check['timestamp']
+               else:
+                       timestamp = xmltimestamp
+               count_services += 1
+
+               if check['service_description'] == None or check['service_description'] == '':
+                       # Host check
+                       line = FORMAT_HOST % (now, check['host_name'], check['returncode'], check['output'].replace('\n', '\\n'))
+               else:
+                       # Service check
+                       line =  FORMAT_SERVICE % (now, check['host_name'], check['service_description'], check['returncode'], check['output'].replace('\n', '\\n'))
+
+               if pipe:
+                       pipe.write(line + '\n')
+               debug(2, opt_verb, line)
+
+       # Close
+       if pipe:
+               pipe.close()
+       else:
+               print "Passive check results NOT written to Nagios pipe due to -vvv!"
+
+       return count_services
+
+
+def dict2out_checkresult(checks, xmltimestamp, opt_checkresultdir, opt_verb):
+       count_services = 0
+       count_failed = 0
+       list_failed = []
+       chars = string.letters + string.digits
+       ctimestamp = datetime.datetime.now().ctime()
+
+       for check in checks:
+               count_services += 1
+               if check.has_key('timestamp'):
+                       timestamp = check['timestamp']
+               else:
+                       timestamp = xmltimestamp
+
+               filename = os.path.join(opt_checkresultdir, 'c' + ''.join([random.choice(chars) for i in range(6)]))
+               try:
+                       crfile = open(filename, "w")
+                       if check['service_description'] == None or check['service_description'] == '':
+                               # Host check
+                               crfile.write('### Active Check Result File ###\nfile_time=%s\n\n### Nagios Service Check Result ###\n# Time: %s\nhost_name=%s\ncheck_type=0\ncheck_options=0\nscheduled_check=1\nreschedule_check=1\nlatency=0.0\nstart_time=%s.00\nfinish_time=%s.05\nearly_timeout=0\nexited_ok=1\nreturn_code=%s\noutput=%s\n' % (timestamp, ctimestamp, check['host_name'], timestamp, timestamp, check['returncode'], check['output'].replace('\n', '\\n') ) )
+                       else:
+                               # Service check
+                               crfile.write('### Active Check Result File ###\nfile_time=%s\n\n### Nagios Service Check Result ###\n# Time: %s\nhost_name=%s\nservice_description=%s\ncheck_type=0\ncheck_options=0\nscheduled_check=1\nreschedule_check=1\nlatency=0.0\nstart_time=%s.00\nfinish_time=%s.05\nearly_timeout=0\nexited_ok=1\nreturn_code=%s\noutput=%s\n' % (timestamp, ctimestamp, check['host_name'], check['service_description'], timestamp, timestamp, check['returncode'], check['output'].replace('\n', '\\n') ) )
+                       crfile.close()
+
+                       # Create OK file
+                       open(filename + '.ok', 'w').close()
+               except:
+                       count_failed += 1
+                       list_failed.append([filename, check['host_name'], check['service_description']])
+
+       return (count_services, count_failed, list_failed)
+
+
 ##############################################################################
 
 def read_xml(options):
@@ -147,6 +230,10 @@ def read_xml(options):
        return doc
 
 
+def read_xml_from_string(content):
+       return libxml2.parseDoc(content)
+
+
 ##############################################################################
 
 def xml_check_version(xmldoc):
@@ -297,3 +384,36 @@ def reset_future_timestamp(timestamp, now):
        else:
                return now
 
+##############################################################################
+
+class MyHTTPServer(BaseHTTPServer.HTTPServer):
+       def __init__(self, server_address, HandlerClass, ssl=False, sslpemfile=None):
+               if ssl:
+                       # FIXME: SSL is in Py2.6
+                       try:
+                               from OpenSSL import SSL
+                       except:
+                               print 'No Python OpenSSL wrapper/bindings found!'
+                               sys.exit(127)
+
+                       SocketServer.BaseServer.__init__(self, server_address, HandlerClass)
+                       context = SSL.Context(SSL.SSLv23_METHOD)
+                       context.use_privatekey_file (sslpemfile)
+                       context.use_certificate_file(sslpemfile)
+                       self.socket = SSL.Connection(context, socket.socket(self.address_family, self.socket_type))
+               else:
+                       SocketServer.BaseServer.__init__(self, server_address, HandlerClass)
+                       self.socket = socket.socket(self.address_family, self.socket_type)
+
+               self.server_bind()
+               self.server_activate()
+
+
+class MyHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+       def setup(self):
+               self.connection = self.request
+               self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
+               self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
+
+##############################################################################
+