X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=nagixsc_http2nagios.py;h=4d9d38fb42ed9c5c08d0ba1fe2ba0b7cb02afa34;hb=5be657722f4ed535678495579783945158d0a135;hp=085609d8d7fb8e12d9e83ac9c23d6fa83ff0af84;hpb=2a177a41949d7d59cf05242a78453e16850506e4;p=nagixsc.git diff --git a/nagixsc_http2nagios.py b/nagixsc_http2nagios.py index 085609d..4d9d38f 100755 --- a/nagixsc_http2nagios.py +++ b/nagixsc_http2nagios.py @@ -1,13 +1,28 @@ #!/usr/bin/python +# +# Nag(ix)SC -- nagixsc_http2nagios.py +# +# Copyright (C) 2009-2010 Sven Velt +# +# 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; only version 2 of the License is applicable. +# +# 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 BaseHTTPServer import ConfigParser import base64 import cgi import optparse import os import re -import subprocess import sys try: @@ -17,9 +32,15 @@ except ImportError: ############################################################################## +from nagixsc import * + +############################################################################## + parser = optparse.OptionParser() parser.add_option('-c', '', dest='cfgfile', help='Config file') +parser.add_option('-d', '--daemon', action='store_true', dest='daemon', help='Daemonize, go to background') +parser.add_option('', '--nossl', action='store_true', dest='nossl', help='Disable SSL (overwrites config file)') parser.set_defaults(cfgfile='http2nagios.cfg') @@ -33,17 +54,89 @@ if cfg_list == []: print 'Config file "%s" could not be read!' % options.cfgfile sys.exit(1) -config = {} +config = { + 'ip': '0.0.0.0', + 'port': '15667', + 'ssl': False, + 'sslcert': None, + 'conf_dir': '', + 'pidfile': '/var/run/nagixsc_conf2http.pid', + 'acl': False, + } + +if 'ip' in cfgread.options('server'): + config['ip'] = cfgread.get('server', 'ip') + +if 'port' in cfgread.options('server'): + config['port'] = cfgread.get('server', 'port') try: - config['ip'] = cfgread.get('server', 'ip') - config['port'] = cfgread.getint('server', 'port') + config['port'] = int(config['port']) +except ValueError: + print 'Port "%s" not an integer!' % config['port'] + sys.exit(127) + +if 'ssl' in cfgread.options('server'): + try: + config['ssl'] = cfgread.getboolean('server', 'ssl') + except ValueError: + print 'Value for "ssl" ("%s") not boolean!' % cfgread.get('server', 'ssl') + sys.exit(127) + +if config['ssl']: + if 'sslcert' in cfgread.options('server'): + config['sslcert'] = cfgread.get('server', 'sslcert') + else: + print 'SSL but no certificate file specified!' + sys.exit(127) + +try: + config['mode'] = cfgread.get('server', 'mode') +except ConfigParser.NoOptionError: + print 'No "mode" specified!' + sys.exit(127) + +if config['mode']=='checkresult': + try: + config['checkresultdir'] = cfgread.get('mode_checkresult','dir') + except ConfigParser.NoOptionError: + print 'No "dir" in section "mode_checkresult" specified!' + sys.exit(127) + + if os.access(config['checkresultdir'],os.W_OK) == False: + print 'Checkresult directory "%s" is not writable!' % config['checkresultdir'] + sys.exit(1) + +elif config['mode']=='passive': + try: + config['pipe'] = cfgread.get('mode_passive','pipe') + except ConfigParser.NoOptionError: + print 'No "pipe" in section "mode_passive" specified!' + sys.exit(127) + + if os.access(config['pipe'],os.W_OK) == False: + print 'Nagios command pipe "%s" is not writable!' % config['pipe'] + sys.exit(1) + +else: + print 'Mode "%s" is neither "checkresult" nor "passive"!' + sys.exit(127) + +acls = { 'a_hl':{}, 'a_hr':{}, } +if 'acl' in cfgread.options('server'): + try: + config['acl'] = cfgread.getboolean('server', 'acl') + except ValueError: + print 'Value for "acl" ("%s") not boolean!' % cfgread.get('server', 'acl') + sys.exit(127) +if config['acl']: + if cfgread.has_section('acl_allowed_hosts_list'): + for user in cfgread.options('acl_allowed_hosts_list'): + acls['a_hl'][user] = [ah.lstrip().rstrip() for ah in cfgread.get('acl_allowed_hosts_list',user).split(',')] + if cfgread.has_section('acl_allowed_hosts_re'): + for user in cfgread.options('acl_allowed_hosts_re'): + acls['a_hr'][user] = re.compile(cfgread.get('acl_allowed_hosts_re',user)) - config['max_xml_file_size'] = cfgread.get('server', 'max_xml_file_size') - config['xml2nagios_cmdline'] = cfgread.get('server', 'xml2nagios_cmdline') -except ConfigParser.NoOptionError, e: - print 'Config file error: %s ' % e - sys.exit(1) users = {} for u in cfgread.options('users'): @@ -51,7 +144,7 @@ for u in cfgread.options('users'): ############################################################################## -class HTTP2NagiosHandler(BaseHTTPServer.BaseHTTPRequestHandler): +class HTTP2NagiosHandler(MyHTTPRequestHandler): def http_error(self, code, output): self.send_response(code) @@ -76,8 +169,6 @@ class HTTP2NagiosHandler(BaseHTTPServer.BaseHTTPRequestHandler): def do_POST(self): - cmdline = config['xml2nagios_cmdline'] - # Check Basic Auth try: authdata = base64.b64decode(self.headers['Authorization'].split(' ')[1]).split(':') @@ -97,39 +188,72 @@ class HTTP2NagiosHandler(BaseHTTPServer.BaseHTTPRequestHandler): xmltext = query.get('xmlfile')[0] if len(xmltext) > 0: - try: - cmd = subprocess.Popen(cmdline.split(' '), stdin=subprocess.PIPE, stdout=subprocess.PIPE) - output = cmd.communicate(xmltext)[0].rstrip() - retcode = cmd.returncode + doc = read_xml_from_string(xmltext) + checks = xml_to_dict(doc) - if retcode == 0: + if config['acl']: + new_checks = [] + for check in checks: + if authdata[0] in acls['a_hl'] and check['host_name'] in acls['a_hl'][authdata[0]]: + new_checks.append(check) + elif authdata[0] in acls['a_hr'] and (acls['a_hr'][authdata[0]]).search(check['host_name']): + new_checks.append(check) + + count_acl_failed = len(checks) - len(new_checks) + checks = new_checks + else: + count_acl_failed = None + + if config['mode'] == 'checkresult': + (count_services, count_failed, list_failed) = dict2out_checkresult(checks, xml_get_timestamp(doc), config['checkresultdir']) + + if count_failed < count_services: self.send_response(200) self.send_header('Content-Type', 'text/plain') self.end_headers() - self.wfile.write(output) + statusmsg = 'Wrote %s check results, %s failed' % (count_services, count_failed) + if count_acl_failed != None: + statusmsg += ' - %s check results failed ACL check' % count_acl_failed + self.wfile.write(statusmsg) return else: - http_error(500, output) + self.http_error(501, 'Could not write all %s check results' % count_services) return - except OSError: - http_error(500, 'Nag(IX)SC - Could not execute "%s"' % cmdline) + elif config['mode'] == 'passive': + count_services = dict2out_passive(checks, xml_get_timestamp(doc), config['pipe']) + + self.send_response(200) + self.send_header('Content-Type', 'text/plain') + self.end_headers() + self.wfile.write('Wrote %s check results' % count_services) return else: - http_error(500, 'Nag(IX)SC - No data received') + self.http_error(502, 'Nag(IX)SC - No data received') return def main(): + if options.nossl: + config['ssl'] = False + + if config['ssl'] and not os.path.isfile(config['sslcert']): + print 'SSL certificate "%s" not found!' % config['sslcert'] + sys.exit(127) + + if options.daemon: + daemonize(pidfile=config['pidfile']) + else: + print 'curl -v -u nagixsc:nagixsc -F \'xmlfile=@xml/nagixsc.xml\' http://127.0.0.1:%s/\n\n' % config['port'] + + server = MyHTTPServer((config['ip'], config['port']), HTTP2NagiosHandler, ssl=config['ssl'], sslpemfile=config['sslcert']) try: - server = BaseHTTPServer.HTTPServer((config['ip'], config['port']), HTTP2NagiosHandler) server.serve_forever() except: server.socket.close() if __name__ == '__main__': - print 'curl -v -u nagixsc:nagixsc -F \'xmlfile=@xml/nagixsc.xml\' http://127.0.0.1:15667/\n\n' main()