Skip to content
Snippets Groups Projects
Commit c3dd9357 authored by Pelle Koster's avatar Pelle Koster
Browse files

Feature/POL1-813 Provision error report as a daily sensu check

parent f0ab904e
No related branches found
No related tags found
No related merge requests found
...@@ -47,6 +47,10 @@ _DEFAULT_CONFIG = { ...@@ -47,6 +47,10 @@ _DEFAULT_CONFIG = {
'measurement': 'multicast', 'measurement': 'multicast',
'command': '{script} --inventory http://localhost:18080' 'command': '{script} --inventory http://localhost:18080'
' --measurement {measurement} --hostname {hostname}' ' --measurement {measurement} --hostname {hostname}'
},
'interface-error-report': {
'script': '/home/brian_checks/venv/report-interface-errors',
'config': '/home/brian_checks/conf/report-interface-errors.config.json'
} }
}, },
'statedir': '/tmp/', 'statedir': '/tmp/',
...@@ -81,6 +85,15 @@ CONFIG_SCHEMA = { ...@@ -81,6 +85,15 @@ CONFIG_SCHEMA = {
'required': ['script', 'config', 'command'], 'required': ['script', 'config', 'command'],
'additionalProperties': False 'additionalProperties': False
}, },
'interface-error-report': {
'type': 'object',
'properties': {
'script': {'type': 'string'},
'config': {'type': 'string'},
},
'required': ['script', 'config'],
'additionalProperties': False
},
'sensu': { 'sensu': {
'type': 'object', 'type': 'object',
'properties': { 'properties': {
...@@ -98,6 +111,9 @@ CONFIG_SCHEMA = { ...@@ -98,6 +111,9 @@ CONFIG_SCHEMA = {
{'$ref': '#/definitions/influx-check'}, {'$ref': '#/definitions/influx-check'},
'eumetsat-multicast-check': 'eumetsat-multicast-check':
{'$ref': '#/definitions/influx-check'}, {'$ref': '#/definitions/influx-check'},
'interface-error-report': {
'$ref': '#/definitions/interface-error-report'
}
}, },
'required': [ 'required': [
'api-base', 'api-key', 'api-base', 'api-key',
......
from brian_polling_manager import sensu
ERROR_REPORT_CHECK_NAME = "interface-error-report"
def load_checks(sensu_params, filter_by):
checks = filter(filter_by, sensu.load_all_checks(sensu_params))
return {c["metadata"]["name"]: c for c in checks}
def load_error_report_checks(sensu_params):
return load_checks(
sensu_params, lambda c: c["metadata"]["name"] == ERROR_REPORT_CHECK_NAME
)
class ErrorReportCheck(sensu.AbstractCheck):
INTERVAL_S = 3600 * 24 # daily
METRIC_FORMAT = ""
METRIC_HANDLERS = None
COMMAND = "{script} --config {config}"
def __init__(self, ifc_check_params):
super().__init__()
self.ifc_check_params = ifc_check_params
@sensu.AbstractCheck.name.getter
def name(self):
return ERROR_REPORT_CHECK_NAME
@sensu.AbstractCheck.command.getter
def command(self):
return self.COMMAND.format(**self.ifc_check_params)
@sensu.AbstractCheck.proxy_entity_name.getter
def proxy_entity_name(self):
return ERROR_REPORT_CHECK_NAME
def refresh(sensu_params):
return sensu.refresh(
sensu_params,
[ErrorReportCheck(sensu_params["interface-error-report"])],
load_error_report_checks(sensu_params),
)
...@@ -29,7 +29,7 @@ import click ...@@ -29,7 +29,7 @@ import click
import jsonschema import jsonschema
from statsd import StatsClient from statsd import StatsClient
from brian_polling_manager import inventory, configuration, \ from brian_polling_manager import error_report, inventory, configuration, \
interfaces, gws_direct, gws_indirect, eumetsat_multicast, sensu interfaces, gws_direct, gws_indirect, eumetsat_multicast, sensu
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -56,6 +56,7 @@ REFRESH_RESULT_SCHEMA = { ...@@ -56,6 +56,7 @@ REFRESH_RESULT_SCHEMA = {
'gws_direct': {'$ref': '#/definitions/refresh-result'}, 'gws_direct': {'$ref': '#/definitions/refresh-result'},
'gws_indirect': {'$ref': '#/definitions/refresh-result'}, 'gws_indirect': {'$ref': '#/definitions/refresh-result'},
'eumetsat_multicast': {'$ref': '#/definitions/refresh-result'}, 'eumetsat_multicast': {'$ref': '#/definitions/refresh-result'},
'interface_error_report': {'$ref': '#/definitions/refresh-result'},
}, },
'required': ['interfaces'], 'required': ['interfaces'],
'additionalProperties': False 'additionalProperties': False
...@@ -96,6 +97,7 @@ def refresh(config, force=False): ...@@ -96,6 +97,7 @@ def refresh(config, force=False):
config['sensu'], state.gws_indirect), config['sensu'], state.gws_indirect),
'eumetsat_multicast': eumetsat_multicast.refresh( 'eumetsat_multicast': eumetsat_multicast.refresh(
config['sensu'], state.eumetsat_multicast), config['sensu'], state.eumetsat_multicast),
'interface_error_report': error_report.check.refresh(config['sensu'])
} }
jsonschema.validate(result, REFRESH_RESULT_SCHEMA) # sanity jsonschema.validate(result, REFRESH_RESULT_SCHEMA) # sanity
......
...@@ -212,29 +212,21 @@ class AbstractCheck(object): ...@@ -212,29 +212,21 @@ class AbstractCheck(object):
@staticmethod @staticmethod
def match_check_dicts(a, b) -> bool: def match_check_dicts(a, b) -> bool:
if a["publish"] != b["publish"]: return (
return False a["publish"] == b["publish"]
if a["command"] != b["command"]: and a["command"] == b["command"]
return False and a["interval"] == b["interval"]
if a["interval"] != b["interval"]: and a["proxy_entity_name"] == b["proxy_entity_name"]
return False and a["round_robin"] == b["round_robin"]
if a["proxy_entity_name"] != b["proxy_entity_name"]: and a["output_metric_format"] == b["output_metric_format"]
return False and set(a["subscriptions"] or []) == set(b["subscriptions"] or [])
if a["round_robin"] != b["round_robin"]: and set(a["output_metric_handlers"] or [])
return False == set(b["output_metric_handlers"] or [])
if a["output_metric_format"] != b["output_metric_format"]: and a["metadata"]["name"] == b["metadata"]["name"]
return False and a["metadata"]["namespace"] == b["metadata"]["namespace"]
if sorted(a["subscriptions"] or []) != sorted(b["subscriptions"] or []): and a["interval"] == b["interval"]
return False and a["proxy_entity_name"] == b["proxy_entity_name"]
if sorted(a["output_metric_handlers"] or []) != sorted( )
b["output_metric_handlers"] or []
):
return False
if a["metadata"]["name"] != b["metadata"]["name"]:
return False
if a["metadata"]["namespace"] != b["metadata"]["namespace"]:
return False
return True
def refresh(sensu_params, required_checks, current_checks): def refresh(sensu_params, required_checks, current_checks):
......
...@@ -63,6 +63,10 @@ def config(): ...@@ -63,6 +63,10 @@ def config():
" --measurement {measurement}" " --measurement {measurement}"
" --hostname {hostname}", " --hostname {hostname}",
}, },
"interface-error-report": {
"script": "/path/to/report-interface-errors",
"config": "/path/to/config",
},
}, },
"statedir": state_dir_name, "statedir": state_dir_name,
"statsd": {"hostname": "localhost", "port": 11119, "prefix": "zzzzz"}, "statsd": {"hostname": "localhost", "port": 11119, "prefix": "zzzzz"},
......
...@@ -179,6 +179,32 @@ ...@@ -179,6 +179,32 @@
"created_by": "admin" "created_by": "admin"
}, },
"secrets": null "secrets": null
},
{
"command": "/path/to/report-interface-errors --config /path/to/config",
"handlers": [],
"high_flap_threshold": 0,
"interval": 300,
"low_flap_threshold": 0,
"publish": false,
"runtime_assets": null,
"subscriptions": [],
"proxy_entity_name": "error-report",
"check_hooks": null,
"stdin": false,
"subdue": null,
"ttl": 0,
"timeout": 0,
"round_robin": true,
"output_metric_format": "",
"output_metric_handlers": [],
"env_vars": null,
"metadata": {
"name": "interface-error-report",
"namespace": "default",
"created_by": "admin"
},
"secrets": null
} }
] ]
from brian_polling_manager import sensu
from brian_polling_manager.error_report.check import ErrorReportCheck, refresh
import pytest
import responses
@pytest.fixture
def config():
return {
"api-base": [
"https://bogus-sensu01.xxx.yyy:12345",
"https://bogus-sensu02.xxx.yyy:12345",
"https://bogus-sensu03.xxx.yyy:12345",
],
"api-key": "abc-sensu-key-blah-blah",
"interface-error-report": {
"script": "/path/to/report-interface-errors",
"config": "/path/to/config",
},
}
def test_error_report_check(config):
check = ErrorReportCheck(config["interface-error-report"]).to_dict()
assert check["command"] == (
"/path/to/report-interface-errors --config /path/to/config"
)
assert check["proxy_entity_name"] == "interface-error-report"
assert check["metadata"]["name"] == "interface-error-report"
assert check["output_metric_format"] == ""
assert check["output_metric_handlers"] == []
@responses.activate
def test_error_report_refresh(config, mocked_sensu, mocked_inventory):
result = refresh(config)
assert result == {"checks": 1, "input": 1, "created": 0, "updated": 1, "deleted": 0}
sensu.clear_cached_values()
result = refresh(config)
assert result == {"checks": 1, "input": 1, "created": 0, "updated": 0, "deleted": 0}
...@@ -12,8 +12,10 @@ from brian_polling_manager.main import REFRESH_RESULT_SCHEMA ...@@ -12,8 +12,10 @@ from brian_polling_manager.main import REFRESH_RESULT_SCHEMA
@pytest.fixture @pytest.fixture
def client(config_filename, mocked_sensu, mocked_inventory): def client(config_filename, mocked_sensu, mocked_inventory):
os.environ['CONFIG_FILENAME'] = config_filename os.environ["CONFIG_FILENAME"] = config_filename
with brian_polling_manager.create_app().test_client() as c: app = brian_polling_manager.create_app()
app.testing = True
with app.test_client() as c:
yield c yield c
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment