Code

Added host checks
authorSven Velt <sven@velt.de>
Tue, 8 Dec 2009 11:06:13 +0000 (12:06 +0100)
committerSven Velt <sven@velt.de>
Tue, 8 Dec 2009 11:06:13 +0000 (12:06 +0100)
examples/nagixsc_debian.conf
examples/nagixsc_usrlocal.conf
nagixsc.py
nagixsc_conf2xml.py
nagixsc_xml2nagios.py
xml/nagixsc.dtd
xml/nagixsc.xml
xml/nagixsc.xsd

index 1b82196b4dd03496150e45680bb1cced248c0b96..8b47fd67e60c19527e91cfa79de78c60da946dba 100644 (file)
@@ -3,7 +3,8 @@ Reserved: For future use
 
 [host1]
 _underscores_at_start: reserved
 
 [host1]
 _underscores_at_start: reserved
-_host_name: host1
+_use_section_name_as: host_name in nagios
+_host_check: /usr/lib/nagios/plugins/check_host -H 127.0.0.1
 Disk_Home: /usr/lib/nagios/plugins/check_disk -w 10% -c 5% -m -p /home
 Disk_Root: /usr/lib/nagios/plugins/check_disk -w 10% -c 5% -m -p /
 Load: /usr/lib/nagios/plugins/check_load -w 5,5,5 -c 10,10,10
 Disk_Home: /usr/lib/nagios/plugins/check_disk -w 10% -c 5% -m -p /home
 Disk_Root: /usr/lib/nagios/plugins/check_disk -w 10% -c 5% -m -p /
 Load: /usr/lib/nagios/plugins/check_load -w 5,5,5 -c 10,10,10
index 2aac151a5b72570e89c84f08e2044502feb273d1..871ef642937a6010459182aaf0e67c38919390e1 100644 (file)
@@ -3,7 +3,8 @@ Reserved: For future use
 
 [host1]
 _underscores_at_start: reserved
 
 [host1]
 _underscores_at_start: reserved
-_host_name: host1
+_use_section_name_as: host_name in nagios
+_host_check: /usr/local/nagios/libexec/check_host -H 127.0.0.1
 Disk_Home: /usr/local/nagios/libexec/check_disk -w 10% -c 5% -m -p /home
 Disk_Root: /usr/local/nagios/libexec/check_disk -w 10% -c 5% -m -p /
 Load: /usr/local/nagios/libexec/check_load -w 5,5,5 -c 10,10,10
 Disk_Home: /usr/local/nagios/libexec/check_disk -w 10% -c 5% -m -p /home
 Disk_Root: /usr/local/nagios/libexec/check_disk -w 10% -c 5% -m -p /
 Load: /usr/local/nagios/libexec/check_load -w 5,5,5 -c 10,10,10
index 4903509bff8a15528c3e3a1c0527a276c9f0695b..bf204c042c5ce0cf0e4e9082aefba679eed710df 100644 (file)
@@ -68,11 +68,34 @@ def xml_to_dict(xmldoc, verb=0, hostfilter=None, servicefilter=None):
                hostname = decode(xmlhostname.get_content(), xmlhostname.prop('encoding'))
                debug(2, verb, 'Found host "%s"' % hostname)
 
                hostname = decode(xmlhostname.get_content(), xmlhostname.prop('encoding'))
                debug(2, verb, 'Found host "%s"' % hostname)
 
+               # Look for Host check result
+               if host.xpathEval('returncode'):
+                       retcode   = host.xpathEval('returncode')[0].get_content()
+               else:
+                       retcode   = None
+
+               if host.xpathEval('output'):
+                       xmloutput = host.xpathEval('output')[0]
+                       output    = decode(xmloutput.get_content(), xmloutput.prop('encoding')).rstrip()
+               else:
+                       output    = None
+
+               if host.xpathEval('timestamp'):
+                       timestamp = int(host.xpathEval('timestamp')[0].get_content())
+               else:
+                       timestamp = filetimestamp
+
+               if retcode and output:
+                       checks.append({'host_name':hostname, 'service_description':None, 'returncode':retcode, 'output':output, 'timestamp':timestamp})
+
+
+               # Look for service filter
                if servicefilter:
                        services = host.xpathEval('service[description="%s"] | service[description="%s"]' % (servicefilter, encode(servicefilter)))
                else:
                        services = host.xpathEval('service')
 
                if servicefilter:
                        services = host.xpathEval('service[description="%s"] | service[description="%s"]' % (servicefilter, encode(servicefilter)))
                else:
                        services = host.xpathEval('service')
 
+               # Loop over services in host
                for service in services:
                        service_dict = {}
 
                for service in services:
                        service_dict = {}
 
@@ -81,7 +104,7 @@ def xml_to_dict(xmldoc, verb=0, hostfilter=None, servicefilter=None):
 
                        srvdescr = decode(xmldescr.get_content(), xmldescr.prop('encoding'))
                        retcode  = service.xpathEval('returncode')[0].get_content()
 
                        srvdescr = decode(xmldescr.get_content(), xmldescr.prop('encoding'))
                        retcode  = service.xpathEval('returncode')[0].get_content()
