diff --git a/doc/source/tutorials/index.rst b/doc/source/tutorials/index.rst index c1b9128..5f3e794 100644 --- a/doc/source/tutorials/index.rst +++ b/doc/source/tutorials/index.rst @@ -1,10 +1,22 @@ Tutorials ######### +Using Surveil +------------- + .. toctree:: :maxdepth: 1 getting_started + monitoring_a_host_with_passive_checks + +Contributing +------------ + +.. toctree:: + :maxdepth: 1 + developing_the_api running_the_tests monitoring_with_your_custom_plugin + diff --git a/doc/source/tutorials/monitoring_a_host_with_passive_checks.rst b/doc/source/tutorials/monitoring_a_host_with_passive_checks.rst new file mode 100644 index 0000000..f7ee78a --- /dev/null +++ b/doc/source/tutorials/monitoring_a_host_with_passive_checks.rst @@ -0,0 +1,30 @@ +Monitoring a host with passive checks +------------------------------------- + +Surveil allows for both passive monitoring and polling. In this guide, we will be creating a host and send passive check results. + + +0. Creating the host and service +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +With the Surveil CLI: :: + + surveil config-host-create --host_name passive_check_host --address 127.0.0.1 + surveil config-service-create --host_name passive_check_host --service_description passive_check_service --passive_checks_enabled 1 --check_command _echo --max_check_attempts 4 --check_interval 5 --retry_interval 3 --check_period "24x7" --notification_interval 30 --notification_period "24x7" --contacts admin --contact_groups admins + surveil config-reload + +1. Sending check results +~~~~~~~~~~~~~~~~~~~~~~~~ + +With the Surveil CLI: :: + + surveil status-submit-check-result --host_name passive_check_host --service_description passive_check_service --output "Hello!" --return_code 0 + + +2. Consulting the status of your host +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +With the Surveil CLI: :: + + surveil status-service-list + diff --git a/doc/source/webapi/v2/config.rst b/doc/source/webapi/v2/config.rst index 81f0898..6810c99 100644 --- a/doc/source/webapi/v2/config.rst +++ b/doc/source/webapi/v2/config.rst @@ -22,13 +22,6 @@ Hosts .. rest-controller:: surveil.api.controllers.v2.config.hosts:HostServiceSubController :webprefix: /v2/config/hosts/(host_name)/services/(service_name) -.. rest-controller:: surveil.api.controllers.v2.config.hosts:HostCheckResultsSubController - :webprefix: /v2/config/hosts/(host_name)/results - -.. rest-controller:: surveil.api.controllers.v2.config.hosts:ServiceCheckResultsSubController - :webprefix: /v2/config/hosts/(host_name)/services/(service_description)/results - - Services ======== diff --git a/doc/source/webapi/v2/status.rst b/doc/source/webapi/v2/status.rst index c53b56a..6822ca4 100644 --- a/doc/source/webapi/v2/status.rst +++ b/doc/source/webapi/v2/status.rst @@ -20,6 +20,12 @@ Hosts .. rest-controller:: surveil.api.controllers.v2.status.hosts:ConfigController :webprefix: /v2/status/hosts/(host_name)/config +.. rest-controller:: surveil.api.controllers.v2.status.hosts:HostCheckResultsSubController + :webprefix: /v2/status/hosts/(host_name)/results + +.. rest-controller:: surveil.api.controllers.v2.status.hosts:ServiceCheckResultsSubController + :webprefix: /v2/status/hosts/(host_name)/services/(service_description)/results + .. rest-controller:: surveil.api.controllers.v2.logs:LogsController :webprefix: /v2/status/hosts/(host_name)/events diff --git a/surveil/api/controllers/v2/config/hosts.py b/surveil/api/controllers/v2/config/hosts.py index d5c6a11..caaf90a 100644 --- a/surveil/api/controllers/v2/config/hosts.py +++ b/surveil/api/controllers/v2/config/hosts.py @@ -14,10 +14,8 @@ import pecan from pecan import rest -import requests import wsmeext.pecan as wsme_pecan -from surveil.api.datamodel import checkresult from surveil.api.datamodel.config import host from surveil.api.datamodel.config import service from surveil.api.handlers.config import host_handler @@ -25,30 +23,7 @@ from surveil.api.handlers.config import service_handler from surveil.common import util -class ServiceCheckResultsSubController(rest.RestController): - - @util.policy_enforce(['authenticated']) - @wsme_pecan.wsexpose(body=checkresult.CheckResult, status_code=204) - def post(self, data): - """Submit a new check result. - - :param data: a check result within the request body. - """ - result = data.as_dict() - result['host_name'] = pecan.request.context['host_name'] - - result['service_description'] = pecan.request.context[ - 'service_description' - ] - - requests.post( - pecan.request.ws_arbiter_url + "/push_check_result", - data=result - ) - - class HostServiceSubController(rest.RestController): - results = ServiceCheckResultsSubController() def __init__(self, service_description): pecan.request.context['service_description'] = service_description @@ -93,27 +68,8 @@ class HostServicesSubController(rest.RestController): return HostServiceSubController(service_description), remainder -class HostCheckResultsSubController(rest.RestController): - - @util.policy_enforce(['authenticated']) - @wsme_pecan.wsexpose(body=checkresult.CheckResult, status_code=204) - def post(self, data): - """Submit a new check result. - - :param data: a check result within the request body. - """ - result = data.as_dict() - result['host_name'] = pecan.request.context['host_name'] - - requests.post( - pecan.request.ws_arbiter_url + "/push_check_result", - data=result - ) - - class HostSubController(rest.RestController): services = HostServicesSubController() - results = HostCheckResultsSubController() class HostController(rest.RestController): diff --git a/surveil/api/controllers/v2/status/hosts.py b/surveil/api/controllers/v2/status/hosts.py index 6f6e031..e2f6a7e 100644 --- a/surveil/api/controllers/v2/status/hosts.py +++ b/surveil/api/controllers/v2/status/hosts.py @@ -14,9 +14,11 @@ import pecan from pecan import rest +import requests import wsmeext.pecan as wsme_pecan from surveil.api.controllers.v2 import logs +from surveil.api.datamodel import checkresult from surveil.api.datamodel.status import live_host from surveil.api.datamodel.status import live_query from surveil.api.datamodel.status import live_service @@ -100,9 +102,50 @@ class HostMetricsController(rest.RestController): return HostMetricController(metric_name), remainder +class HostCheckResultsSubController(rest.RestController): + + @util.policy_enforce(['authenticated']) + @wsme_pecan.wsexpose(body=checkresult.CheckResult, status_code=204) + def post(self, data): + """Submit a new check result. + + :param data: a check result within the request body. + """ + result = data.as_dict() + result['host_name'] = pecan.request.context['host_name'] + + requests.post( + pecan.request.ws_arbiter_url + "/push_check_result", + data=result + ) + + +class ServiceCheckResultsSubController(rest.RestController): + + @util.policy_enforce(['authenticated']) + @wsme_pecan.wsexpose(body=checkresult.CheckResult, status_code=204) + def post(self, data): + """Submit a new check result. + + :param data: a check result within the request body. + """ + result = data.as_dict() + result['host_name'] = pecan.request.context['host_name'] + + result['service_description'] = pecan.request.context[ + 'service_name' + ] + + requests.post( + pecan.request.ws_arbiter_url + "/push_check_result", + data=result + ) + + class HostServiceController(rest.RestController): metrics = HostServiceMetricsController() + results = ServiceCheckResultsSubController() def __init__(self, service_name): pecan.request.context['service_name'] = service_name @@ -194,6 +237,7 @@ class HostController(rest.RestController): # config = config.ConfigController() events = logs.LogsController() metrics = HostMetricsController() + results = HostCheckResultsSubController() def __init__(self, host_name): pecan.request.context['host_name'] = host_name @@ -205,4 +249,4 @@ class HostController(rest.RestController): """Returns a specific host.""" handler = live_host_handler.HostHandler(pecan.request) host = handler.get(self.host_name) - return host \ No newline at end of file + return host diff --git a/surveil/api/datamodel/config/service.py b/surveil/api/datamodel/config/service.py index bbaa37b..67dd045 100644 --- a/surveil/api/datamodel/config/service.py +++ b/surveil/api/datamodel/config/service.py @@ -23,23 +23,25 @@ class Service(types.Base): service_description = wsme.wsattr(wtypes.text, mandatory=True) - check_command = wsme.wsattr(wtypes.text, mandatory=True) + check_command = wsme.wsattr(wtypes.text, mandatory=False) - max_check_attempts = wsme.wsattr(int, mandatory=True) + max_check_attempts = wsme.wsattr(int, mandatory=False) - check_interval = wsme.wsattr(int, mandatory=True) + check_interval = wsme.wsattr(int, mandatory=False) - retry_interval = wsme.wsattr(int, mandatory=True) + retry_interval = wsme.wsattr(int, mandatory=False) - check_period = wsme.wsattr(wtypes.text, mandatory=True) + check_period = wsme.wsattr(wtypes.text, mandatory=False) - notification_interval = wsme.wsattr(int, mandatory=True) + notification_interval = wsme.wsattr(int, mandatory=False) - notification_period = wsme.wsattr(wtypes.text, mandatory=True) + notification_period = wsme.wsattr(wtypes.text, mandatory=False) - contacts = wsme.wsattr(wtypes.text, mandatory=True) + contacts = wsme.wsattr(wtypes.text, mandatory=False) - contact_groups = wsme.wsattr(wtypes.text, mandatory=True) + contact_groups = wsme.wsattr(wtypes.text, mandatory=False) + + passive_checks_enabled = wsme.wsattr(wtypes.text, mandatory=False) @classmethod def sample(cls): @@ -55,4 +57,5 @@ class Service(types.Base): notification_period="24x7", contacts="surveil-ptl,surveil-bob", contact_groups="linux-admins", + passive_checks_enabled='1', ) diff --git a/surveil/tests/api/controllers/v2/config/test_hosts.py b/surveil/tests/api/controllers/v2/config/test_hosts.py index 200a12e..cdaa93f 100644 --- a/surveil/tests/api/controllers/v2/config/test_hosts.py +++ b/surveil/tests/api/controllers/v2/config/test_hosts.py @@ -15,9 +15,6 @@ import copy import json -import requests_mock -from six.moves import urllib_parse - from surveil.api.datamodel.config import host from surveil.api.datamodel.config import service from surveil.tests.api import functionalTest @@ -271,57 +268,3 @@ class TestHostController(functionalTest.FunctionalTest): in self.mongoconnection.shinken.services.find()] self.assertEqual(0, len(mongo_services)) - - def test_submit_service_result(self): - with requests_mock.Mocker() as m: - m.register_uri(requests_mock.POST, - self.ws_arbiter_url + "/push_check_result") - - check_result = { - "return_code": "0", - "output": "TEST OUTPUT", - "time_stamp": "1409149234" - } - - response = self.post_json( - "/v2/config/hosts/bogus-router/services/" + - "service-example/results", - params=check_result - ) - - self.assertEqual(response.status_int, 204) - self.assertEqual( - urllib_parse.parse_qs(m.last_request.body), - { - u'output': [u'TEST OUTPUT'], - u'return_code': [u'0'], - u'service_description': [u'service-example'], - u'host_name': [u'bogus-router'], - u'time_stamp': [u'1409149234'] - } - ) - - def test_submit_host_result(self): - with requests_mock.Mocker() as m: - m.register_uri(requests_mock.POST, - self.ws_arbiter_url + "/push_check_result") - - check_result = { - "return_code": "0", - "output": "TEST OUTPUT", - "time_stamp": "1409149234" - } - - response = self.post_json("/v2/config/hosts/bogus-router/results", - params=check_result) - - self.assertEqual(response.status_int, 204) - self.assertEqual( - urllib_parse.parse_qs(m.last_request.body), - { - u'output': [u'TEST OUTPUT'], - u'return_code': [u'0'], - u'host_name': [u'bogus-router'], - u'time_stamp': [u'1409149234'] - } - ) diff --git a/surveil/tests/api/controllers/v2/status/test_hosts.py b/surveil/tests/api/controllers/v2/status/test_hosts.py index f36f334..7c4112d 100644 --- a/surveil/tests/api/controllers/v2/status/test_hosts.py +++ b/surveil/tests/api/controllers/v2/status/test_hosts.py @@ -15,6 +15,9 @@ import copy import json +import requests_mock +from six.moves import urllib_parse + from surveil.tests.api import functionalTest @@ -197,3 +200,57 @@ class TestStatusHosts(functionalTest.FunctionalTest): 'service_description': 'check-ws-arbiter'} self.assert_count_equal_backport(json.loads(response.body.decode()), expected) + + def test_submit_service_result(self): + with requests_mock.Mocker() as m: + m.register_uri(requests_mock.POST, + self.ws_arbiter_url + "/push_check_result") + + check_result = { + "return_code": "0", + "output": "TEST OUTPUT", + "time_stamp": "1409149234" + } + + response = self.post_json( + "/v2/status/hosts/bogus-router/services/" + + "service-example/results", + params=check_result + ) + + self.assertEqual(response.status_int, 204) + self.assertEqual( + urllib_parse.parse_qs(m.last_request.body), + { + u'output': [u'TEST OUTPUT'], + u'return_code': [u'0'], + u'service_description': [u'service-example'], + u'host_name': [u'bogus-router'], + u'time_stamp': [u'1409149234'] + } + ) + + def test_submit_host_result(self): + with requests_mock.Mocker() as m: + m.register_uri(requests_mock.POST, + self.ws_arbiter_url + "/push_check_result") + + check_result = { + "return_code": "0", + "output": "TEST OUTPUT", + "time_stamp": "1409149234" + } + + response = self.post_json("/v2/status/hosts/bogus-router/results", + params=check_result) + + self.assertEqual(response.status_int, 204) + self.assertEqual( + urllib_parse.parse_qs(m.last_request.body), + { + u'output': [u'TEST OUTPUT'], + u'return_code': [u'0'], + u'host_name': [u'bogus-router'], + u'time_stamp': [u'1409149234'] + } + )