Code

Changed license to GPL-2+ (from GPL-2only).
[nagixsc.git] / nagixsc_xml2nagios.py
index 868bca5e49630ff662d187d5ee04a4b1845330c7..fae228ee3acd3fe4abced8b0a472fe281eb3d1ed 100755 (executable)
@@ -1,13 +1,29 @@
 #!/usr/bin/python
+#
+# Nag(ix)SC -- nagixsc_xml2nagios.py
+#
+# Copyright (C) 2009-2010 Sven Velt <sv@teamix.net>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 
 #import base64
-import datetime
 import libxml2
 import optparse
 import os
-import random
-import string
 import sys
+import time
 
 NAGIOSCMDs = [ '/usr/local/nagios/var/rw/nagios.cmd', '/var/lib/nagios3/rw/nagios.cmd', ]
 CHECKRESULTDIRs = [ '/usr/local/nagios/var/spool/checkresults', '/var/lib/nagios3/spool/checkresults', ]
@@ -52,7 +68,7 @@ from nagixsc import *
 ##############################################################################
 
 if options.mode not in MODEs:
-       print 'Not an allowed mode "%s" - allowed are: %s' % (options.mode, ", ".join(MODEs))
+       print 'Not an allowed mode "%s" - allowed are: "%s"' % (options.mode, '", "'.join(MODEs))
        sys.exit(127)
 
 # Check command line options wrt mode
@@ -85,18 +101,18 @@ elif options.mode == 'checkresult' or options.mode == 'checkresult_check':
 elif options.mode == 'active':
        debug(1, options.verb, 'Running in active/plugin mode')
        if options.host == None:
-               debug(1, options.verb, 'No host specified, using first host in XML file')
+               debug(1, options.verb, 'No host specified on command line')
        if options.service == None:
-               print 'No service specified on command line!'
-               sys.exit(127)
+               debug(1, options.verb, 'No service specified on command line, looking at XML file later')
 
 ##############################################################################
 
-now = int(datetime.datetime.now().strftime('%s'))
-
 # Get URL or file
 doc = read_xml(options)
 
+# Now timestamp AFTER getting the XML file
+now = long(time.time())
+
 
 # Check XML against DTD
 if options.schemacheck:
@@ -140,39 +156,13 @@ for check in checks:
 # Next steps depend on mode, output results
 # MODE: passive
 if options.mode == 'passive' or options.mode == 'passive_check':
-       count_services = 0
-       # Prepare
-       if options.verb <= 2:
-               pipe = open(options.pipe, "w")
-       else:
-               pipe = None
-
-       # Output
-       for check in checks:
-               count_services += 1
-               if check['service_description'] == None or check['service_description'] == '':
-                       # Host check
-                       line = '[%s] PROCESS_HOST_CHECK_RESULT;%s;%s;%s' % (now, check['host_name'], check['returncode'], check['output'].replace('\n', '\\n'))
-               else:
-                       # Service check
-                       line = '[%s] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%s;%s' % (now, check['host_name'], check['service_description'], check['returncode'], check['output'].replace('\n', '\\n'))
-
-               if pipe:
-                       pipe.write(line + '\n')
-               debug(2, options.verb, '%s / %s: %s - "%s"' % (check['host_name'], check['service_description'], check['returncode'], check['output'].replace('\n', '\\n')))
-               debug(3, options.verb, line)
-
-       # Close
-       if pipe:
-               pipe.close()
-       else:
-               print "Passive check results NOT written to Nagios pipe due to -vvv!"
+       count_services = dict2out_passive(checks, xml_get_timestamp(doc), options.pipe, options.verb)
 
        # Return/Exit as a Nagios Plugin if called with mode 'passive_check'
        if options.mode == 'passive_check':
                returncode   = 0
                returnstring = 'OK'
-               output       = ''
+               output       = '%s check results written which are %s seconds old' % (count_services, (now-filetimestamp))
 
                if options.markold:
                        if (now - filetimestamp) > options.seconds:
@@ -180,45 +170,24 @@ if options.mode == 'passive' or options.mode == 'passive_check':
                                output = '%s check results written, which are %s(>%s) seconds old' % (count_services, (now-filetimestamp), options.seconds)
                                returncode = 1
 
-               if not output:
-                       output = '%s check results written which are %s seconds old' % (count_services, (now-filetimestamp))
-
                print 'Nag(ix)SC %s - %s' % (returnstring, output)
                sys.exit(returncode)
 
-# MODE: checkresult
-elif options.mode == 'checkresult' or options.mode == 'checkresult_check':
-       count_services = 0
-       count_failed   = 0
+# MODE: checkresult: "checkresult", "checkresult_check"
+elif options.mode.startswith('checkresult'):
+       (count_services, count_failed, list_failed) = dict2out_checkresult(checks, xml_get_timestamp(doc), options.checkresultdir, options.verb)
 
-       chars = string.letters + string.digits
+       if options.mode == 'checkresult':
+               if list_failed:
+                       for entry in list_failed:
+                               print 'Could not write checkresult files "%s(.ok)" for "%s"/"%s"!' % (entry[0], entry[1], entry[2])
 
-       for check in checks:
-               count_services += 1
-               if check.has_key('timestamp'):
-                       timestamp = check['timestamp']
+               if count_failed == 0:
+                       sys.exit(0)
                else:
-                       timestamp = xml_get_timestamp(xmldoc)
-
-               filename = os.path.join(options.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, datetime.datetime.now().ctime(), 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, datetime.datetime.now().ctime(), 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
-                       if options.mode == 'checkresult':
-                               print 'Could not write checkresult files "%s(.ok)" for "%s"/"%s"!' % (filename, check['host_name'], check['service_description'])
-
-       if options.mode == 'checkresult_check':
+                       sys.exit(1)
+
+       elif options.mode == 'checkresult_check':
                returnstring = ''
                output       = ''
                if count_failed == 0:
@@ -237,19 +206,20 @@ elif options.mode == 'checkresult' or options.mode == 'checkresult_check':
                print 'Nag(ix)SC %s - %s' % (returnstring, output)
                sys.exit(returncode)
 
-       if count_failed == 0:
-               sys.exit(0)
-       else:
-               sys.exit(1)
-
 # MODE: active
 elif options.mode == 'active':
 
        if len(checks) > 1:
                print 'Nag(ix)SC UNKNOWN - Found more (%s) than one host/service!' % len(checks)
+               print 'Found: ' + ', '.join(['%s/%s' % (c['host_name'], c['service_description']) for c in checks])
                sys.exit(3)
        elif len(checks) == 0:
-               print 'Nag(ix)SC UNKNOWN - No check for "%s"/"%s" found in XML' % (options.host, options.service)
+               output = 'Nag(ix)SC UNKNOWN - No check found in XML'
+               if options.host:
+                       output += ' - Host filter: "%s"' % options.host
+               if options.service:
+                       output += ' - Service filter: "%s"' % options.service
+               print output
                sys.exit(3)
 
        print checks[0]['output']