1 import base64
2 import datetime
3 import libxml2
4 import sys
6 def debug(level, verb, string):
7 if level <= verb:
8 print "%s: %s" % (level, string)
11 ##############################################################################
13 def available_encodings():
14 return ['base64', 'plain',]
17 def decode(data, encoding):
18 if encoding == 'plain':
19 return data
20 else:
21 return base64.b64decode(data)
24 def encode(data, encoding=None):
25 if encoding == 'plain':
26 return data
27 else:
28 return base64.b64encode(data)
31 ##############################################################################
33 def read_xml(options):
34 if options.url != None:
35 import urllib2
37 if options.httpuser and options.httppasswd:
38 passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
39 passman.add_password(None, options.url, options.httpuser, options.httppasswd)
40 authhandler = urllib2.HTTPBasicAuthHandler(passman)
41 opener = urllib2.build_opener(authhandler)
42 urllib2.install_opener(opener)
44 try:
45 response = urllib2.urlopen(options.url)
46 except urllib2.HTTPError, error:
47 print error
48 sys.exit(0)
49 except urllib2.URLError, error:
50 print error.reason[1]
51 sys.exit(0)
53 doc = libxml2.parseDoc(response.read())
54 response.close()
56 else:
57 doc = libxml2.parseFile(options.file)
59 return doc
62 ##############################################################################
64 def xml_check_version(xmldoc):
65 # FIXME: Check XML structure
66 try:
67 xmlnagixsc = xmldoc.xpathNewContext().xpathEval('/nagixsc')[0]
68 except:
69 return (False, 'Not a Nag(IX)SC XML file!')
71 try:
72 if xmlnagixsc.prop('version') != "1.0":
73 return (False, 'Wrong version (found "%s", need "1.0") of XML file!' % xmlnagixsc.prop('version'))
74 except:
75 return (False, 'No version information found in XML file!')
77 return (True, 'XML seems to be ok')
80 def xml_get_timestamp(xmldoc):
81 try:
82 timestamp = int(xmldoc.xpathNewContext().xpathEval('/nagixsc/timestamp')[0].get_content())
83 except:
84 return False
86 return timestamp
89 def xml_to_dict(xmldoc, verb=0, hostfilter=None, servicefilter=None):
90 checks = []
91 filetimestamp = xml_get_timestamp(xmldoc)
93 if hostfilter:
94 hosts = xmldoc.xpathNewContext().xpathEval('/nagixsc/host[name="%s"] | /nagixsc/host[name="%s"]' % (hostfilter, encode(hostfilter)))
95 else:
96 hosts = xmldoc.xpathNewContext().xpathEval('/nagixsc/host')
98 for host in hosts:
99 xmlhostname = host.xpathEval('name')[0]
100 hostname = decode(xmlhostname.get_content(), xmlhostname.prop('encoding'))
101 debug(2, verb, 'Found host "%s"' % hostname)
103 # Look for Host check result
104 if host.xpathEval('returncode'):
105 retcode = host.xpathEval('returncode')[0].get_content()
106 else:
107 retcode = None
109 if host.xpathEval('output'):
110 xmloutput = host.xpathEval('output')[0]
111 output = decode(xmloutput.get_content(), xmloutput.prop('encoding')).rstrip()
112 else:
113 output = None
115 if host.xpathEval('timestamp'):
116 timestamp = int(host.xpathEval('timestamp')[0].get_content())
117 else:
118 timestamp = filetimestamp
120 if retcode and output:
121 checks.append({'host_name':hostname, 'service_description':None, 'returncode':retcode, 'output':output, 'timestamp':timestamp})
124 # Look for service filter
125 if servicefilter:
126 services = host.xpathEval('service[description="%s"] | service[description="%s"]' % (servicefilter, encode(servicefilter)))
127 else:
128 services = host.xpathEval('service')
130 # Loop over services in host
131 for service in services:
132 service_dict = {}
134 xmldescr = service.xpathEval('description')[0]
135 xmloutput = service.xpathEval('output')[0]
137 srvdescr = decode(xmldescr.get_content(), xmldescr.prop('encoding'))
138 retcode = service.xpathEval('returncode')[0].get_content()
139 output = decode(xmloutput.get_content(), xmloutput.prop('encoding')).rstrip()
141 try:
142 timestamp = int(service.xpathEval('timestamp')[0].get_content())
143 except:
144 timestamp = filetimestamp
146 debug(2, verb, 'Found service "%s"' % srvdescr)
148 service_dict = {'host_name':hostname, 'service_description':srvdescr, 'returncode':retcode, 'output':output, 'timestamp':timestamp}
149 checks.append(service_dict)
151 debug(1, verb, 'Host: "%s" - Service: "%s" - RetCode: "%s" - Output: "%s"' % (hostname, srvdescr, retcode, output) )
153 return checks
156 def xml_from_dict(checks, encoding='base64'):
157 lasthost = None
159 db = [(check['host_name'], check) for check in checks]
160 db.sort()
162 xmldoc = libxml2.newDoc('1.0')
163 xmlroot = xmldoc.newChild(None, 'nagixsc', None)
164 xmlroot.setProp('version', '1.0')
165 xmltimestamp = xmlroot.newChild(None, 'timestamp', datetime.datetime.now().strftime('%s'))
167 for entry in db:
168 check = entry[1]
170 if check['host_name'] != lasthost:
171 xmlhost = xmlroot.newChild(None, 'host', None)
172 xmlhostname = xmlhost.newChild(None, 'name', encode(check['host_name'], encoding))
173 lasthost = check['host_name']
175 if check['service_description'] == '' or check['service_description'] == None:
176 # Host check result
177 xmlreturncode = xmlhost.newChild(None, 'returncode', str(check['returncode']))
178 xmloutput = xmlhost.newChild(None, 'output', encode(check['output'], encoding))
179 xmloutput.setProp('encoding', encoding)
180 if check.has_key('timestamp'):
181 xmltimestamp = xmlhost.newChild(None, 'timestamp', str(check['timestamp']))
182 else:
183 # Service check result
184 xmlservice = xmlhost.newChild(None, 'service', None)
185 xmlname = xmlservice.newChild(None, 'description', encode(check['service_description'], encoding))
186 xmlname.setProp('encoding', encoding)
187 xmlreturncode = xmlservice.newChild(None, 'returncode', str(check['returncode']))
188 xmloutput = xmlservice.newChild(None, 'output', encode(check['output'], encoding))
189 xmloutput.setProp('encoding', encoding)
190 if check.has_key('timestamp'):
191 xmltimestamp = xmlservice.newChild(None, 'timestamp', str(check['timestamp']))
193 return xmldoc
196 def check_mark_outdated(check, now, maxtimediff, markold):
197 timedelta = now - check['timestamp']
198 if timedelta > maxtimediff:
199 check['output'] = 'Nag(ix)SC: Check result is %s(>%s) seconds old - %s' % (timedelta, maxtimediff, check['output'])
200 if markold:
201 check['returncode'] = 3
202 return check