From 3c751ba932bc8835d607f002ba605de27c2604d7 Mon Sep 17 00:00:00 2001 From: "flavien.peyre" Date: Mon, 11 May 2015 16:38:58 -0400 Subject: [PATCH] Hosts status API now use live_shinken Change-Id: I75ec95e9698208930d5993af9f25281d9244b991 --- surveil/api/datamodel/status/live_host.py | 8 +- .../api/handlers/status/live_host_handler.py | 123 +++++---- .../api/controllers/v2/status/test_hosts.py | 234 ++++-------------- 3 files changed, 130 insertions(+), 235 deletions(-) diff --git a/surveil/api/datamodel/status/live_host.py b/surveil/api/datamodel/status/live_host.py index 6f2c6da..5fd54b1 100644 --- a/surveil/api/datamodel/status/live_host.py +++ b/surveil/api/datamodel/status/live_host.py @@ -34,10 +34,10 @@ class LiveHost(types.Base): description = wsme.wsattr(wtypes.text, mandatory=False) """The description of the host""" - state = wsme.wsattr(int, mandatory=False) + state = wsme.wsattr(wtypes.text, mandatory=False) """The current state of the host""" - acknowledged = wsme.wsattr(int, mandatory=False) + acknowledged = wsme.wsattr(bool, mandatory=False) """Wether or not the problem, if any, has been acknowledged""" last_check = wsme.wsattr(int, mandatory=False) @@ -57,8 +57,8 @@ class LiveHost(types.Base): childs=['surveil.com'], parents=['parent.com'], description='Very Nice Host', - state=0, - acknowledged=1, + state='OK', + acknowledged=True, last_check=1429220785, last_state_change=1429220785, plugin_output='PING OK - Packet loss = 0%, RTA = 0.02 ms' diff --git a/surveil/api/handlers/status/live_host_handler.py b/surveil/api/handlers/status/live_host_handler.py index ab1daf5..d902352 100644 --- a/surveil/api/handlers/status/live_host_handler.py +++ b/surveil/api/handlers/status/live_host_handler.py @@ -17,8 +17,9 @@ import json from surveil.api.datamodel.status import live_host from surveil.api.handlers import handler -from surveil.api.handlers.status import fields_filter -from surveil.api.handlers.status import influxdb_query +from surveil.api.handlers.status import mongodb_query + +import wsme class HostHandler(handler.Handler): @@ -26,42 +27,34 @@ class HostHandler(handler.Handler): def get(self, host_name): """Return a host.""" - cli = self.request.influxdb_client - query = ("SELECT * from LIVE_HOST_STATE " - "WHERE host_name='%s' " - "GROUP BY * " - "ORDER BY time DESC " - "LIMIT 1") % host_name - response = cli.query(query) - - host = live_host.LiveHost( - **self._host_dict_from_influx_item(response.items()[0]) + mongo_s = self.request.mongo_connection.shinken_live.hosts.find_one( + {"host_name": host_name} ) - return host + + return live_host.LiveHost(**_host_dict_from_mongo_item(mongo_s)) def get_all(self, live_query=None): """Return all live hosts.""" - cli = self.request.influxdb_client - query = influxdb_query.build_influxdb_query( - live_query, - 'LIVE_HOST_STATE', - group_by=['host_name', 'address', 'childs', 'parents'], - order_by=['time DESC'], - limit=1 - ) - response = cli.query(query) - - host_dicts = [] - - for item in response.items(): - host_dict = self._host_dict_from_influx_item(item) - host_dicts.append(host_dict) if live_query: - host_dicts = fields_filter.filter_fields( - host_dicts, - live_query - ) + lq_filters, lq_fields = _translate_live_query(live_query) + else: + lq_filters = {} + lq_fields = {} + + query, fields = mongodb_query.build_mongodb_query(lq_filters, + lq_fields) + + if fields != {}: + mongo_dicts = (self.request.mongo_connection. + shinken_live.hosts.find(query, fields)) + else: + mongo_dicts = (self.request.mongo_connection. + shinken_live.hosts.find(query)) + + host_dicts = [ + _host_dict_from_mongo_item(s) for s in mongo_dicts + ] hosts = [] for host_dict in host_dicts: @@ -70,26 +63,54 @@ class HostHandler(handler.Handler): return hosts - def _host_dict_from_influx_item(self, item): - points = item[1] - first_point = next(points) - tags = item[0][1] +def _translate_live_query(live_query): + # Mappings + mapping = { + "last_check": "last_chk", + "description": "display_name", + "plugin_output": "output", + "acknowledged": "problem_has_been_acknoledged" + } - host_dict = { - # TAGS - "host_name": tags['host_name'], - "address": tags['address'], - "description": tags['host_name'], - "childs": json.loads(tags['childs']), - "parents": json.loads(tags['parents']), + # Load the fields + if live_query.fields != wsme.Unset: + fields = live_query.fields + else: + fields = [] - # Values - "state": first_point['state'], - "acknowledged": int(first_point['acknowledged']), - "last_check": int(first_point['last_check']), - "last_state_change": int(first_point['last_state_change']), - "plugin_output": first_point['output'] - } + # Translate the fields + lq_fields = [] + for field in fields: + lq_fields.append(mapping.get(field, field)) - return host_dict + # Load the filters + filters = json.loads(live_query.filters) + + # Translate the filters + for filter in filters.values(): + for field in filter.keys(): + value = filter.pop(field) + filter[mapping.get(field, field)] = value + + return filters, lq_fields + + +def _host_dict_from_mongo_item(mongo_item): + """Create a dict from a mongodb item.""" + + mappings = [ + ('last_chk', 'last_check', int), + ('last_state_change', 'last_state_change', int), + ('output', 'plugin_output', str), + ('problem_has_been_acknowledged', 'acknowledged', bool), + ('state', 'state', str), + ('display_name', 'description', str), + ] + + for field in mappings: + value = mongo_item.pop(field[0], None) + if value is not None: + mongo_item[field[1]] = field[2](value) + + return mongo_item \ No newline at end of file diff --git a/surveil/tests/api/controllers/v2/status/test_hosts.py b/surveil/tests/api/controllers/v2/status/test_hosts.py index 5b7decb..927629a 100644 --- a/surveil/tests/api/controllers/v2/status/test_hosts.py +++ b/surveil/tests/api/controllers/v2/status/test_hosts.py @@ -15,8 +15,6 @@ import copy import json -import httpretty - from surveil.tests.api import functionalTest @@ -24,83 +22,50 @@ class TestStatusHosts(functionalTest.FunctionalTest): def setUp(self): super(TestStatusHosts, self).setUp() - self.influxdb_response = json.dumps({ - "results": [ - { - "series": [ - {"name": "LIVE_HOST_STATE", - "tags": {"host_name": "localhost", - "address": "127.0.0.1", - "childs": '[]', - "parents": '["parent.com"]'}, - "columns": [ - "time", - "last_check", - "last_state_change", - "output", - "state", - "state_type", - "acknowledged" - ], - "values":[ - ["2015-04-19T01:09:24Z", - 1.429405764e+09, - 1.429405765316929e+09, - "OK - localhost: rta 0.033ms, lost 0%", - 0, - "HARD", - 0] - ]}, - {"name": "LIVE_HOST_STATE", - "tags": {"host_name": "test_keystone", - "address": "127.0.0.1", - "childs": '[]', - "parents": '["parent.com"]'}, - "columns": [ - "time", - "last_check", - "last_state_change", - "output", - "state", - "state_type", - "acknowledged" - ], - "values":[ - ["2015-04-19T01:09:23Z", - 1.429405763e+09, - 1.429405765317144e+09, - "OK - 127.0.0.1: rta 0.032ms, lost 0%", - 0, - "HARD", - 0] - ]}, - {"name": "LIVE_HOST_STATE", - "tags": {"host_name": "ws-arbiter", - "address": "127.0.0.1", - "childs": '["test_keystone"]', - "parents": '["parent.com"]'}, - "columns": [ - "time", - "last_check", - "last_state_change", - "output", - "state", - "state_type", - "acknowledged" - ], - "values":[ - ["2015-04-19T01:09:24Z", - 1.429405764e+09, - 1.429405765317063e+09, - "OK - localhost: rta 0.030ms, lost 0%", - 0, - "HARD", - 0] - ]} - ] - } - ] - }) + self.host = [ + { + "display_name": "localhost", + "address": "127.0.0.1", + "childs": [], + "parents": ['parent.com'], + "last_chk": 1.429405764e+09, + "last_state_change": 1.429405765316929e+09, + "plugin_output": "OK - localhost: rta 0.033ms, lost 0%", + "state": "OK", + "state_type": "HARD", + "problem_has_been_acknowledged": True, + "host_name": "localhost", + }, + { + "display_name": "test_keystone", + "address": "127.0.0.1", + "childs": [], + "parents": ['parent.com'], + "last_chk": 1.429405763e+09, + "last_state_change": 1.429405765317144e+09, + "plugin_output": "OK - 127.0.0.1: rta 0.032ms, lost 0%", + "state": "OK", + "state_type": "HARD", + "problem_has_been_acknowledged": True, + "host_name": "test_keystone", + }, + { + "display_name": "ws-arbiter", + "address": "127.0.0.1", + "childs": ['test_keystone'], + "parents": ['parent.com'], + "last_chk": 1.429405764e+09, + "last_state_change": 1.429405765317063e+09, + "plugin_output": "OK - localhost: rta 0.030ms, lost 0%", + "state": "OK", + "state_type": "HARD", + "problem_has_been_acknowledged": True, + "host_name": "ws-arbiter", + }, + ] + self.mongoconnection.shinken_live.hosts.insert( + copy.deepcopy(self.host) + ) self.services = [ { @@ -121,17 +86,13 @@ class TestStatusHosts(functionalTest.FunctionalTest): "last_state_change": 1429220785, "plugin_output": 'Hi there' }, + ] self.mongoconnection.shinken_live.services.insert( copy.deepcopy(self.services) ) - @httpretty.activate def test_get_all_hosts(self): - httpretty.register_uri(httpretty.GET, - "http://influxdb:8086/query", - body=self.influxdb_response) - response = self.get("/v2/status/hosts") expected = [ @@ -142,8 +103,8 @@ class TestStatusHosts(functionalTest.FunctionalTest): "last_state_change": 1429405765, "plugin_output": "OK - localhost: rta 0.033ms, lost 0%", "last_check": 1429405764, - "state": 0, - "acknowledged": 0, + "state": "OK", + "acknowledged": True, "host_name": "localhost"}, {"description": "test_keystone", "address": "127.0.0.1", @@ -152,8 +113,8 @@ class TestStatusHosts(functionalTest.FunctionalTest): "last_state_change": 1429405765, "plugin_output": "OK - 127.0.0.1: rta 0.032ms, lost 0%", "last_check": 1429405763, - "state": 0, - "acknowledged": 0, + "state": "OK", + "acknowledged": True, "host_name": "test_keystone"}, {"description": "ws-arbiter", "address": "127.0.0.1", @@ -162,61 +123,19 @@ class TestStatusHosts(functionalTest.FunctionalTest): "last_state_change": 1429405765, "plugin_output": "OK - localhost: rta 0.030ms, lost 0%", "last_check": 1429405764, - "state": 0, - "acknowledged": 0, + "state": "OK", + "acknowledged": True, "host_name": "ws-arbiter"}] self.assertItemsEqual(json.loads(response.body), expected) - self.assertEqual( - httpretty.last_request().querystring['q'], - ["SELECT * FROM LIVE_HOST_STATE " - "GROUP BY host_name, address, childs, parents " - "ORDER BY time DESC LIMIT 1"] - ) - @httpretty.activate def test_query_hosts(self): - influxdb_response = json.dumps({ - "results": [ - { - "series": [ - {"name": "LIVE_HOST_STATE", - "tags": {"host_name": "ws-arbiter", - "address": "127.0.0.1", - "childs": '["test_keystone"]', - "parents": '["parent.com"]'}, - "columns": [ - "time", - "last_check", - "last_state_change", - "output", - "state", - "state_type", - "acknowledged" - ], - "values":[ - ["2015-04-19T01:09:24Z", - 1.429405764e+09, - 1.429405765317063e+09, - "OK - localhost: rta 0.030ms, lost 0%", - 0, - "HARD", - 0] - ]} - ] - } - ] - }) - httpretty.register_uri(httpretty.GET, - "http://influxdb:8086/query", - body=influxdb_response) - query = { 'fields': ['host_name', 'last_check'], 'filters': json.dumps({ "isnot": { "host_name": ['localhost'], - "description": ["test_keystone"] + "description": ['test_keystone'] } }) } @@ -227,44 +146,7 @@ class TestStatusHosts(functionalTest.FunctionalTest): self.assertItemsEqual(json.loads(response.body), expected) - self.assertEqual( - httpretty.last_request().querystring['q'], - ["SELECT * FROM LIVE_HOST_STATE WHERE host_name!='localhost' " - "AND description!='test_keystone' " - "GROUP BY host_name, address, childs, parents " - "ORDER BY time DESC " - "LIMIT 1"] - ) - - @httpretty.activate def test_get_specific_host(self): - influx_response = json.dumps( - {"results": [ - {"series": [ - {"name": "LIVE_HOST_STATE", - "tags": {"address": "localhost", - "childs": "[\"test_keystone\"]", - "parents": '["parent.com"]', - "host_name": "localhost"}, - "columns": ["time", - "acknowledged", - "last_check", - "last_state_change", - "output", - "state", - "state_type"], - "values":[["2015-04-23T18:03:11Z", - 0, - 1.429812191e+09, - 1.429812192166997e+09, - "OK - localhost: rta 0.044ms, lost 0%", - 0, - "HARD"]]}]}]} - ) - - httpretty.register_uri(httpretty.GET, - "http://influxdb:8086/query", - body=influx_response) response = self.get("/v2/status/hosts/localhost") @@ -272,23 +154,15 @@ class TestStatusHosts(functionalTest.FunctionalTest): "parents": ['parent.com'], "description": "localhost", "last_state_change": 1429812192, - "acknowledged": 0, + "acknowledged": True, "plugin_output": "OK - localhost: rta 0.044ms, lost 0%", "last_check": 1429812191, - "state": 0, + "state": "OK", "host_name": "localhost", "address": "localhost"} self.assertItemsEqual(json.loads(response.body), expected) - self.assertEqual( - httpretty.last_request().querystring['q'], - ["SELECT * from LIVE_HOST_STATE WHERE host_name='localhost'" - " GROUP BY * " - "ORDER BY time DESC " - "LIMIT 1"] - ) - def test_get_specific_host_service(self): response = self.get( "/v2/status/hosts/someserver/services/servicesomething"