-                       output   = decode(xmloutput.get_content(), xmldescr.prop('encoding')).rstrip()
+                       output   = decode(xmloutput.get_content(), xmloutput.prop('encoding')).rstrip()
 
                        try:
                                timestamp = int(service.xpathEval('timestamp')[0].get_content())
 
                        try:
                                timestamp = int(service.xpathEval('timestamp')[0].get_content())
@@ -117,14 +140,23 @@ def xml_from_dict(checks, encoding='base64'):
                        xmlhostname = xmlhost.newChild(None, 'name', encode(check['host_name'], encoding))
                        lasthost = check['host_name']
 
                        xmlhostname = xmlhost.newChild(None, 'name', encode(check['host_name'], encoding))
                        lasthost = check['host_name']
 
-               xmlservice    = xmlhost.newChild(None, 'service', None)
-               xmlname       = xmlservice.newChild(None, 'description', encode(check['service_description'], encoding))
-               xmlname.setProp('encoding', encoding)
-               xmlreturncode = xmlservice.newChild(None, 'returncode', str(check['returncode']))
-               xmloutput     = xmlservice.newChild(None, 'output', encode(check['output'], encoding))
-               xmloutput.setProp('encoding', encoding)
-               if check.has_key('timestamp'):
-                       xmltimestamp  = xmlservice.newChild(None, 'timestamp', str(check['timestamp']))
+               if check['service_description'] == '' or check['service_description'] == None:
+                       # Host check result
+                       xmlreturncode = xmlhost.newChild(None, 'returncode', str(check['returncode']))
+                       xmloutput     = xmlhost.newChild(None, 'output', encode(check['output'], encoding))
+                       xmloutput.setProp('encoding', encoding)
+                       if check.has_key('timestamp'):
+                               xmltimestamp  = xmlhost.newChild(None, 'timestamp', str(check['timestamp']))
+               else:
+                       # Service check result
+                       xmlservice    = xmlhost.newChild(None, 'service', None)
+                       xmlname       = xmlservice.newChild(None, 'description', encode(check['service_description'], encoding))
+                       xmlname.setProp('encoding', encoding)
+                       xmlreturncode = xmlservice.newChild(None, 'returncode', str(check['returncode']))
+                       xmloutput     = xmlservice.newChild(None, 'output', encode(check['output'], encoding))
+                       xmloutput.setProp('encoding', encoding)
+                       if check.has_key('timestamp'):
+                               xmltimestamp  = xmlservice.newChild(None, 'timestamp', str(check['timestamp']))
 
        return xmldoc
 
 
        return xmldoc
 
index c58ad1e6e135960486ab180858f293ca082a2646..149bdd135827cfb96827d613179a9a0b0025fe87 100755 (executable)
@@ -37,6 +37,19 @@ if options.encoding not in available_encodings():
 
 ##############################################################################
 
 
 ##############################################################################
 
+def exec_check(host_name, service_descr, cmdline):
+       try:
+               cmd     = subprocess.Popen(cmdline.split(' '), stdout=subprocess.PIPE)
+               output  = cmd.communicate()[0].rstrip()
+               retcode = cmd.returncode
+       except OSError:
+               output  = 'Could not execute "%s"' % cmdline
+               retcode = 127
+
+       return {'host_name':host_name, 'service_description':service_descr, 'returncode':retcode, 'output':output, 'timestamp':datetime.datetime.now().strftime('%s')}
+
+##############################################################################
+
 config = ConfigParser.RawConfigParser()
 config.optionxform = str # We need case-sensitive options
 conf_list = config.read(options.conffile)
 config = ConfigParser.RawConfigParser()
 config.optionxform = str # We need case-sensitive options
 conf_list = config.read(options.conffile)
@@ -51,21 +64,27 @@ if 'nagixsc' in hosts:
        hosts.remove('nagixsc')
 
 for host in hosts:
        hosts.remove('nagixsc')
 
 for host in hosts:
+       # Overwrite section/host name with '_host_name'
        if config.has_option(host,'_host_name'):
                host_name = config.get(host,'_host_name')
        else:
                host_name = host
 
        if config.has_option(host,'_host_name'):
                host_name = config.get(host,'_host_name')
        else:
                host_name = host
 
+
+       # Look for host check
+       if config.has_option(host,'_host_check'):
+               cmdline = config.get(host, '_host_check')
+               check = exec_check(host_name, None, cmdline)
+               checks.append(check)
+
+
        for service in config.options(host):
                # If option starts with '_' it may be a NagixSC option in the future
                if service[0] != '_':
                        cmdline = config.get(host, service)
 
        for service in config.options(host):
                # If option starts with '_' it may be a NagixSC option in the future
                if service[0] != '_':
                        cmdline = config.get(host, service)
 
-                       cmd = subprocess.Popen(cmdline.split(' '), stdout=subprocess.PIPE)
-                       output = cmd.communicate()[0].rstrip()
-                       retcode = cmd.returncode
-
-                       checks.append({'host_name':host_name, 'service_description':service, 'returncode':retcode, 'output':output, 'timestamp':datetime.datetime.now().strftime('%s')})
+                       check = exec_check(host_name, service, cmdline)
+                       checks.append(check)
 
 
 xmldoc = xml_from_dict(checks, options.encoding)
 
 
 xmldoc = xml_from_dict(checks, options.encoding)
