diff --git a/gnocpush/pusher.py b/gnocpush/pusher.py index 2e95ea9..253405a 100644 --- a/gnocpush/pusher.py +++ b/gnocpush/pusher.py @@ -1,7 +1,6 @@ import logging -from gnocpush.utils import sanitize_severity -from dateutil import parser +from gnocpush.utils import alertmanager_to_gnoc from globalnoc_alertmon_agent import AlertMonAgent, Alert log = logging.getLogger(__name__) @@ -18,19 +17,8 @@ def __init__(self, config): ) def push(self, alerts): - for alert in alerts: - sev = sanitize_severity(alert['labels'].get('severity', 'Unknown')) - desc = alert['annotations'].get('description', 'Unknown') - - data = { - 'node_name': alert['labels'].get('node_name', 'Unknown'), - 'device': alert['labels'].get('device'), - 'service_name': alert['labels'].get('service_name', 'Unknown'), - 'severity': sev, - 'description': desc, - 'start_time': parser.isoparse(alert['startsAt']).timestamp() - } + data = alertmanager_to_gnoc(alert) log.debug(f"Pushing alert: {data}") diff --git a/gnocpush/utils.py b/gnocpush/utils.py index fb89cf8..0376caa 100644 --- a/gnocpush/utils.py +++ b/gnocpush/utils.py @@ -2,6 +2,8 @@ import logging +from dateutil import parser + log = logging.getLogger(__name__) @@ -20,3 +22,20 @@ def sanitize_severity(severity): log.debug(f'severity: {severity} -> {s}') return s + + +def alertmanager_to_gnoc(alert): + sev = sanitize_severity(alert['labels'].get('severity', 'Unknown')) + desc = alert['annotations'].get('description', 'Unknown') + start_time = int(parser.isoparse(alert['startsAt']).timestamp()) + + data = { + 'node_name': alert['labels'].get('node_name', 'Unknown'), + 'device': alert['labels'].get('device'), + 'service_name': alert['labels'].get('service_name', 'Unknown'), + 'severity': sev, + 'description': desc, + 'start_time': start_time, + } + + return data diff --git a/pyproject.toml b/pyproject.toml index 00d182a..c9fe6bf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,14 +21,21 @@ gnocpush = "gnocpush.cli.gnocpush:main" gnocscrape = "gnocpush.cli.gnocscrape:main" [tool.flake8] -ignore = ['E221', 'E251'] +ignore = ["E221", "E251"] [tool.setuptools.packages.find] exclude = ["charts"] [tool.pytest.ini_options] minversion = "6.0" -addopts = "-q" +addopts = [ + "-q", + "--import-mode=importlib", +] testpaths = [ "tests", ] +markers = [ + "sanitize_severity", + "alertmanager_to_gnoc", +] diff --git a/tests/test_severity.py b/tests/test_severity.py deleted file mode 100644 index 5e39035..0000000 --- a/tests/test_severity.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python3 - -from gnocpush.utils import sanitize_severity - - -def test_critical(): - words = ["critical", "CRITICAL", "cRiTiCaL", "Critical"] - for word in words: - assert sanitize_severity(word) == 'Critical' - - -def test_major(): - words = ["major", "MAJOR", "mAjOr", "Major"] - for word in words: - assert sanitize_severity(word) == 'Major' - - -def test_minor(): - words = ["minor", "MINOR", "mInOr", "Minor"] - for word in words: - assert sanitize_severity(word) == 'Minor' - - -def test_unknown(): - words = ["unknown", "UNKNOWN", "uNkNoWn", "Unknown", "foo", "bar", "baz"] - for word in words: - assert sanitize_severity(word) == 'Unknown' - - -def test_ok(): - words = ["ok", "OK", "oK", "Ok"] - for word in words: - assert sanitize_severity(word) == 'OK' diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..da0f45a --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 + +import pytest + +from gnocpush.utils import sanitize_severity, alertmanager_to_gnoc + + +@pytest.mark.sanitize_severity +def test_critical(): + words = ["critical", "CRITICAL", "cRiTiCaL", "Critical"] + for word in words: + assert sanitize_severity(word) == 'Critical' + + +def test_major(): + words = ["major", "MAJOR", "mAjOr", "Major"] + for word in words: + assert sanitize_severity(word) == 'Major' + + +def test_minor(): + words = ["minor", "MINOR", "mInOr", "Minor"] + for word in words: + assert sanitize_severity(word) == 'Minor' + + +def test_unknown(): + words = [ + "unknown", + "UNKNOWN", + "uNkNoWn", + "Unknown", + "foo", + "bar", + "baz", + ] + for word in words: + assert sanitize_severity(word) == 'Unknown' + + +def test_ok(): + words = ["ok", "OK", "oK", "Ok"] + for word in words: + assert sanitize_severity(word) == 'OK' + + +@pytest.mark.alertmanager_to_gnoc +def test_alertmanager_to_gnoc(): + alertmanager_alert = { + "status": "firing", + "labels": { + "alertname": "bogus_critical", + "device": "faux", + "gnoc": "true", + "ifDescr": "Ethernet26", + "ifIndex": "26", + "ifName": "Ethernet26", + "instance": "bdc-b05-lf1", + "job": "snmp-network", + "node_name": "bogus_critical", + "prom": "dev/ruka", + "prometheus": "kube-prometheus-stack/kube-prometheus-stack-prometheus", # noqa + "service_name": "bogons", + "severity": "Critical", + "site": "dev" + }, + "annotations": { + "description": "Bogus Critical alert" + }, + "startsAt": "2024-05-06T03:09:33.464Z", + "endsAt": "0001-01-01T00:00:00Z", + "generatorURL": "https://ruka.example.org/graph?g0.expr=ifOperStatus%7BifName%3D%22Ethernet26%22%2Cinstance%3D%22bdc-b05-lf1%22%7D+%21%3D+1&g0.tab=1", # noqa + "fingerprint": "b6b655ae6855c5ae" + } + + gnoc_alert = { + 'node_name': 'bogus_critical', + 'device': 'faux', + 'service_name': 'bogons', + 'severity': 'Critical', + 'description': 'Bogus Critical alert', + 'start_time': 1714964973, + } + + assert alertmanager_to_gnoc(alertmanager_alert) == gnoc_alert