From 454698ff54e6df0c0003f54647af24a1ab3ad8c3 Mon Sep 17 00:00:00 2001 From: Muhamad Najjar Date: Thu, 2 Aug 2018 10:11:16 +0000 Subject: [PATCH] determine instance id from instance ip in Prometheus datasource Change-Id: Ib3149d00d63aa67e76dde6fd14ec3d07b87f75e5 --- vitrage/datasources/prometheus/driver.py | 29 +++++++++++++++---- vitrage/datasources/prometheus/properties.py | 1 + vitrage/datasources/prometheus/transformer.py | 7 ++--- .../prometheus/test_prometheus_driver.py | 20 ++++++++----- 4 files changed, 41 insertions(+), 16 deletions(-) diff --git a/vitrage/datasources/prometheus/driver.py b/vitrage/datasources/prometheus/driver.py index 8d78e9d88..cefcfbbc4 100644 --- a/vitrage/datasources/prometheus/driver.py +++ b/vitrage/datasources/prometheus/driver.py @@ -28,6 +28,7 @@ from vitrage.datasources.prometheus.properties import PrometheusLabels \ as PLabels from vitrage.datasources.prometheus.properties import PrometheusProperties \ as PProps +from vitrage import os_clients LOG = log.getLogger(__name__) @@ -41,6 +42,13 @@ class PrometheusDriver(AlarmDriverBase): super(PrometheusDriver, self).__init__() self.conf = conf self._client = None + self._nova_client = None + + @property + def nova_client(self): + if not self._nova_client: + self._nova_client = os_clients.nova_client(self.conf) + return self._nova_client def _vitrage_type(self): return PROMETHEUS_DATASOURCE @@ -137,13 +145,24 @@ class PrometheusDriver(AlarmDriverBase): for alarm in details.get(PProps.ALERTS, []): alarm[DSProps.EVENT_TYPE] = event_type alarm[PProps.STATUS] = details[PProps.STATUS] + instance_id = get_label(alarm, PLabels.INSTANCE) + if ':' in instance_id: + instance_id = instance_id[:instance_id.index(':')] + + # The 'instance' label can be instance ip or hostname. + # we try to fetch the instance id from nova by its ip, + # and if not found we leave it as it is. + nova_instance = self.nova_client.servers.list( + search_opts={'all_tenants': 1, 'ip': instance_id}) + if nova_instance: + instance_id = nova_instance[0].id + alarm[PLabels.INSTANCE_ID] = instance_id old_alarm = self._old_alarm(alarm) - alarm = \ - self._filter_and_cache_alarm(alarm, - old_alarm, - self._filter_get_erroneous, - get_alarm_update_time(alarm)) + alarm = self._filter_and_cache_alarm( + alarm, old_alarm, + self._filter_get_erroneous, + get_alarm_update_time(alarm)) if alarm: alarms.append(alarm) diff --git a/vitrage/datasources/prometheus/properties.py b/vitrage/datasources/prometheus/properties.py index c4c31be81..228df5f61 100644 --- a/vitrage/datasources/prometheus/properties.py +++ b/vitrage/datasources/prometheus/properties.py @@ -37,6 +37,7 @@ class PrometheusAnnotations(object): class PrometheusLabels(object): SEVERITY = 'severity' INSTANCE = 'instance' + INSTANCE_ID = 'instance_id' ALERT_NAME = 'alertname' # A (unique?) name of the alert diff --git a/vitrage/datasources/prometheus/transformer.py b/vitrage/datasources/prometheus/transformer.py index 8ed117896..75dba8761 100644 --- a/vitrage/datasources/prometheus/transformer.py +++ b/vitrage/datasources/prometheus/transformer.py @@ -86,8 +86,7 @@ class PrometheusTransformer(AlarmTransformerBase): @staticmethod def get_enrich_query(event): LOG.debug('event for enrich query: %s', str(event)) - hostname = get_label(event, PLabels.INSTANCE) - if not hostname: + instance_id = event.get(PLabels.INSTANCE_ID) + if not instance_id: return None - hostname = hostname[:hostname.index(':')] - return {VProps.ID: hostname} + return {VProps.ID: instance_id} diff --git a/vitrage/tests/unit/datasources/prometheus/test_prometheus_driver.py b/vitrage/tests/unit/datasources/prometheus/test_prometheus_driver.py index 664f83aa8..5ba76d107 100644 --- a/vitrage/tests/unit/datasources/prometheus/test_prometheus_driver.py +++ b/vitrage/tests/unit/datasources/prometheus/test_prometheus_driver.py @@ -12,6 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. +from mock import mock from oslo_config import cfg from testtools import matchers @@ -34,15 +35,20 @@ class PrometheusDriverTest(base.BaseTest): cls.conf.register_opts(cls.OPTS, group=PROMETHEUS_DATASOURCE) def test_enrich_event(self): - # Test setup - driver = PrometheusDriver(self.conf) - event = self._generate_event() + with (mock.patch('vitrage.datasources.prometheus.driver.' + 'PrometheusDriver.nova_client')) as mock_nova_client: - # Enrich event - created_events = driver.enrich_event(event, PROMETHEUS_EVENT_TYPE) + mock_nova_client.servers.list.return_value = None - # Test assertions - self._assert_event_equal(created_events, PROMETHEUS_EVENT_TYPE) + # Test setup + driver = PrometheusDriver(self.conf) + event = self._generate_event() + + # Enrich event + created_events = driver.enrich_event(event, PROMETHEUS_EVENT_TYPE) + + # Test assertions + self._assert_event_equal(created_events, PROMETHEUS_EVENT_TYPE) @staticmethod def _generate_event():