diff --git a/doc/source/zabbix_vitrage.rst b/doc/source/zabbix_vitrage.rst index ccd0ff33e..2bcffa574 100644 --- a/doc/source/zabbix_vitrage.rst +++ b/doc/source/zabbix_vitrage.rst @@ -48,7 +48,7 @@ To forward zabbix events to Vitrage a new media script needs to be created and a | host={HOST.NAME1} | hostid={HOST.ID1} | hostip={HOST.IP1} - | id={TRIGGER.ID} + | triggerid={TRIGGER.ID} | description={TRIGGER.NAME} | rawtext={TRIGGER.NAME.ORIG} | expression={TRIGGER.EXPRESSION} diff --git a/vitrage/datasources/aodh/driver.py b/vitrage/datasources/aodh/driver.py index d3691d344..d27cb94bf 100644 --- a/vitrage/datasources/aodh/driver.py +++ b/vitrage/datasources/aodh/driver.py @@ -113,10 +113,6 @@ class AodhDriver(AlarmDriverBase): else: LOG.warning('Unsupported Aodh alarm of type %s' % alarm_type) - @staticmethod - def get_update_method(conf): - return conf[AODH_DATASOURCE].update_method - def _parse_query(data, key): query_fields = data.get(AodhProps.QUERY, {}) diff --git a/vitrage/datasources/cinder/volume/driver.py b/vitrage/datasources/cinder/volume/driver.py index 0325c71e9..2bd1d51c4 100644 --- a/vitrage/datasources/cinder/volume/driver.py +++ b/vitrage/datasources/cinder/volume/driver.py @@ -66,7 +66,3 @@ class CinderVolumeDriver(DriverBase): 'volume.detach.end', 'volume.delete.start', 'volume.delete.end'] - - @staticmethod - def get_update_method(conf): - return conf[CINDER_VOLUME_DATASOURCE].update_method diff --git a/vitrage/datasources/driver_base.py b/vitrage/datasources/driver_base.py index 9a71d40db..7a5221b8d 100644 --- a/vitrage/datasources/driver_base.py +++ b/vitrage/datasources/driver_base.py @@ -113,20 +113,3 @@ class DriverBase(object): """ return [] - - @staticmethod - @abc.abstractmethod - def get_update_method(conf): - """Return the update method for this driver - - update methods available are: - None: updates only via overall snapshots - Pull: updates every [changes_interval] seconds - Push: updates by getting notifications from the datasource itself - - :param conf: the datasource's configuration - :return: the update method of the datasource - :rtype: str - """ - - return None diff --git a/vitrage/datasources/listener_service.py b/vitrage/datasources/listener_service.py index 04dbdaeb0..a12fbcdfe 100644 --- a/vitrage/datasources/listener_service.py +++ b/vitrage/datasources/listener_service.py @@ -64,8 +64,8 @@ class ListenerService(os_service.Service): @staticmethod def _get_push_drivers(drivers, conf): - return (driver for driver in drivers.values() - if driver.get_update_method(conf).lower() == UpdateMethod.PUSH) + return (driver_cls for datasource, driver_cls in drivers.items() + if conf[datasource].update_method.lower() == UpdateMethod.PUSH) def _get_topic_listener(self, conf, topic, callback): # Create a listener for each topic diff --git a/vitrage/datasources/nagios/driver.py b/vitrage/datasources/nagios/driver.py index f263fefe3..a64889213 100644 --- a/vitrage/datasources/nagios/driver.py +++ b/vitrage/datasources/nagios/driver.py @@ -34,7 +34,7 @@ LOG = log.getLogger(__name__) class NagiosDriver(AlarmDriverBase): - ServiceKey = namedtuple('ServiceKey', ['host_name', 'service']) + ServiceKey = namedtuple('ServiceKey', ['hostname', 'service']) def __init__(self, conf): super(NagiosDriver, self).__init__() @@ -45,7 +45,7 @@ class NagiosDriver(AlarmDriverBase): return NAGIOS_DATASOURCE def _alarm_key(self, alarm): - return self.ServiceKey(host_name=alarm[NagiosProps.RESOURCE_NAME], + return self.ServiceKey(hostname=alarm[NagiosProps.RESOURCE_NAME], service=alarm[NagiosProps.SERVICE]) def _get_alarms(self): @@ -103,7 +103,3 @@ class NagiosDriver(AlarmDriverBase): def _is_valid(self, alarm): return alarm[NagiosProps.RESOURCE_TYPE] is not None and \ alarm[NagiosProps.RESOURCE_NAME] is not None - - @staticmethod - def get_update_method(conf): - return conf[NAGIOS_DATASOURCE].update_method diff --git a/vitrage/datasources/neutron/network/driver.py b/vitrage/datasources/neutron/network/driver.py index 598154ca1..8fecdb64e 100644 --- a/vitrage/datasources/neutron/network/driver.py +++ b/vitrage/datasources/neutron/network/driver.py @@ -21,10 +21,6 @@ from vitrage.datasources.neutron.network import NEUTRON_NETWORK_DATASOURCE # noinspection PyAbstractClass class NetworkDriver(NeutronBase): - @staticmethod - def get_update_method(conf): - return conf[NEUTRON_NETWORK_DATASOURCE].update_method - @staticmethod def get_event_types(conf): return ['network.create.end', diff --git a/vitrage/datasources/neutron/port/driver.py b/vitrage/datasources/neutron/port/driver.py index c0b9a403c..aceccb846 100644 --- a/vitrage/datasources/neutron/port/driver.py +++ b/vitrage/datasources/neutron/port/driver.py @@ -21,10 +21,6 @@ from vitrage.datasources.neutron.port import NEUTRON_PORT_DATASOURCE # noinspection PyAbstractClass class PortDriver(NeutronBase): - @staticmethod - def get_update_method(conf): - return conf[NEUTRON_PORT_DATASOURCE].update_method - @staticmethod def get_event_types(conf): return ['port.create.end', diff --git a/vitrage/datasources/nova/host/driver.py b/vitrage/datasources/nova/host/driver.py index 1c6001415..b74f92dfe 100644 --- a/vitrage/datasources/nova/host/driver.py +++ b/vitrage/datasources/nova/host/driver.py @@ -27,10 +27,6 @@ class HostDriver(NovaDriverBase): compute_hosts.append(host_dict) return compute_hosts - @staticmethod - def get_update_method(conf): - return conf[NOVA_HOST_DATASOURCE].update_method - def get_all(self, sync_mode): return self.make_pickleable( self.filter_none_compute_hosts(self.client.hosts.list()), diff --git a/vitrage/datasources/nova/instance/driver.py b/vitrage/datasources/nova/instance/driver.py index d96a8fbec..8e2dbbe5d 100644 --- a/vitrage/datasources/nova/instance/driver.py +++ b/vitrage/datasources/nova/instance/driver.py @@ -67,7 +67,3 @@ class InstanceDriver(NovaDriverBase): 'compute.instance.volume.detach', 'compute.instance.pause.end', 'compute.instance.unpause.end'] - - @staticmethod - def get_update_method(conf): - return conf[NOVA_INSTANCE_DATASOURCE].update_method diff --git a/vitrage/datasources/nova/zone/driver.py b/vitrage/datasources/nova/zone/driver.py index cb3120324..30eea9475 100644 --- a/vitrage/datasources/nova/zone/driver.py +++ b/vitrage/datasources/nova/zone/driver.py @@ -27,10 +27,6 @@ class ZoneDriver(NovaDriverBase): zones_res.append(zone_dict) return zones_res - @staticmethod - def get_update_method(conf): - return conf[NOVA_ZONE_DATASOURCE].update_method - def get_all(self, sync_mode): return self.make_pickleable(self.filter_internal_zone( self.client.availability_zones.list()), diff --git a/vitrage/datasources/static_physical/driver.py b/vitrage/datasources/static_physical/driver.py index f27f96f3e..70d95ef1f 100644 --- a/vitrage/datasources/static_physical/driver.py +++ b/vitrage/datasources/static_physical/driver.py @@ -32,10 +32,6 @@ class StaticPhysicalDriver(DriverBase): def enrich_event(event, event_type): pass - @staticmethod - def get_update_method(conf): - return conf[STATIC_PHYSICAL_DATASOURCE].update_method - ENTITIES_SECTION = 'entities' def __init__(self, conf): diff --git a/vitrage/datasources/zabbix/auxiliary/readme b/vitrage/datasources/zabbix/auxiliary/readme index db559db5d..03a83438f 100644 --- a/vitrage/datasources/zabbix/auxiliary/readme +++ b/vitrage/datasources/zabbix/auxiliary/readme @@ -52,7 +52,7 @@ associated with a user. Follow the steps below as a Zabbix Admin user: host={HOST.NAME1} hostid={HOST.ID1} hostip={HOST.IP1} - id={TRIGGER.ID} + triggerid={TRIGGER.ID} description={TRIGGER.NAME} rawtext={TRIGGER.NAME.ORIG} expression={TRIGGER.EXPRESSION} diff --git a/vitrage/datasources/zabbix/auxiliary/zabbix_vitrage.py b/vitrage/datasources/zabbix/auxiliary/zabbix_vitrage.py index aa5e33203..fb09e6805 100644 --- a/vitrage/datasources/zabbix/auxiliary/zabbix_vitrage.py +++ b/vitrage/datasources/zabbix/auxiliary/zabbix_vitrage.py @@ -37,7 +37,7 @@ Message: host={HOST.NAME1} hostid={HOST.ID1} hostip={HOST.IP1} - id={TRIGGER.ID} + triggerid={TRIGGER.ID} description={TRIGGER.NAME} rawtext={TRIGGER.NAME.ORIG} expression={TRIGGER.EXPRESSION} diff --git a/vitrage/datasources/zabbix/driver.py b/vitrage/datasources/zabbix/driver.py index 5dacd2422..ff79cf7c0 100644 --- a/vitrage/datasources/zabbix/driver.py +++ b/vitrage/datasources/zabbix/driver.py @@ -32,7 +32,7 @@ LOG = log.getLogger(__name__) class ZabbixDriver(AlarmDriverBase): - ServiceKey = namedtuple('ServiceKey', ['host_name', 'service']) + ServiceKey = namedtuple('ServiceKey', ['hostname', 'triggerid']) conf_map = None def __init__(self, conf): @@ -47,8 +47,8 @@ class ZabbixDriver(AlarmDriverBase): return ZABBIX_DATASOURCE def _alarm_key(self, alarm): - return self.ServiceKey(host_name=alarm[ZProps.RESOURCE_NAME], - service=alarm[ZProps.DESCRIPTION]) + return self.ServiceKey(hostname=alarm[ZProps.RESOURCE_NAME], + triggerid=alarm[ZProps.TRIGGER_ID]) def _get_alarms(self): zabbix_user = self.conf.zabbix.user @@ -90,7 +90,6 @@ class ZabbixDriver(AlarmDriverBase): for trigger in triggers: trigger[ZProps.ZABBIX_RESOURCE_NAME] = host[ZProps.HOST] - trigger_id = trigger[ZProps.TRIGGER_ID] trigger[ZProps.RAWTEXT] = triggers_rawtexts[trigger_id] alarms.append(trigger) @@ -118,12 +117,7 @@ class ZabbixDriver(AlarmDriverBase): zabbix_host = alarm[ZProps.ZABBIX_RESOURCE_NAME] vitrage_host = ZabbixDriver.conf_map[zabbix_host] alarm[ZProps.RESOURCE_TYPE] = vitrage_host[ZProps.RESOURCE_TYPE] - - vitrage_host_name = vitrage_host[ZProps.RESOURCE_NAME] alarm[ZProps.RESOURCE_NAME] = vitrage_host[ZProps.RESOURCE_NAME] - alarm[ZProps.DESCRIPTION] = alarm[ZProps.DESCRIPTION].replace( - zabbix_host, - vitrage_host_name) def _is_erroneous(self, alarm): return alarm and \ @@ -138,7 +132,11 @@ class ZabbixDriver(AlarmDriverBase): return True if new_alarm[ZProps.VALUE] == TriggerValue.PROBLEM: - return new_alarm[ZProps.PRIORITY] != old_alarm[ZProps.PRIORITY] + priority_changed = \ + new_alarm[ZProps.PRIORITY] != old_alarm[ZProps.PRIORITY] + description_changed = \ + new_alarm[ZProps.DESCRIPTION] != old_alarm[ZProps.DESCRIPTION] + return priority_changed or description_changed def _is_valid(self, alarm): return alarm[ZProps.RESOURCE_TYPE] is not None and \ @@ -175,6 +173,7 @@ class ZabbixDriver(AlarmDriverBase): if ZabbixDriver.conf_map: zabbix_host = event[ZProps.HOST] + event[ZProps.ZABBIX_RESOURCE_NAME] = zabbix_host v_resource = ZabbixDriver.conf_map[zabbix_host] event[ZProps.RESOURCE_NAME] = v_resource[ZProps.RESOURCE_NAME] event[ZProps.RESOURCE_TYPE] = v_resource[ZProps.RESOURCE_TYPE] @@ -185,7 +184,3 @@ class ZabbixDriver(AlarmDriverBase): @staticmethod def get_event_types(conf): return ['zabbix.alarm.ok', 'zabbix.alarm.problem'] - - @staticmethod - def get_update_method(conf): - return conf[ZABBIX_DATASOURCE].update_method diff --git a/vitrage/datasources/zabbix/transformer.py b/vitrage/datasources/zabbix/transformer.py index b53267fcc..75df4c8cb 100644 --- a/vitrage/datasources/zabbix/transformer.py +++ b/vitrage/datasources/zabbix/transformer.py @@ -59,6 +59,11 @@ class ZabbixTransformer(AlarmTransformerBase): update_timestamp = self._format_update_timestamp(update_timestamp, sample_timestamp) + zabbix_hostname = entity_event[ZProps.ZABBIX_RESOURCE_NAME] + vitrage_hostname = entity_event[ZProps.RESOURCE_NAME] + entity_event[ZProps.DESCRIPTION] = entity_event[ZProps.DESCRIPTION]\ + .replace(zabbix_hostname, vitrage_hostname) + value = entity_event[ZProps.VALUE] entity_state = AlarmProps.INACTIVE_STATE if \ value == TriggerValue.OK else AlarmProps.ACTIVE_STATE @@ -133,11 +138,11 @@ class ZabbixTransformer(AlarmTransformerBase): def _create_entity_key(self, entity_event): sync_type = entity_event[DSProps.SYNC_TYPE] - alarm_name = entity_event[ZProps.DESCRIPTION] + alarm_id = entity_event[ZProps.TRIGGER_ID] resource_name = entity_event[ZProps.RESOURCE_NAME] return tbase.build_key(self._key_values(sync_type, resource_name, - alarm_name)) + alarm_id)) @staticmethod def _unify_time_format(entity_event): diff --git a/vitrage/tests/resources/mock_configurations/driver/driver_zabbix_snapshot_dynamic.json b/vitrage/tests/resources/mock_configurations/driver/driver_zabbix_snapshot_dynamic.json index 76ee2caa6..c52893a4e 100644 --- a/vitrage/tests/resources/mock_configurations/driver/driver_zabbix_snapshot_dynamic.json +++ b/vitrage/tests/resources/mock_configurations/driver/driver_zabbix_snapshot_dynamic.json @@ -2,8 +2,10 @@ "sync_type": "zabbix", "resource_type": "nova\\.host", "resource_name": "compute-[1-9]", + "zabbix_resource_name": "computer-[1-9]", "description": "CPU utilization|Check_MK|Uptime", "name": "CPU utilization|Check_MK|Uptime", + "triggerid": "[0-9]*", "lastchange": "1469450551", "timestamp": "2015.12.01 12:46:41", "status": "0", diff --git a/vitrage/tests/unit/datasources/nagios/mock_driver.py b/vitrage/tests/unit/datasources/nagios/mock_driver.py index 6cfbc9f66..0f2dc1282 100644 --- a/vitrage/tests/unit/datasources/nagios/mock_driver.py +++ b/vitrage/tests/unit/datasources/nagios/mock_driver.py @@ -13,7 +13,6 @@ # under the License. from vitrage.datasources.nagios.driver import NagiosDriver -from vitrage.datasources.nagios import NAGIOS_DATASOURCE from vitrage.tests.mocks import mock_driver @@ -32,10 +31,6 @@ class MockNagiosDriver(NagiosDriver): def enrich_event(event, event_type): pass - @staticmethod - def get_update_method(conf): - return conf[NAGIOS_DATASOURCE].update_method - def __init__(self, conf): super(MockNagiosDriver, self).__init__(conf) self.service_datas = None diff --git a/vitrage/tests/unit/datasources/zabbix/mock_driver.py b/vitrage/tests/unit/datasources/zabbix/mock_driver.py index ca1aea4f8..f89999d89 100644 --- a/vitrage/tests/unit/datasources/zabbix/mock_driver.py +++ b/vitrage/tests/unit/datasources/zabbix/mock_driver.py @@ -13,7 +13,6 @@ # under the License. from vitrage.datasources.zabbix.driver import ZabbixDriver -from vitrage.datasources.zabbix import ZABBIX_DATASOURCE from vitrage.tests.mocks import mock_driver @@ -32,10 +31,6 @@ class MockZabbixDriver(ZabbixDriver): def enrich_event(event, event_type): pass - @staticmethod - def get_update_method(conf): - return conf[ZABBIX_DATASOURCE].update_method - def __init__(self, conf): super(MockZabbixDriver, self).__init__(conf) self.alarm_datas = None diff --git a/vitrage/tests/unit/datasources/zabbix/test_zabbix_driver.py b/vitrage/tests/unit/datasources/zabbix/test_zabbix_driver.py index 411a0f84f..f15b7eba4 100644 --- a/vitrage/tests/unit/datasources/zabbix/test_zabbix_driver.py +++ b/vitrage/tests/unit/datasources/zabbix/test_zabbix_driver.py @@ -47,11 +47,11 @@ class ZabbixDriverTest(ZabbixBaseTest): # Test Setup zabbix_driver = MockZabbixDriver(self.conf) - alarm_data1 = self._extract_alarm_data(description='CPU 1', status='1') - alarm_data2 = self._extract_alarm_data(description='CPU 2', status='1', + alarm_data1 = self._extract_alarm_data(triggerid='1', status='1') + alarm_data2 = self._extract_alarm_data(triggerid='2', status='1', value='1') - alarm_data3 = self._extract_alarm_data(description='CPU 3', value='1') - alarm_data4 = self._extract_alarm_data(description='CPU 4') + alarm_data3 = self._extract_alarm_data(triggerid='3', value='1') + alarm_data4 = self._extract_alarm_data(triggerid='4') zabbix_driver.set_alarm_datas([alarm_data1, alarm_data2, @@ -74,7 +74,7 @@ class ZabbixDriverTest(ZabbixBaseTest): alarm_data1 = self._extract_alarm_data() alarm_data2 = self._extract_alarm_data(z_resource_name='compute-2') alarm_data3 = self._extract_alarm_data(z_resource_name='compute-2', - description='Uptime') + triggerid='2') zabbix_driver.set_alarm_datas([alarm_data1, alarm_data2, alarm_data3]) @@ -212,7 +212,7 @@ class ZabbixDriverTest(ZabbixBaseTest): alarm_data2 = self._extract_alarm_data(z_resource_name='compute-2', priority='1', value='1') alarm_data3 = self._extract_alarm_data(z_resource_name='compute-2', - description='Uptime', + triggerid='22222', priority='1') zabbix_driver.set_alarm_datas([alarm_data1, alarm_data2, alarm_data3]) @@ -269,7 +269,7 @@ class ZabbixDriverTest(ZabbixBaseTest): alarm_data2 = self._extract_alarm_data(z_resource_name='compute-2', priority='2') alarm_data3 = self._extract_alarm_data(z_resource_name='compute-2', - description='Uptime') + triggerid='2') zabbix_driver.set_alarm_datas([alarm_data1, alarm_data2, alarm_data3]) # Step action @@ -333,13 +333,13 @@ class ZabbixDriverTest(ZabbixBaseTest): self.assertIsNotNone(changed_alarms, 'No alarms returned') self.assertEqual(0, len(changed_alarms)) - # Step 5 - get changes + # Step 6 - get changes # Step setup alarm_data2 = self._extract_alarm_data(z_resource_name='compute-2', priority='4', value='1') alarm_data3 = self._extract_alarm_data(z_resource_name='compute-2', - description='Uptime', + triggerid='2', priority='4', value='1') @@ -348,7 +348,7 @@ class ZabbixDriverTest(ZabbixBaseTest): expected_alarm1 = copy.copy(alarm_data2) expected_alarm1[ZProps.RESOURCE_NAME] = 'host2' expected_alarm2 = copy.copy(expected_alarm1) - expected_alarm2[ZProps.DESCRIPTION] = 'Uptime' + expected_alarm2[ZProps.TRIGGER_ID] = '2' # Step action alarms = zabbix_driver._get_changed_alarms() @@ -365,7 +365,7 @@ class ZabbixDriverTest(ZabbixBaseTest): alarm_data1 = self._extract_alarm_data(value='1') alarm_data2 = self._extract_alarm_data(z_resource_name='compute-2') alarm_data3 = self._extract_alarm_data(z_resource_name='compute-2', - description='Uptime') + triggerid='2') # Step 1 - delete inactive alarm # Step setup @@ -425,11 +425,13 @@ class ZabbixDriverTest(ZabbixBaseTest): description='cpu', status='0', value='0', - priority='1'): + priority='1', + triggerid='0'): return {ZProps.ZABBIX_RESOURCE_NAME: z_resource_name, ZProps.DESCRIPTION: description, ZProps.STATUS: status, ZProps.VALUE: value, ZProps.PRIORITY: priority, - ZProps.RESOURCE_NAME: z_resource_name} + ZProps.RESOURCE_NAME: z_resource_name, + ZProps.TRIGGER_ID: triggerid} diff --git a/vitrage/tests/unit/datasources/zabbix/test_zabbix_transformer.py b/vitrage/tests/unit/datasources/zabbix/test_zabbix_transformer.py index aee703b96..48611358f 100644 --- a/vitrage/tests/unit/datasources/zabbix/test_zabbix_transformer.py +++ b/vitrage/tests/unit/datasources/zabbix/test_zabbix_transformer.py @@ -70,7 +70,7 @@ class ZabbixTransformerTest(base.BaseTest): self.assertEqual(event[DSProps.SYNC_TYPE], observed_key_fields[1]) self.assertEqual(event[ZabbixProps.RESOURCE_NAME], observed_key_fields[2]) - self.assertEqual(event[ZabbixProps.DESCRIPTION], + self.assertEqual(event[ZabbixProps.TRIGGER_ID], observed_key_fields[3]) def test_zabbix_alarm_transform(self): diff --git a/vitrage/tests/unit/datasources/zabbix/zabbix_base_test.py b/vitrage/tests/unit/datasources/zabbix/zabbix_base_test.py index fb7cd6b0e..47ab7a9fe 100644 --- a/vitrage/tests/unit/datasources/zabbix/zabbix_base_test.py +++ b/vitrage/tests/unit/datasources/zabbix/zabbix_base_test.py @@ -22,14 +22,14 @@ class ZabbixBaseTest(base.BaseTest): for alarm in alarms: if alarm[ZabbixProps.RESOURCE_NAME] == \ expected_serv[ZabbixProps.RESOURCE_NAME] and \ - alarm[ZabbixProps.DESCRIPTION] == \ - expected_serv[ZabbixProps.DESCRIPTION]: + alarm[ZabbixProps.TRIGGER_ID] == \ + expected_serv[ZabbixProps.TRIGGER_ID]: self._assert_expected_alarm(expected_serv, alarm) return self.fail("alarm not found: %s %s" % (expected_serv[ZabbixProps.RESOURCE_NAME], - expected_serv[ZabbixProps.DESCRIPTION])) + expected_serv[ZabbixProps.TRIGGER_ID])) def _assert_expected_alarm(self, expected_alarm, alarm): for key, value in expected_alarm.items():