From 13052572d35d5fa35e8e0a78414ac9d9efa8e333 Mon Sep 17 00:00:00 2001 From: aviau Date: Thu, 23 Apr 2015 17:32:08 -0400 Subject: [PATCH] LIVE API: Get a specific host service Change-Id: I1e2eea66deee911a86b9416ea7b9bcb7b2678f0a --- surveil/api/controllers/v2/status/hosts.py | 46 +++++++++++---- .../handlers/status/live_service_handler.py | 46 +++++++++++---- .../api/controllers/v2/status/test_hosts.py | 59 +++++++++++++++++++ 3 files changed, 128 insertions(+), 23 deletions(-) diff --git a/surveil/api/controllers/v2/status/hosts.py b/surveil/api/controllers/v2/status/hosts.py index 7e5711d..7976c7c 100644 --- a/surveil/api/controllers/v2/status/hosts.py +++ b/surveil/api/controllers/v2/status/hosts.py @@ -20,7 +20,9 @@ from surveil.api.controllers.v2 import logs from surveil.api.controllers.v2.status import metrics from surveil.api.datamodel.status import live_host from surveil.api.datamodel.status import live_query +from surveil.api.datamodel.status import live_service from surveil.api.handlers.status import live_host_handler +from surveil.api.handlers.status import live_service_handler class HostsController(rest.RestController): @@ -44,9 +46,41 @@ class HostsController(rest.RestController): return HostController(host_name), remainder +class ConfigController(rest.RestController): + + @pecan.expose() + def get_all(self): + """Returns config from a specific host.""" + return "Dump CONFIG" + + +class HostServicesController(rest.RestController): + + @pecan.expose() + def _lookup(self, service_name, *remainder): + return HostServiceController(service_name), remainder + + +class HostServiceController(rest.RestController): + + def __init__(self, service_name): + pecan.request.context['service_name'] = service_name + self.service_name = service_name + + @wsme_pecan.wsexpose(live_service.LiveService) + def get(self): + """Returns a specific host service.""" + handler = live_service_handler.ServiceHandler(pecan.request) + service = handler.get( + pecan.request.context['host_name'], + self.service_name + ) + return service + + class HostController(rest.RestController): - # services = ServicesController() + services = HostServicesController() # See init for controller creation. We need host_name to instanciate it # externalcommands = ExternalCommandsController() # config = config.ConfigController() @@ -62,12 +96,4 @@ class HostController(rest.RestController): """Returns a specific host.""" handler = live_host_handler.HostHandler(pecan.request) host = handler.get(self.host_name) - return host - - -class ConfigController(rest.RestController): - - @pecan.expose() - def get_all(self): - """Returns config from a specific host.""" - return "Dump CONFIG" + return host \ No newline at end of file diff --git a/surveil/api/handlers/status/live_service_handler.py b/surveil/api/handlers/status/live_service_handler.py index 7491387..bfb644c 100644 --- a/surveil/api/handlers/status/live_service_handler.py +++ b/surveil/api/handlers/status/live_service_handler.py @@ -22,6 +22,20 @@ from surveil.api.handlers.status import liveQuery_filter as query_filter class ServiceHandler(handler.Handler): """Fulfills a request on live services.""" + def get(self, host_name, service_name): + """Return a specific service.""" + cli = self.request.influxdb_client + query = ("SELECT * from SERVICE_STATE " + "WHERE host_name='%s' " + "AND service_description='%s' " + "GROUP BY * LIMIT 1") % (host_name, service_name) + response = cli.query(query) + + host = live_service.LiveService( + **self._service_dict_from_influx_item(response.items()[0]) + ) + return host + def get_all(self, live_query=None): """Return all live services.""" cli = self.request.influxdb_client @@ -36,19 +50,7 @@ class ServiceHandler(handler.Handler): service_dicts = [] for item in response.items(): - first_entry = next(item[1]) - - service_dict = { - "service_description": item[0][1]['service_description'], - "host_name": item[0][1]['host_name'], - "description": item[0][1]['service_description'], - "state": first_entry['state'], - "acknowledged": int(first_entry['acknowledged']), - "last_check": int(first_entry['last_check']), - "last_state_change": int(first_entry['last_state_change']), - "plugin_output": first_entry['output'] - } - + service_dict = self._service_dict_from_influx_item(item) service_dicts.append(service_dict) if live_query: @@ -63,3 +65,21 @@ class ServiceHandler(handler.Handler): services.append(service) return services + + def _service_dict_from_influx_item(self, item): + tags = item[0][1] + points = item[1] + first_point = next(points) + + service_dict = { + "service_description": tags['service_description'], + "host_name": tags['host_name'], + "description": tags['service_description'], + "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'] + } + + return service_dict diff --git a/surveil/tests/api/controllers/v2/status/test_hosts.py b/surveil/tests/api/controllers/v2/status/test_hosts.py index 26d5655..78bb0ad 100644 --- a/surveil/tests/api/controllers/v2/status/test_hosts.py +++ b/surveil/tests/api/controllers/v2/status/test_hosts.py @@ -201,3 +201,62 @@ class TestStatusHosts(functionalTest.FunctionalTest): "address": "localhost"} self.assertItemsEqual(json.loads(response.body), expected) + + @httpretty.activate + def test_get_specific_host_service(self): + influx_response = json.dumps( + {"results": [ + {"series": [ + {"name": "SERVICE_STATE", + "tags": {"host_name": "ws-arbiter", + "service_description": "check-ws-arbiter"}, + "columns": ["time", + "acknowledged", + "last_check", + "last_state_change", + "output", + "state", + "state_type"], + "values":[ + ["2015-04-23T21:12:11Z", + 0, + 1.429823531e+09, + 1.42982353221745e+09, + "TCP OK - 0.000 second response time on port 7760", + 0, + "HARD"], + ["2015-04-23T21:17:11Z", + 0, + 1.429823831e+09, + 1.42982353221745e+09, + "TCP OK - 0.000 second response time on port 7760", + 0, + "HARD"], + ["2015-04-23T21:22:10Z", + 0, + 1.42982413e+09, + 1.42982353221745e+09, + "TCP OK - 0.000 second response time on port 7760", + 0, + "HARD"]]}]}]} + ) + + httpretty.register_uri(httpretty.GET, + "http://influxdb:8086/query", + body=influx_response) + + response = self.app.get( + "/v2/status/hosts/ws-arbiter/services/check-ws-arbiter" + ) + + expected = {'description': 'check-ws-arbiter', + 'last_state_change': 1429823532, + 'acknowledged': 0, + 'plugin_output': ('TCP OK - 0.000 second ' + 'response time on port 7760'), + 'last_check': 1429823531, + 'state': 0, + 'host_name': 'ws-arbiter', + 'service_description': 'check-ws-arbiter'} + + self.assertItemsEqual(json.loads(response.body), expected)