index 4296ee5d099a473b5c9f5e5f8b0e0596c70ee96e..9b0a394d56b3c094f63b7427888b83a78225d1ca 100755 (executable)
@@ -143,6 +143,7 @@ for check in checks:
 # Next steps depend on mode, output results
 # MODE: passive
 if options.mode == 'passive' or options.mode == 'passive_check':
 # 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")
        # Prepare
        if options.verb <= 2:
                pipe = open(options.pipe, "w")
@@ -151,7 +152,13 @@ if options.mode == 'passive' or options.mode == 'passive_check':
 
        # Output
        for check in checks:
 
        # Output
        for check in checks:
-               line = '[%s] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%s;%s' % (now, check['host_name'], check['service_description'], check['returncode'], check['output'].replace('\n', '\\n'))
+               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')
 
                if pipe:
                        pipe.write(line + '\n')
@@ -173,11 +180,11 @@ if options.mode == 'passive' or options.mode == 'passive_check':
                if options.markold:
                        if (now - filetimestamp) > options.seconds:
                                returnstring = 'WARNING'
                if options.markold:
                        if (now - filetimestamp) > options.seconds:
                                returnstring = 'WARNING'
-                               output = 'Check results are %s(>%s) seconds old' % ((now-filetimestamp), options.seconds)
+                               output = '%s check results written, which are %s(>%s) seconds old' % (count_services, (now-filetimestamp), options.seconds)
                                returncode = 1
 
                if not output:
                                returncode = 1
 
                if not output:
-                       output = 'Check results are %s seconds old' % (now-filetimestamp)
+                       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)
 
                print 'Nag(ix)SC %s - %s' % (returnstring, output)
                sys.exit(returncode)
@@ -199,7 +206,12 @@ elif options.mode == 'checkresult' or options.mode == 'checkresult_check':
                filename = os.path.join(options.checkresultdir, 'c' + ''.join([random.choice(chars) for i in range(6)]))
                try:
                        crfile = open(filename, "w")
                filename = os.path.join(options.checkresultdir, 'c' + ''.join([random.choice(chars) for i in range(6)]))
                try:
                        crfile = open(filename, "w")
-                       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') ) )
+                       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
                        crfile.close()
 
                        # Create OK file
index 171df1611339b08c334be2830e394748338431d3..fa6e453bc3eeb705e44d5b3e08e278955c276c1a 100644 (file)
@@ -3,7 +3,7 @@
 
 <!ELEMENT timestamp (#PCDATA)>
 
 
 <!ELEMENT timestamp (#PCDATA)>
 
-<!ELEMENT host (name,service+)>
+<!ELEMENT host (name,returncode?,output?,service+)>
 <!ATTLIST host encoding CDATA #IMPLIED >
 
 <!ELEMENT name (#PCDATA)>
 <!ATTLIST host encoding CDATA #IMPLIED >
 
 <!ELEMENT name (#PCDATA)>
index 5444ae9feee083cd568c138bd65f0aa147bbbedb..d83074eadcbccb470e4eb6c63445933d45f07bc1 100644 (file)
@@ -5,6 +5,8 @@
 
        <host>
                <name encoding="plain">host1</name>
 
        <host>
                <name encoding="plain">host1</name>
+               <returncode>0</returncode>
+               <output>T0sgLSAxMjcuMC4wLjE6IHJ0YSAwLjA4NG1zLCBsb3N0IDAlfHJ0YT0wLjA4NG1zOzIwMC4wMDA7NTAwLjAwMDswOyBwbD0wJTs0MDs4MDs7Cg==</output>
 
                <service>
                        <description encoding="base64">RGlza19Ib21l</description>
 
                <service>
                        <description encoding="base64">RGlza19Ib21l</description>
index 5c82b91c6bf00e5ebe9d76a190e5ea6b2266d8e3..6be18a3138479a7a4916cd5df189a255549776eb 100644 (file)
@@ -7,6 +7,10 @@
                                <xsd:element name="host" type="xsd:string" minOccurs="1" maxOccurs="unbounded">
                                        <xsd:sequence>
 
                                <xsd:element name="host" type="xsd:string" minOccurs="1" maxOccurs="unbounded">
                                        <xsd:sequence>
 
+                                               <xsd:element name="name" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                                               <xsd:element name="returncode" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                                               <xsd:element name="output" type="xsd:int" minOccurs="0" maxOccurs="1" />
+
                                                <xsd:element name="service" type="xsd:string" minOccurs="1" maxOccurs="unbounded">
                                                        <xsd:sequence>
                                                                <xsd:element name="description" type="xsd:string" minOccurs="1" maxOccurs="1" />
                                                <xsd:element name="service" type="xsd:string" minOccurs="1" maxOccurs="unbounded">
                                                        <xsd:sequence>
                                                                <xsd:element name="description" type="xsd:string" minOccurs="1" maxOccurs="1" />