[Pkg-nagios-changes] [SCM] UNNAMED PROJECT branch, debian/master, updated. 810edbdd3feedbfe37f4a65bee50b57b2f60fa2a
Gerhard Lausser
gerhard.lausser at consol.de
Tue Feb 28 22:21:32 UTC 2012
The following commit has been merged in the debian/master branch:
commit 34768d04677e6610dd0f9b050be6adfd20e8bc59
Author: Gerhard Lausser <gerhard.lausser at consol.de>
Date: Fri Feb 17 21:09:48 2012 +0100
Add better error handling for invalid livestatus queries
diff --git a/shinken/modules/livestatus_broker/livestatus.py b/shinken/modules/livestatus_broker/livestatus.py
index 93e5a66..8ef1be9 100644
--- a/shinken/modules/livestatus_broker/livestatus.py
+++ b/shinken/modules/livestatus_broker/livestatus.py
@@ -25,6 +25,8 @@
import time
from livestatus_counters import LiveStatusCounters
from livestatus_request import LiveStatusRequest
+from livestatus_response import LiveStatusResponse
+from livestatus_query import LiveStatusQueryError
class LiveStatus(object):
@@ -40,6 +42,27 @@ class LiveStatus(object):
self.counters = LiveStatusCounters()
def handle_request(self, data):
+ try:
+ return self.handle_request_and_fail(data)
+ except LiveStatusQueryError, exp:
+ # LiveStatusQueryError(404, table)
+ # LiveStatusQueryError(450, column)
+ code, detail = exp.args
+ response = LiveStatusResponse()
+ response.output = LiveStatusQueryError.messages[code] % detail
+ response.statuscode = code
+ if 'fixed16' in data:
+ response.responseheader = 'fixed16'
+ return response.respond()
+ except Exception, exp:
+ response = LiveStatusResponse()
+ response.output = LiveStatusQueryError.messages[452] % data
+ response.statuscode = 452
+ if 'fixed16' in data:
+ response.responseheader = 'fixed16'
+ return response.respond()
+
+ def handle_request_and_fail(self, data):
"""Execute the livestatus request.
This function creates a LiveStatusRequest method, calls the parser,
@@ -47,11 +70,7 @@ class LiveStatus(object):
"""
request = LiveStatusRequest(data, self.datamgr, self.query_cache, self.db, self.pnp_path, self.return_queue, self.counters)
- try:
- request.parse_input(data)
- except:
- print "THIS QUERY IS INVALID", data
- return '', False
+ request.parse_input(data)
if sorted([q.my_type for q in request.queries]) == ['command', 'query', 'wait']:
# The Multisite way
for query in [q for q in request.queries if q.my_type == 'command']:
diff --git a/shinken/modules/livestatus_broker/livestatus_query.py b/shinken/modules/livestatus_broker/livestatus_query.py
index ee00388..8a24103 100644
--- a/shinken/modules/livestatus_broker/livestatus_query.py
+++ b/shinken/modules/livestatus_broker/livestatus_query.py
@@ -32,6 +32,15 @@ from livestatus_stack import LiveStatusStack
from livestatus_constraints import LiveStatusConstraints
+class LiveStatusQueryError(Exception):
+ messages = {
+ 200: 'OK',
+ 404: 'Invalid GET request, no such table \'%s\'',
+ 450: 'Invalid GET request, no such column \'%s\'',
+ 452: 'Completely invalid GET request \'%s\'',
+ }
+ pass
+
class LiveStatusQuery(object):
my_type = 'query'
@@ -122,6 +131,8 @@ class LiveStatusQuery(object):
keyword = line.split(' ')[0].rstrip(':')
if keyword == 'GET': # Get the name of the base table
_, self.table = self.split_command(line)
+ if self.table not in table_class_map.keys():
+ raise LiveStatusQueryError(404, self.table)
elif keyword == 'Columns': # Get the names of the desired columns
_, self.columns = self.split_option_with_columns(line)
self.response.columnheaders = 'off'
@@ -743,7 +754,7 @@ class LiveStatusQuery(object):
if hasattr(item, attribute):
return getattr(item.__class__, attribute).im_func.default == reference
else:
- return getattr(item.__class__, attribute).im_func.default == reference
+ raise LiveStatusQueryError(450, attribute.replace('lsm_', ''))
def eq_nocase_filter(item):
return getattr(item, attribute)(self).lower() == reference.lower()
@@ -756,7 +767,7 @@ class LiveStatusQuery(object):
if hasattr(item, attribute):
return getattr(item.__class__, attribute).im_func.default != reference
else:
- return getattr(item.__class__, attribute).im_func.default != reference
+ raise LiveStatusQueryError(450, attribute.replace('lsm_', ''))
def gt_filter(item):
try:
@@ -765,7 +776,7 @@ class LiveStatusQuery(object):
if hasattr(item, attribute):
return getattr(item.__class__, attribute).im_func.default > reference
else:
- return getattr(item.__class__, attribute).im_func.default > reference
+ raise LiveStatusQueryError(450, attribute.replace('lsm_', ''))
def ge_filter(item):
try:
@@ -774,7 +785,7 @@ class LiveStatusQuery(object):
if hasattr(item, attribute):
return getattr(item.__class__, attribute).im_func.default >= reference
else:
- return getattr(item.__class__, attribute).im_func.default >= reference
+ raise LiveStatusQueryError(450, attribute.replace('lsm_', ''))
def lt_filter(item):
try:
@@ -783,7 +794,7 @@ class LiveStatusQuery(object):
if hasattr(item, attribute):
return getattr(item.__class__, attribute).im_func.default < reference
else:
- return getattr(item.__class__, attribute).im_func.default < reference
+ raise LiveStatusQueryError(450, attribute.replace('lsm_', ''))
def le_filter(item):
try:
@@ -792,7 +803,7 @@ class LiveStatusQuery(object):
if hasattr(item, attribute):
return getattr(item.__class__, attribute).im_func.default <= reference
else:
- return getattr(item.__class__, attribute).im_func.default <= reference
+ raise LiveStatusQueryError(450, attribute.replace('lsm_', ''))
def match_filter(item):
#print "ma_filter %s %s(%s) ~ %s(%s)" % (attribute, type(getattr(item, attribute)(self)), getattr(item, attribute)(self), type(reference), reference)
@@ -800,7 +811,7 @@ class LiveStatusQuery(object):
p = re.compile(reference)
return p.search(getattr(item, attribute)(self))
except Exception:
- return False
+ raise LiveStatusQueryError(450, attribute.replace('lsm_', ''))
def match_nocase_filter(item):
p = re.compile(reference, re.I)
diff --git a/shinken/modules/livestatus_broker/livestatus_response.py b/shinken/modules/livestatus_broker/livestatus_response.py
index d8092b5..04ea39b 100644
--- a/shinken/modules/livestatus_broker/livestatus_response.py
+++ b/shinken/modules/livestatus_broker/livestatus_response.py
@@ -70,6 +70,7 @@ class LiveStatusResponse:
self.keepalive = keepalive
self.columnheaders = columnheaders
self.separators = separators
+ self.statuscode = 200
self.output = ''
pass
@@ -86,9 +87,8 @@ class LiveStatusResponse:
def respond(self):
self.output += '\n'
if self.responseheader == 'fixed16':
- statuscode = 200
responselength = len(self.output)
- self.output = '%3d %11d\n' % (statuscode, responselength) + self.output
+ self.output = '%3d %11d\n' % (self.statuscode, responselength) + self.output
return self.output, self.keepalive
diff --git a/test/test_livestatus.py b/test/test_livestatus.py
index 47841ff..dc9616c 100755
--- a/test/test_livestatus.py
+++ b/test/test_livestatus.py
@@ -371,13 +371,59 @@ ResponseHeader: fixed16
objlist.append([service, 0, 'OK'])
self.scheduler_loop(1, objlist)
self.update_broker()
+
+ # non-existing filter-column
+ request = """GET hosts
+Columns: name state
+Filter: serialnumber = localhost
+"""
+ goodresponse = """Invalid GET request, no such column 'serialnumber'
+"""
+ response, keepalive = self.livestatus_broker.livestatus.handle_request(request)
+ print "response", response
+ self.assert_(response == goodresponse)
+
+ # this time as fixed16
+ request = """GET hosts
+Columns: name state
+Filter: serialnumber = localhost
+ResponseHeader: fixed16
+"""
+ goodresponse = """450 51
+Invalid GET request, no such column 'serialnumber'
+"""
+ response, keepalive = self.livestatus_broker.livestatus.handle_request(request)
+ print "response", response
+ self.assert_(response == goodresponse)
+
+ # invalid filter-clause. attribute, operator missing
request = """GET hosts
Columns: name state
Filter: localhost
+ResponseHeader: fixed16
+"""
+ goodresponse = """452 106
+Completely invalid GET request 'GET hosts
+Columns: name state
+Filter: localhost
+ResponseHeader: fixed16
+'
+"""
+ response, keepalive = self.livestatus_broker.livestatus.handle_request(request)
+ print response
+ self.assert_(response == goodresponse)
+
+ # non-existing table
+ request = """GET hostshundsglumpvarreckts
+Columns: name state
+ResponseHeader: fixed16
+"""
+ goodresponse = """404 62
+Invalid GET request, no such table 'hostshundsglumpvarreckts'
"""
response, keepalive = self.livestatus_broker.livestatus.handle_request(request)
print response
- self.assert_(response == '')
+ self.assert_(response == goodresponse)
def test_bad_column(self):
self.print_header()
--
UNNAMED PROJECT
More information about the Pkg-nagios-changes
mailing list