1 #!/usr/bin/python
3 import BaseHTTPServer
4 import ConfigParser
5 import base64
6 import cgi
7 import optparse
8 import os
9 import re
10 import subprocess
11 import sys
13 try:
14 from hashlib import md5
15 except ImportError:
16 from md5 import md5
18 ##############################################################################
20 parser = optparse.OptionParser()
22 parser.add_option('-c', '', dest='cfgfile', help='Config file')
24 parser.set_defaults(cfgfile='http2nagios.cfg')
26 (options, args) = parser.parse_args()
28 cfgread = ConfigParser.SafeConfigParser()
29 cfgread.optionxform = str # We need case-sensitive options
30 cfg_list = cfgread.read(options.cfgfile)
32 if cfg_list == []:
33 print 'Config file "%s" could not be read!' % options.cfgfile
34 sys.exit(1)
36 config = {}
37 try:
38 config['ip'] = cfgread.get('server', 'ip')
39 config['port'] = cfgread.getint('server', 'port')
41 config['max_xml_file_size'] = cfgread.get('server', 'max_xml_file_size')
42 config['xml2nagios_cmdline'] = cfgread.get('server', 'xml2nagios_cmdline')
44 except ConfigParser.NoOptionError, e:
45 print 'Config file error: %s ' % e
46 sys.exit(1)
48 users = {}
49 for u in cfgread.options('users'):
50 users[u] = cfgread.get('users', u)
52 ##############################################################################
54 class HTTP2NagiosHandler(BaseHTTPServer.BaseHTTPRequestHandler):
56 def http_error(self, code, output):
57 self.send_response(code)
58 self.send_header('Content-Type', 'text/plain')
59 self.end_headers()
60 self.wfile.write(output)
61 return
64 def do_GET(self):
65 self.send_response(200)
66 self.send_header('Content-Type', 'text/html')
67 self.end_headers()
68 self.wfile.write(''' <html><body>
69 <form action="." method="post" enctype="multipart/form-data">
70 filename: <input type="file" name="xmlfile" /><br />
71 <input type="submit" />
72 </form>
73 </body></html>
74 ''')
75 return
78 def do_POST(self):
79 cmdline = config['xml2nagios_cmdline']
81 # Check Basic Auth
82 try:
83 authdata = base64.b64decode(self.headers['Authorization'].split(' ')[1]).split(':')
84 if not users[authdata[0]] == md5(authdata[1]).hexdigest():
85 raise Exception
86 except:
87 self.send_response(401)
88 self.send_header('WWW-Authenticate', 'Basic realm="Nag(ix)SC HTTP Push"')
89 self.send_header('Content-Type', 'text/plain')
90 self.end_headers()
91 self.wfile.write('Sorry! No action without login!')
92 return
94 (ctype,pdict) = cgi.parse_header(self.headers.getheader('content-type'))
95 if ctype == 'multipart/form-data':
96 query = cgi.parse_multipart(self.rfile, pdict)
97 xmltext = query.get('xmlfile')[0]
99 if len(xmltext) > 0:
100 try:
101 cmd = subprocess.Popen(cmdline.split(' '), stdin=subprocess.PIPE, stdout=subprocess.PIPE)
102 output = cmd.communicate(xmltext)[0].rstrip()
103 retcode = cmd.returncode
105 if retcode == 0:
106 self.send_response(200)
107 self.send_header('Content-Type', 'text/plain')
108 self.end_headers()
109 self.wfile.write(output)
110 return
111 else:
112 http_error(500, output)
113 return
115 except OSError:
116 http_error(500, 'Nag(IX)SC - Could not execute "%s"' % cmdline)
117 return
119 else:
120 http_error(500, 'Nag(IX)SC - No data received')
121 return
125 def main():
126 try:
127 server = BaseHTTPServer.HTTPServer((config['ip'], config['port']), HTTP2NagiosHandler)
128 server.serve_forever()
129 except:
130 server.socket.close()
132 if __name__ == '__main__':
133 print 'curl -v -u nagixsc:nagixsc -F \'xmlfile=@xml/nagixsc.xml\' http://127.0.0.1:15667/\n\n'
134 main()