1 import base64
2 import datetime
3 import libxml2
5 def debug(level, verb, string):
6 if level <= verb:
7 print "%s: %s" % (level, string)
10 ##############################################################################
12 def available_encodings():
13 return ['base64', 'plain',]
16 def decode(data, encoding):
17 if encoding == 'plain':
18 return data
19 else:
20 return base64.b64decode(data)
23 def encode(data, encoding=None):
24 if encoding == 'plain':
25 return data
26 else:
27 return base64.b64encode(data)
30 ##############################################################################
32 def xml_check_version(xmldoc):
33 # FIXME: Check XML structure
34 try:
35 xmlnagixsc = xmldoc.xpathNewContext().xpathEval('/nagixsc')[0]
36 except:
37 return (False, 'Not a Nag(IX)SC XML file!')
39 try:
40 if xmlnagixsc.prop('version') != "1.0":
41 return (False, 'Wrong version (found "%s", need "1.0") of XML file!' % xmlnagixsc.prop('version'))
42 except:
43 return (False, 'No version information found in XML file!')
45 return (True, 'XML seems to be ok')
48 def xml_get_timestamp(xmldoc):
49 try:
50 timestamp = int(xmldoc.xpathNewContext().xpathEval('/nagixsc/timestamp')[0].get_content())
51 except:
52 return False
54 return timestamp
57 def xml_to_dict(xmldoc, verb=0, hostfilter=None, servicefilter=None):
58 checks = []
59 filetimestamp = xml_get_timestamp(xmldoc)
61 if hostfilter:
62 hosts = xmldoc.xpathNewContext().xpathEval('/nagixsc/host[name="%s"] | /nagixsc/host[name="%s"]' % (hostfilter, encode(hostfilter)))
63 else:
64 hosts = xmldoc.xpathNewContext().xpathEval('/nagixsc/host')
66 for host in hosts:
67 xmlhostname = host.xpathEval('name')[0]
68 hostname = decode(xmlhostname.get_content(), xmlhostname.prop('encoding'))
69 debug(2, verb, 'Found host "%s"' % hostname)
71 # Look for Host check result
72 if host.xpathEval('returncode'):
73 retcode = host.xpathEval('returncode')[0].get_content()
74 else:
75 retcode = None
77 if host.xpathEval('output'):
78 xmloutput = host.xpathEval('output')[0]
79 output = decode(xmloutput.get_content(), xmloutput.prop('encoding')).rstrip()
80 else:
81 output = None
83 if host.xpathEval('timestamp'):
84 timestamp = int(host.xpathEval('timestamp')[0].get_content())
85 else:
86 timestamp = filetimestamp
88 if retcode and output:
89 checks.append({'host_name':hostname, 'service_description':None, 'returncode':retcode, 'output':output, 'timestamp':timestamp})
92 # Look for service filter
93 if servicefilter:
94 services = host.xpathEval('service[description="%s"] | service[description="%s"]' % (servicefilter, encode(servicefilter)))
95 else:
96 services = host.xpathEval('service')
98 # Loop over services in host
99 for service in services:
100 service_dict = {}
102 xmldescr = service.xpathEval('description')[0]
103 xmloutput = service.xpathEval('output')[0]
105 srvdescr = decode(xmldescr.get_content(), xmldescr.prop('encoding'))
106 retcode = service.xpathEval('returncode')[0].get_content()
107 output = decode(xmloutput.get_content(), xmloutput.prop('encoding')).rstrip()
109 try:
110 timestamp = int(service.xpathEval('timestamp')[0].get_content())
111 except:
112 timestamp = filetimestamp
114 debug(2, verb, 'Found service "%s"' % srvdescr)
116 service_dict = {'host_name':hostname, 'service_description':srvdescr, 'returncode':retcode, 'output':output, 'timestamp':timestamp}
117 checks.append(service_dict)
119 debug(1, verb, 'Host: "%s" - Service: "%s" - RetCode: "%s" - Output: "%s"' % (hostname, srvdescr, retcode, output) )
121 return checks
124 def xml_from_dict(checks, encoding='base64'):
125 lasthost = None
127 db = [(check['host_name'], check) for check in checks]
128 db.sort()
130 xmldoc = libxml2.newDoc('1.0')
131 xmlroot = xmldoc.newChild(None, 'nagixsc', None)
132 xmlroot.setProp('version', '1.0')
133 xmltimestamp = xmlroot.newChild(None, 'timestamp', datetime.datetime.now().strftime('%s'))
135 for entry in db:
136 check = entry[1]
138 if check['host_name'] != lasthost:
139 xmlhost = xmlroot.newChild(None, 'host', None)
140 xmlhostname = xmlhost.newChild(None, 'name', encode(check['host_name'], encoding))
141 lasthost = check['host_name']
143 if check['service_description'] == '' or check['service_description'] == None:
144 # Host check result
145 xmlreturncode = xmlhost.newChild(None, 'returncode', str(check['returncode']))
146 xmloutput = xmlhost.newChild(None, 'output', encode(check['output'], encoding))
147 xmloutput.setProp('encoding', encoding)
148 if check.has_key('timestamp'):
149 xmltimestamp = xmlhost.newChild(None, 'timestamp', str(check['timestamp']))
150 else:
151 # Service check result
152 xmlservice = xmlhost.newChild(None, 'service', None)
153 xmlname = xmlservice.newChild(None, 'description', encode(check['service_description'], encoding))
154 xmlname.setProp('encoding', encoding)
155 xmlreturncode = xmlservice.newChild(None, 'returncode', str(check['returncode']))
156 xmloutput = xmlservice.newChild(None, 'output', encode(check['output'], encoding))
157 xmloutput.setProp('encoding', encoding)
158 if check.has_key('timestamp'):
159 xmltimestamp = xmlservice.newChild(None, 'timestamp', str(check['timestamp']))
161 return xmldoc
164 def check_mark_outdated(check, now, maxtimediff, markold):
165 timedelta = now - check['timestamp']
166 if timedelta > maxtimediff:
167 check['output'] = 'Nag(ix)SC: Check result is %s(>%s) seconds old - %s' % (timedelta, maxtimediff, check['output'])
168 if markold:
169 check['returncode'] = 3
170 return check