Code

Added host checks
[nagixsc.git] / nagixsc.py
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