From df3c4149195bd0196691b0881347b5043b176cf6 Mon Sep 17 00:00:00 2001 From: Takashi Kajinami Date: Sun, 21 Aug 2022 02:52:05 +0900 Subject: [PATCH] Remove Ceilometer datasource ... because it depends on Ceilometer API and ceilometerclient, which were already retired. Change-Id: I9f99eaf637d1250140059e17e140dda5925dd700 --- ...eilometer-datasource-81172dc7d4dfc96b.yaml | 5 + vitrage/datasources/ceilometer/__init__.py | 44 -- vitrage/datasources/ceilometer/driver.py | 387 ----------------- vitrage/datasources/ceilometer/properties.py | 54 --- vitrage/datasources/ceilometer/transformer.py | 164 -------- vitrage/os_clients.py | 16 - .../datasources/ceilometer/__init__.py | 0 .../datasources/ceilometer/test_ceilometer.py | 100 ----- .../unit/datasources/ceilometer/__init__.py | 0 .../ceilometer_transformer_base_test.py | 119 ------ .../datasources/ceilometer/mock_driver.py | 24 -- .../ceilometer/test_ceilometer_driver.py | 391 ------------------ .../ceilometer/test_ceilometer_transformer.py | 166 -------- 13 files changed, 5 insertions(+), 1465 deletions(-) create mode 100644 releasenotes/notes/remove-ceilometer-datasource-81172dc7d4dfc96b.yaml delete mode 100644 vitrage/datasources/ceilometer/__init__.py delete mode 100644 vitrage/datasources/ceilometer/driver.py delete mode 100644 vitrage/datasources/ceilometer/properties.py delete mode 100644 vitrage/datasources/ceilometer/transformer.py delete mode 100644 vitrage/tests/functional/datasources/ceilometer/__init__.py delete mode 100644 vitrage/tests/functional/datasources/ceilometer/test_ceilometer.py delete mode 100644 vitrage/tests/unit/datasources/ceilometer/__init__.py delete mode 100644 vitrage/tests/unit/datasources/ceilometer/ceilometer_transformer_base_test.py delete mode 100644 vitrage/tests/unit/datasources/ceilometer/mock_driver.py delete mode 100644 vitrage/tests/unit/datasources/ceilometer/test_ceilometer_driver.py delete mode 100644 vitrage/tests/unit/datasources/ceilometer/test_ceilometer_transformer.py diff --git a/releasenotes/notes/remove-ceilometer-datasource-81172dc7d4dfc96b.yaml b/releasenotes/notes/remove-ceilometer-datasource-81172dc7d4dfc96b.yaml new file mode 100644 index 000000000..32a5e08f8 --- /dev/null +++ b/releasenotes/notes/remove-ceilometer-datasource-81172dc7d4dfc96b.yaml @@ -0,0 +1,5 @@ +--- +upgrade: + - | + The ceilometer datasource has been removed, because it depends on + Ceilometer API which was already removed. diff --git a/vitrage/datasources/ceilometer/__init__.py b/vitrage/datasources/ceilometer/__init__.py deleted file mode 100644 index 1bfa5fcf6..000000000 --- a/vitrage/datasources/ceilometer/__init__.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2016 - Nokia -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_config import cfg -from vitrage.common.constants import DatasourceOpts as DSOpts -from vitrage.common.constants import UpdateMethod - -CEILOMETER_DATASOURCE = 'ceilometer' - -OPTS = [ - cfg.StrOpt(DSOpts.TRANSFORMER, - default='vitrage.datasources.ceilometer.' - 'transformer.CeilometerTransformer', - help='Ceilometer transformer class path', - required=True), - cfg.StrOpt(DSOpts.DRIVER, - default='vitrage.datasources.ceilometer.' - 'driver.CeilometerDriver', - help='ceilometer driver class path', - required=True), - cfg.StrOpt(DSOpts.UPDATE_METHOD, - default=UpdateMethod.PUSH, - help='None: updates only via Vitrage periodic snapshots.' - 'Pull: updates every [changes_interval] seconds.' - 'Push: updates by getting notifications from the' - ' datasource itself.', - required=True), - cfg.IntOpt(DSOpts.CHANGES_INTERVAL, - default=10, - min=10, - help='interval between checking changes' - 'in ceilometer data source'), -] diff --git a/vitrage/datasources/ceilometer/driver.py b/vitrage/datasources/ceilometer/driver.py deleted file mode 100644 index 615d8b468..000000000 --- a/vitrage/datasources/ceilometer/driver.py +++ /dev/null @@ -1,387 +0,0 @@ -# Copyright 2016 - Alcatel-Lucent -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_log import log - -from vitrage.common.constants import DatasourceAction -from vitrage.common.constants import DatasourceProperties as DSProps -from vitrage.datasources.alarm_driver_base import AlarmDriverBase -from vitrage.datasources.ceilometer import CEILOMETER_DATASOURCE -from vitrage.datasources.ceilometer.properties \ - import CeilometerEventType as CeilEventType -from vitrage.datasources.ceilometer.properties \ - import CeilometerProperties as CeilProps -from vitrage.datasources.ceilometer.properties \ - import CeilometerState as CeilState -from vitrage import os_clients -from vitrage.utils import datetime as datetime_utils - -LOG = log.getLogger(__name__) - - -class CeilometerDriver(AlarmDriverBase): - - def __init__(self): - super(CeilometerDriver, self).__init__() - self._client = None - self._init_aodh_event_actions() - self._cache_all_alarms() - - @property - def client(self): - if not self._client: - self._client = os_clients.ceilometer_client() - return self._client - - def _vitrage_type(self): - return CEILOMETER_DATASOURCE - - def _alarm_key(self, alarm): - return alarm[CeilProps.ALARM_ID] - - def _cache_all_alarms(self): - alarms = self._get_alarms() - self._filter_and_cache_alarms(alarms, - self._filter_get_valid) - - def _get_alarms(self): - try: - aodh_alarms = self.client.alarms.list() - return [self._convert_alarm(alarm) for alarm in - aodh_alarms if alarm is not None] - except Exception: - LOG.exception("Failed to get all alarms.") - return [] - - def _is_erroneous(self, alarm): - return alarm and alarm[CeilProps.STATE] == CeilState.ALARM - - def _status_changed(self, alarm1, alarm2): - return alarm1 and alarm2 and \ - not alarm1[CeilProps.STATE] == alarm2[CeilProps.STATE] - - def _is_valid(self, alarm): - return True - - @classmethod - def _convert_event_alarm(cls, alarm): - res = cls._convert_base_alarm(alarm) - res[CeilProps.EVENT_TYPE] = alarm.event_rule[CeilProps.EVENT_TYPE], - res[CeilProps.RESOURCE_ID] = _parse_query(alarm.event_rule, - CeilProps.EVENT_RESOURCE_ID) - return res - - @classmethod - def _convert_threshold_alarm(cls, alarm): - res = cls._convert_base_alarm(alarm) - res[CeilProps.STATE_TIMESTAMP] = alarm.state_timestamp - res[CeilProps.RESOURCE_ID] = _parse_query(alarm.threshold_rule, - CeilProps.RESOURCE_ID) - return res - - @classmethod - def _convert_gnocchi_resources_threshold(cls, alarm): - res = cls._convert_base_alarm_gnocchi(alarm) - if type(alarm) is not dict: - alarm = alarm.to_dict() - res[CeilProps.STATE_TIMESTAMP] = \ - alarm.get(CeilProps.STATE_TIMESTAMP) - res[CeilProps.RESOURCE_ID] = \ - alarm.get(CeilProps.GNOCCHI_RESOURCES_THRESHOLD_RULE, - {}).get(CeilProps.RESOURCE_ID) - else: - res[CeilProps.STATE_TIMESTAMP] = \ - alarm.get(CeilProps.DETAIL, {}).get(CeilProps.STATE_TIMESTAMP) - res[CeilProps.RESOURCE_ID] = \ - alarm.get(CeilProps.DETAIL, - {}).get(CeilProps.RULE, - {}).get(CeilProps.RESOURCE_ID) - return res - - @classmethod - def _convert_vitrage_alarm(cls, alarm): - res = cls._convert_base_alarm(alarm) - res[CeilProps.VITRAGE_ID] = _parse_query(alarm.event_rule, - CeilProps.VITRAGE_ID) - res[CeilProps.RESOURCE_ID] = _parse_query(alarm.event_rule, - CeilProps.RESOURCE_ID) - return res - - @staticmethod - def _convert_base_dict_alarm_gnocchi(alarm): - detail = alarm.get(CeilProps.DETAIL) - return { - CeilProps.SEVERITY: alarm.get(CeilProps.SEVERITY), - CeilProps.PROJECT_ID: alarm.get(CeilProps.PROJECT_ID), - CeilProps.TIMESTAMP: alarm.get(CeilProps.TIMESTAMP), - CeilProps.TYPE: alarm.get(CeilProps.TYPE), - CeilProps.ALARM_ID: alarm.get(CeilProps.ALARM_ID), - CeilProps.DESCRIPTION: detail.get(CeilProps.DESCRIPTION), - CeilProps.ENABLED: detail.get(CeilProps.ENABLED), - CeilProps.NAME: detail.get(CeilProps.NAME), - CeilProps.REPEAT_ACTIONS: detail.get(CeilProps.REPEAT_ACTIONS), - CeilProps.STATE: detail.get(CeilProps.STATE) - } - - @staticmethod - def _convert_base_non_dict_alarm_gnocchi(alarm): - alarm = alarm.to_dict() - return { - CeilProps.SEVERITY: alarm.get(CeilProps.SEVERITY), - CeilProps.DESCRIPTION: alarm.get(CeilProps.DESCRIPTION), - CeilProps.ENABLED: alarm.get(CeilProps.ENABLED), - CeilProps.ALARM_ID: alarm.get(CeilProps.ALARM_ID), - CeilProps.NAME: alarm.get(CeilProps.NAME), - CeilProps.PROJECT_ID: alarm.get(CeilProps.PROJECT_ID), - CeilProps.REPEAT_ACTIONS: alarm.get(CeilProps.REPEAT_ACTIONS), - CeilProps.STATE: alarm.get(CeilProps.STATE), - CeilProps.TIMESTAMP: alarm.get(CeilProps.TIMESTAMP), - CeilProps.TYPE: alarm.get(CeilProps.TYPE) - } - - @classmethod - def _convert_base_alarm_gnocchi(cls, alarm): - """distinguish between alarm received by notification (type dict) - - to alarm received by _get_alarms() (type alarm). - """ - - if type(alarm) is dict: - return cls._convert_base_dict_alarm_gnocchi(alarm) - - return cls._convert_base_non_dict_alarm_gnocchi(alarm) - - @staticmethod - def _convert_base_alarm(alarm): - return { - CeilProps.SEVERITY: alarm.severity, - CeilProps.DESCRIPTION: alarm.description, - CeilProps.ENABLED: alarm.enabled, - CeilProps.ALARM_ID: alarm.alarm_id, - CeilProps.NAME: alarm.name, - CeilProps.PROJECT_ID: alarm.project_id, - CeilProps.REPEAT_ACTIONS: alarm.repeat_actions, - CeilProps.STATE: alarm.state, - CeilProps.TIMESTAMP: alarm.timestamp, - CeilProps.TYPE: alarm.type - } - - @classmethod - def _convert_alarm(cls, alarm): - alarm_type = alarm.type - if alarm_type == CeilProps.EVENT and \ - _is_vitrage_alarm(alarm.event_rule): - return cls._convert_vitrage_alarm(alarm) - elif alarm_type == CeilProps.EVENT: - return cls._convert_event_alarm(alarm) - elif alarm_type == CeilProps.THRESHOLD: - return cls._convert_threshold_alarm(alarm) - elif alarm_type == CeilProps.GNOCCHI_RESOURCES_THRESHOLD: - return cls._convert_gnocchi_resources_threshold(alarm) - else: - LOG.warning('Unsupported Ceilometer alarm type %s' % alarm_type) - - @staticmethod - def get_event_types(): - # Add event_types to receive notifications about - return [CeilEventType.CREATION, - CeilEventType.STATE_TRANSITION, - CeilEventType.RULE_CHANGE, - CeilEventType.DELETION] - - def enrich_event(self, event, event_type): - if event_type in self.actions: - entity = self.actions[event_type](event) - else: - LOG.warning('Unsupported Ceilometer event type %s' % event_type) - return None - - # Don't need to update entity, only update the cache - if entity is None: - return None - - entity[DSProps.EVENT_TYPE] = event_type - - return CeilometerDriver.make_pickleable( - [entity], CEILOMETER_DATASOURCE, - DatasourceAction.UPDATE)[0] - - def _init_aodh_event_actions(self): - self.actions = { - CeilEventType.CREATION: - self._convert_alarm_creation_event, - CeilEventType.RULE_CHANGE: - self._convert_alarm_rule_change_event, - CeilEventType.STATE_TRANSITION: - self._convert_alarm_state_transition_event, - CeilEventType.DELETION: - self._convert_alarm_deletion_event - } - - @classmethod - def _convert_base_event(cls, event): - return { - CeilProps.PROJECT_ID: event[CeilProps.PROJECT_ID], - CeilProps.ALARM_ID: event[CeilProps.ALARM_ID], - CeilProps.SEVERITY: event[CeilProps.SEVERITY], - CeilProps.TIMESTAMP: event[CeilProps.TIMESTAMP], - CeilProps.USER_ID: event[CeilProps.USER_ID] - } - - @classmethod - def _convert_vitrage_alarm_rule(cls, rule): - return { - CeilProps.VITRAGE_ID: _parse_query(rule, CeilProps.VITRAGE_ID), - CeilProps.RESOURCE_ID: _parse_query(rule, CeilProps.RESOURCE_ID) - } - - @classmethod - def _convert_threshold_alarm_rule(cls, rule): - return { - CeilProps.RESOURCE_ID: _parse_query(rule, CeilProps.RESOURCE_ID), - } - - @classmethod - def _convert_gnocchi_resources_threshold_alarm_rule(cls, rule): - return { - CeilProps.RESOURCE_ID: _parse_query(rule, CeilProps.RESOURCE_ID), - } - - @classmethod - def _convert_event_alarm_rule(cls, rule): - return { - CeilProps.EVENT_TYPE: rule[CeilProps.EVENT_TYPE], - CeilProps.RESOURCE_ID: - _parse_query(rule, CeilProps.EVENT_RESOURCE_ID) - } - - @classmethod - def _convert_detail_event(cls, event): - alarm_info = event[CeilProps.DETAIL] - alarm_rule = alarm_info[CeilProps.RULE] - - entity_detail = { - CeilProps.DESCRIPTION: alarm_info[CeilProps.DESCRIPTION], - CeilProps.ENABLED: alarm_info[CeilProps.ENABLED], - CeilProps.NAME: alarm_info[CeilProps.NAME], - CeilProps.STATE: alarm_info[CeilProps.STATE], - CeilProps.REPEAT_ACTIONS: alarm_info[CeilProps.REPEAT_ACTIONS], - CeilProps.TYPE: alarm_info[CeilProps.TYPE], - CeilProps.STATE_TIMESTAMP: alarm_info[CeilProps.STATE_TIMESTAMP], - CeilProps.STATE_REASON: alarm_info[CeilProps.STATE_REASON] - } - - if _is_vitrage_alarm(alarm_rule): - entity_detail.update(cls._convert_vitrage_alarm_rule(alarm_rule)) - elif entity_detail[CeilProps.TYPE] == CeilProps.EVENT: - entity_detail.update(cls._convert_event_alarm_rule(alarm_rule)) - elif entity_detail[CeilProps.TYPE] == CeilProps.THRESHOLD: - entity_detail.update( - cls._convert_threshold_alarm_rule(alarm_rule)) - elif entity_detail[CeilProps.TYPE] == \ - CeilProps.GNOCCHI_RESOURCES_THRESHOLD: - entity_detail.update( - cls._convert_gnocchi_resources_threshold_alarm_rule( - alarm_rule)) - - return entity_detail - - @classmethod - def _parse_changed_rule(cls, change_rule): - entity = {} - if CeilProps.EVENT_TYPE in change_rule: - entity[CeilProps.EVENT_TYPE] = change_rule[CeilProps.EVENT_TYPE] - if 'query' in change_rule: - event_resource_id = \ - _parse_query(change_rule, CeilProps.EVENT_RESOURCE_ID) - resource_id = \ - _parse_query(change_rule, CeilProps.RESOURCE_ID) - if event_resource_id or resource_id: - entity[CeilProps.RESOURCE_ID] = event_resource_id if \ - event_resource_id is not None else resource_id - - return entity - - @staticmethod - def should_delete_outdated_entities(): - return True - - def _convert_alarm_creation_event(self, event): - entity = self._convert_base_event(event) - detail = self._convert_detail_event(event) - entity.update(detail) - - return self._filter_and_cache_alarm(entity, None, - self._filter_get_erroneous, - datetime_utils.utcnow(False)) - - def _convert_alarm_rule_change_event(self, event): - """handle alarm rule change notification - - example of changed rule: - "detail": {"severity": "critical", - "rule": - {"query": [{"field": "traits.resource_id", - "type": "", - "value": "1", - "op": "eq"}], - "event_type": "instance.update"}} - """ - old_alarm = self._old_alarm(event) - entity = old_alarm.copy() - - changed_rule = event[CeilProps.DETAIL] - for (changed_type, changed_info) in changed_rule.items(): - # handle changed rule which may effect the neighbor - if changed_type == CeilProps.RULE: - entity.update(self._parse_changed_rule( - changed_rule[changed_type])) - # handle other changed alarm properties - elif changed_type in vars(CeilProps).values(): - entity[changed_type] = changed_info - - return self._filter_and_cache_alarm(entity, old_alarm, - self._filter_get_erroneous, - datetime_utils.utcnow(False)) - - def _convert_alarm_state_transition_event(self, event): - - old_alarm = self._old_alarm(event) - entity = old_alarm.copy() - try: - entity[CeilProps.STATE] = event[CeilProps.DETAIL][CeilProps.STATE] - except Exception: - LOG.exception("Failed to Convert alarm state transition event.") - - return self._filter_and_cache_alarm(entity, old_alarm, - self._filter_get_change, - datetime_utils.utcnow(False)) - - def _convert_alarm_deletion_event(self, event): - alarm_key = self._alarm_key(event) - alarm = self.cache.pop(alarm_key)[0] - return alarm if self._is_erroneous(alarm) else None - - -def _parse_query(data, key): - query_fields = data.get(CeilProps.QUERY, {}) - for query in query_fields: - field = query['field'] - if field == key: - return query['value'] - return None - - -def _is_vitrage_alarm(rule): - return _parse_query(rule, CeilProps.VITRAGE_ID) is not None diff --git a/vitrage/datasources/ceilometer/properties.py b/vitrage/datasources/ceilometer/properties.py deleted file mode 100644 index f85f7bd34..000000000 --- a/vitrage/datasources/ceilometer/properties.py +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright 2016 - Nokia -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -class CeilometerProperties(object): - ALARM_ID = 'alarm_id' - DESCRIPTION = 'description' - ENABLED = 'enabled' - EVENT = 'event' - EVENT_TYPE = 'event_type' - EVENT_RESOURCE_ID = 'traits.resource_id' - NAME = 'name' - STATE = 'state' - PROJECT_ID = 'project_id' - QUERY = 'query' - REPEAT_ACTIONS = 'repeat_actions' - RESOURCE_ID = 'resource_id' - SEVERITY = 'severity' - STATE_TIMESTAMP = 'state_timestamp' - THRESHOLD = 'threshold' - GNOCCHI_RESOURCES_THRESHOLD = 'gnocchi_resources_threshold' - TIMESTAMP = 'timestamp' - TYPE = 'type' - VITRAGE_ID = 'vitrage_id' - DETAIL = 'detail' - RULE = 'rule' - GNOCCHI_RESOURCES_THRESHOLD_RULE = 'gnocchi_resources_threshold_rule' - USER_ID = 'user_id' - STATE_REASON = 'state_reason' - TIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%f' - - -class CeilometerState(object): - OK = 'ok' - ALARM = 'alarm' - INSUFFICIENT_DATA = 'insufficient_data' - - -class CeilometerEventType(object): - CREATION = 'alarm.creation' - RULE_CHANGE = 'alarm.rule_change' - STATE_TRANSITION = 'alarm.state_transition' - DELETION = 'alarm.deletion' diff --git a/vitrage/datasources/ceilometer/transformer.py b/vitrage/datasources/ceilometer/transformer.py deleted file mode 100644 index d73316006..000000000 --- a/vitrage/datasources/ceilometer/transformer.py +++ /dev/null @@ -1,164 +0,0 @@ -# Copyright 2016 - Nokia -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from vitrage.common.constants import DatasourceProperties as DSProps -from vitrage.common.constants import EdgeLabel -from vitrage.common.constants import EntityCategory -from vitrage.common.constants import GraphAction -from vitrage.common.constants import VertexProperties as VProps -from vitrage.datasources.alarm_transformer_base import AlarmTransformerBase -from vitrage.datasources.ceilometer import CEILOMETER_DATASOURCE -from vitrage.datasources.ceilometer.properties \ - import CeilometerEventType as CeilEventType -from vitrage.datasources.ceilometer.properties \ - import CeilometerProperties as CeilProps -from vitrage.datasources.ceilometer.properties \ - import CeilometerState as CeilState -from vitrage.datasources import transformer_base as tbase -from vitrage.datasources.transformer_base import Neighbor -from vitrage.datasources.transformer_base import TransformerBase -from vitrage.evaluator.actions.evaluator_event_transformer \ - import VITRAGE_DATASOURCE -import vitrage.graph.utils as graph_utils -from vitrage.utils import datetime as datetime_utils - - -class CeilometerTransformer(AlarmTransformerBase): - - # Event types which need to refer them differently - GRAPH_ACTION_MAPPING = { - CeilEventType.DELETION: GraphAction.DELETE_ENTITY, - } - - def _create_snapshot_entity_vertex(self, entity_event): - if _is_vitrage_alarm(entity_event): - return self._create_merge_alarm_vertex(entity_event) - return self._create_vertex(entity_event) - - def _create_update_entity_vertex(self, entity_event): - if _is_vitrage_alarm(entity_event): - return self._create_merge_alarm_vertex(entity_event) - return self._create_vertex(entity_event) - - def _create_vertex(self, entity_event): - metadata = { - VProps.NAME: entity_event[CeilProps.NAME], - VProps.SEVERITY: entity_event[CeilProps.SEVERITY], - CeilProps.DESCRIPTION: entity_event[CeilProps.DESCRIPTION], - CeilProps.ENABLED: entity_event[CeilProps.ENABLED], - VProps.PROJECT_ID: entity_event.get(CeilProps.PROJECT_ID, None), - CeilProps.REPEAT_ACTIONS: entity_event[CeilProps.REPEAT_ACTIONS], - VProps.RESOURCE_ID: entity_event[CeilProps.RESOURCE_ID], - 'alarm_type': entity_event[CeilProps.TYPE] - } - - # TODO(annarez): convert EVENT_TYPE to tuple - if entity_event[CeilProps.TYPE] == CeilProps.EVENT: - metadata[CeilProps.EVENT_TYPE] = \ - entity_event[CeilProps.EVENT_TYPE] - - elif entity_event[CeilProps.TYPE] == CeilProps.THRESHOLD: - metadata[CeilProps.STATE_TIMESTAMP] = \ - entity_event[CeilProps.STATE_TIMESTAMP] - - vitrage_sample_timestamp = entity_event[DSProps.SAMPLE_DATE] - - update_timestamp = self._format_update_timestamp( - CeilometerTransformer._timestamp(entity_event), - vitrage_sample_timestamp) - - return graph_utils.create_vertex( - self._create_entity_key(entity_event), - vitrage_category=EntityCategory.ALARM, - vitrage_type=entity_event[DSProps.ENTITY_TYPE], - vitrage_sample_timestamp=vitrage_sample_timestamp, - entity_id=entity_event[CeilProps.ALARM_ID], - entity_state=self._get_alarm_state(entity_event), - update_timestamp=update_timestamp, - metadata=metadata) - - def _create_snapshot_neighbors(self, entity_event): - return self._create_aodh_neighbors(entity_event) - - def _create_update_neighbors(self, entity_event): - return self._create_aodh_neighbors(entity_event) - - def _create_aodh_neighbors(self, entity_event): - graph_neighbors = entity_event.get(self.QUERY_RESULT, []) - result = [] - for vertex in graph_neighbors: - edge = graph_utils.create_edge( - source_id=TransformerBase.uuid_from_deprecated_vitrage_id( - self._create_entity_key(entity_event)), - target_id=vertex.vertex_id, - relationship_type=EdgeLabel.ON) - result.append(Neighbor(vertex, edge)) - return result - - def _create_merge_alarm_vertex(self, entity_event): - """Handle an alarm that already has a vitrage_id - - This is a deduced alarm created in aodh by vitrage, so it already - exists in the graph. - This function will update the exiting vertex (and not create a new one) - """ - metadata = { - CeilProps.DESCRIPTION: entity_event[CeilProps.DESCRIPTION], - VProps.PROJECT_ID: entity_event[CeilProps.PROJECT_ID], - } - vitrage_sample_timestamp = entity_event[DSProps.SAMPLE_DATE] - update_timestamp = self._format_update_timestamp( - CeilometerTransformer._timestamp(entity_event), - vitrage_sample_timestamp) - - return graph_utils.create_vertex( - self._create_entity_key(entity_event), - vitrage_category=EntityCategory.ALARM, - vitrage_type=VITRAGE_DATASOURCE, - vitrage_sample_timestamp=vitrage_sample_timestamp, - entity_id=entity_event.get(CeilProps.ALARM_ID), - update_timestamp=update_timestamp, - metadata=metadata) - - def _ok_status(self, entity_event): - return entity_event[CeilProps.STATE] != CeilState.ALARM - - def _create_entity_key(self, entity_event): - if _is_vitrage_alarm(entity_event): - return entity_event.get(CeilProps.VITRAGE_ID) - - entity_type = entity_event[DSProps.ENTITY_TYPE] - alarm_id = entity_event[CeilProps.ALARM_ID] - return tbase.build_key((EntityCategory.ALARM, entity_type, alarm_id)) - - @staticmethod - def _timestamp(entity_event): - return datetime_utils.change_time_str_format( - entity_event[CeilProps.TIMESTAMP], - CeilProps.TIME_FORMAT, - tbase.TIMESTAMP_FORMAT) - - @staticmethod - def get_enrich_query(event): - affected_resource_id = event.get(CeilProps.RESOURCE_ID, None) - if not affected_resource_id: - return None - return {VProps.ID: affected_resource_id} - - def get_vitrage_type(self): - return CEILOMETER_DATASOURCE - - -def _is_vitrage_alarm(entity_event): - return entity_event.get(CeilProps.VITRAGE_ID) is not None diff --git a/vitrage/os_clients.py b/vitrage/os_clients.py index fa6405ec2..183cc8bf3 100644 --- a/vitrage/os_clients.py +++ b/vitrage/os_clients.py @@ -23,7 +23,6 @@ LOG = log.getLogger(__name__) OPTS = [ cfg.StrOpt('aodh_version', default='2', help='Aodh version'), - cfg.StrOpt('ceilometer_version', default='2', help='Ceilometer version'), cfg.StrOpt('nova_version', default='2.11', help='Nova version'), cfg.StrOpt('cinder_version', default='3', help='Cinder version'), cfg.StrOpt('glance_version', default='2', help='Glance version'), @@ -43,7 +42,6 @@ OPTS = [ _client_modules = { 'aodh': 'aodhclient.client', - 'ceilometer': 'ceilometerclient.client', 'nova': 'novaclient.client', 'cinder': 'cinderclient.client', 'glance': 'glanceclient.client', @@ -87,20 +85,6 @@ def aodh_client(): LOG.exception('Create Aodh client - Got Exception.') -def ceilometer_client(): - """Get an instance of ceilometer client""" - try: - cm_client = driver_module('ceilometer') - client = cm_client.get_client( - version=CONF.ceilometer_version, - session=keystone_client.get_session(), - ) - LOG.info('Ceilometer client created') - return client - except Exception: - LOG.exception('Create Ceilometer client - Got Exception.') - - def nova_client(): """Get an instance of nova client""" try: diff --git a/vitrage/tests/functional/datasources/ceilometer/__init__.py b/vitrage/tests/functional/datasources/ceilometer/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/vitrage/tests/functional/datasources/ceilometer/test_ceilometer.py b/vitrage/tests/functional/datasources/ceilometer/test_ceilometer.py deleted file mode 100644 index 6220b4027..000000000 --- a/vitrage/tests/functional/datasources/ceilometer/test_ceilometer.py +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright 2016 - ZTE, Nokia -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_config import cfg -from testtools import matchers - -from vitrage.common.constants import DatasourceProperties as DSProp -from vitrage.common.constants import EntityCategory -from vitrage.common.constants import VertexProperties as VProps -from vitrage.datasources.ceilometer import CEILOMETER_DATASOURCE -from vitrage.datasources.ceilometer.properties \ - import CeilometerProperties as CeilProps -from vitrage.datasources import NOVA_HOST_DATASOURCE -from vitrage.datasources import NOVA_INSTANCE_DATASOURCE -from vitrage.datasources import NOVA_ZONE_DATASOURCE -from vitrage.datasources.transformer_base import TransformerBase -from vitrage.tests.functional.datasources.base import \ - TestDataSourcesBase -from vitrage.tests.mocks import mock_transformer - - -class TestCeilometerAlarms(TestDataSourcesBase): - - DATASOURCES_OPTS = [ - cfg.ListOpt('types', - default=[CEILOMETER_DATASOURCE, - NOVA_HOST_DATASOURCE, - NOVA_INSTANCE_DATASOURCE, - NOVA_ZONE_DATASOURCE], - help='Names of supported driver data sources'), - - cfg.ListOpt('path', - default=['vitrage.datasources'], - help='base path for data sources') - ] - - def setUp(self): - super(TestCeilometerAlarms, self).setUp() - self.cfg_fixture.config(group='datasources', - types=[ - CEILOMETER_DATASOURCE, - NOVA_HOST_DATASOURCE, - NOVA_INSTANCE_DATASOURCE, - NOVA_ZONE_DATASOURCE]) - self.load_datasources() - - def test_ceilometer_alarms_validity(self): - # Setup - processor = self._create_processor_with_graph() - self.assertThat(processor.entity_graph, - matchers.HasLength( - self._num_total_expected_vertices()) - ) - - detail = {TransformerBase.QUERY_RESULT: '', - DSProp.ENTITY_TYPE: CEILOMETER_DATASOURCE} - spec_list = \ - mock_transformer.simple_aodh_alarm_generators(alarm_num=1, - snapshot_events=1, - snap_vals=detail) - static_events = mock_transformer.generate_random_events_list(spec_list) - - aodh_event = static_events[0] - aodh_event[CeilProps.RESOURCE_ID] = \ - self._find_entity_id_by_type(processor.entity_graph, - NOVA_HOST_DATASOURCE) - - # Action - processor.process_event(aodh_event) - - # Test assertions - self.assertThat(processor.entity_graph, - matchers.HasLength( - self._num_total_expected_vertices() + 1) - ) - - aodh_vertices = processor.entity_graph.get_vertices( - vertex_attr_filter={ - VProps.VITRAGE_CATEGORY: EntityCategory.ALARM, - VProps.VITRAGE_TYPE: CEILOMETER_DATASOURCE - }) - self.assertThat(aodh_vertices, matchers.HasLength(1)) - - aodh_neighbors = processor.entity_graph.neighbors( - aodh_vertices[0].vertex_id) - self.assertThat(aodh_neighbors, matchers.HasLength(1)) - - self.assertEqual(NOVA_HOST_DATASOURCE, - aodh_neighbors[0][VProps.VITRAGE_TYPE]) diff --git a/vitrage/tests/unit/datasources/ceilometer/__init__.py b/vitrage/tests/unit/datasources/ceilometer/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/vitrage/tests/unit/datasources/ceilometer/ceilometer_transformer_base_test.py b/vitrage/tests/unit/datasources/ceilometer/ceilometer_transformer_base_test.py deleted file mode 100644 index bfc6eaf07..000000000 --- a/vitrage/tests/unit/datasources/ceilometer/ceilometer_transformer_base_test.py +++ /dev/null @@ -1,119 +0,0 @@ -# Copyright 2017 - ZTE, Nokia -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from vitrage.common.constants import DatasourceAction -from vitrage.common.constants import DatasourceProperties as DSProps -from vitrage.common.constants import EdgeLabel -from vitrage.common.constants import EntityCategory -from vitrage.common.constants import GraphAction -from vitrage.common.constants import VertexProperties as VProps -from vitrage.datasources.alarm_properties import AlarmProperties as AlarmProps -from vitrage.datasources.ceilometer.properties \ - import CeilometerProperties as CeilProps -from vitrage.datasources.ceilometer.properties import CeilometerState -from vitrage.datasources.nova.instance import NOVA_INSTANCE_DATASOURCE -from vitrage.datasources.transformer_base import TransformerBase -from vitrage.graph.driver.elements import Vertex -from vitrage.tests import base - - -class CeilometerTransformerBaseTest(base.BaseTest): - - def _validate_aodh_vertex_props(self, vertex, event): - - self.assertEqual(EntityCategory.ALARM, - vertex[VProps.VITRAGE_CATEGORY]) - self.assertEqual(event[DSProps.ENTITY_TYPE], - vertex[VProps.VITRAGE_TYPE]) - self.assertEqual(event[CeilProps.NAME], vertex[VProps.NAME]) - self.assertEqual(event[CeilProps.SEVERITY], - vertex[VProps.SEVERITY]) - self.assertEqual(event[CeilProps.DESCRIPTION], - vertex[CeilProps.DESCRIPTION]) - self.assertEqual(event[CeilProps.ENABLED], - vertex[CeilProps.ENABLED]) - self.assertEqual(event[CeilProps.PROJECT_ID], - vertex[VProps.PROJECT_ID]) - self.assertEqual(event[CeilProps.REPEAT_ACTIONS], - vertex[CeilProps.REPEAT_ACTIONS]) - self.assertEqual(event[CeilProps.TYPE], vertex['alarm_type']) - if event[CeilProps.TYPE] == CeilProps.EVENT: - self.assertEqual(event[CeilProps.EVENT_TYPE], - vertex[CeilProps.EVENT_TYPE]) - elif event[CeilProps.TYPE] == CeilProps.THRESHOLD: - self.assertEqual(event[CeilProps.STATE_TIMESTAMP], - vertex[CeilProps.STATE_TIMESTAMP]) - self.assertEqual(event[DSProps.SAMPLE_DATE], - vertex[VProps.VITRAGE_SAMPLE_TIMESTAMP]) - - event_status = event[CeilProps.STATE] - if event_status == CeilometerState.OK: - self.assertEqual(AlarmProps.INACTIVE_STATE, - vertex[VProps.STATE]) - else: - self.assertEqual(AlarmProps.ACTIVE_STATE, - vertex[VProps.STATE]) - self.assertFalse(vertex[VProps.VITRAGE_IS_PLACEHOLDER]) - self.assertFalse(vertex[VProps.VITRAGE_IS_DELETED]) - - def _validate_action(self, alarm, wrapper): - if DSProps.EVENT_TYPE in alarm \ - and alarm[DSProps.EVENT_TYPE] in vars(GraphAction).values(): - self.assertEqual(alarm[DSProps.EVENT_TYPE], wrapper.action) - return - - ds_action = alarm[DSProps.DATASOURCE_ACTION] - if ds_action in (DatasourceAction.SNAPSHOT, DatasourceAction.UPDATE): - self.assertEqual(GraphAction.UPDATE_ENTITY, wrapper.action) - else: - self.assertEqual(GraphAction.CREATE_ENTITY, wrapper.action) - - def _validate_neighbors(self, neighbors, alarm_id, event): - resource_counter = 0 - - for neighbor in neighbors: - resource_id = event[CeilProps.RESOURCE_ID] - self._validate_instance_neighbor(neighbor, - resource_id, - alarm_id) - resource_counter += 1 - - self.assertEqual(1, - resource_counter, - 'Alarm can be belonged to only one resource') - - def _validate_instance_neighbor(self, - alarm_neighbor, - resource_id, - alarm_vertex_id): - # validate neighbor vertex - self.assertEqual(EntityCategory.RESOURCE, - alarm_neighbor.vertex[VProps.VITRAGE_CATEGORY]) - self.assertEqual(NOVA_INSTANCE_DATASOURCE, - alarm_neighbor.vertex[VProps.VITRAGE_TYPE]) - self.assertEqual(resource_id, alarm_neighbor.vertex[VProps.ID]) - self.assertFalse(alarm_neighbor.vertex[VProps.VITRAGE_IS_PLACEHOLDER]) - self.assertFalse(alarm_neighbor.vertex[VProps.VITRAGE_IS_DELETED]) - - # Validate neighbor edge - edge = alarm_neighbor.edge - self.assertEqual(edge.target_id, alarm_neighbor.vertex.vertex_id) - self.assertEqual(edge.source_id, alarm_vertex_id) - self.assertEqual(edge.label, EdgeLabel.ON) - - def _convert_dist_to_vertex(self, neighbor): - ver_id = neighbor[VProps.VITRAGE_CATEGORY] + \ - TransformerBase.KEY_SEPARATOR + neighbor[VProps.VITRAGE_TYPE] + \ - TransformerBase.KEY_SEPARATOR + neighbor[VProps.ID] - return Vertex(vertex_id=ver_id, properties=neighbor) diff --git a/vitrage/tests/unit/datasources/ceilometer/mock_driver.py b/vitrage/tests/unit/datasources/ceilometer/mock_driver.py deleted file mode 100644 index 0d596aa4a..000000000 --- a/vitrage/tests/unit/datasources/ceilometer/mock_driver.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2017 - Nokia -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from vitrage.datasources.ceilometer.driver import CeilometerDriver - - -class MockCeilometerDriver(CeilometerDriver): - """A aodh driver for tests. - - """ - - def _cache_all_alarms(self): - pass diff --git a/vitrage/tests/unit/datasources/ceilometer/test_ceilometer_driver.py b/vitrage/tests/unit/datasources/ceilometer/test_ceilometer_driver.py deleted file mode 100644 index d6359068e..000000000 --- a/vitrage/tests/unit/datasources/ceilometer/test_ceilometer_driver.py +++ /dev/null @@ -1,391 +0,0 @@ -# Copyright 2017 - ZTE, Nokia -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -from oslo_config import cfg -import testtools - -from vitrage.common.constants import DatasourceOpts as DSOpts -from vitrage.common.constants import DatasourceProperties as DSProps -from vitrage.common.constants import UpdateMethod -from vitrage.datasources.ceilometer import CEILOMETER_DATASOURCE -from vitrage.datasources.ceilometer.properties import CeilometerEventType -from vitrage.datasources.ceilometer.properties \ - import CeilometerProperties as CeilProps -from vitrage.tests import base -from vitrage.tests.mocks import mock_driver -from vitrage.tests.unit.datasources.ceilometer.mock_driver \ - import MockCeilometerDriver - - -@testtools.skip("skip for now") -class CeilometerDriverTest(base.BaseTest): - - OPTS = [ - cfg.StrOpt(DSOpts.UPDATE_METHOD, - default=UpdateMethod.PUSH), - ] - - # noinspection PyPep8Naming - @classmethod - def setUpClass(cls): - super(CeilometerDriverTest, cls).setUpClass() - cls.conf = cfg.ConfigOpts() - cls.conf.register_opts(cls.OPTS, group=CEILOMETER_DATASOURCE) - - def test_event_alarm_notifications(self): - - aodh_driver = MockCeilometerDriver() - - # 1. alarm creation with 'ok' state - # prepare data - detail_data = {"type": "creation", - CeilProps.DETAIL: self._create_alarm_data_type_event(), - } - generators = \ - mock_driver.simple_aodh_alarm_notification_generators( - alarm_num=1, - update_events=1, - update_vals=detail_data) - alarm = mock_driver.generate_sequential_events_list(generators)[0] - alarm_info = alarm.copy() - - # action - entity = aodh_driver.enrich_event(alarm, CeilometerEventType.CREATION) - - # Test assertions - # alarm with status OK should not be handled - self.assertIsNone(entity) - - # 2.alarm state transition from 'ok' to 'alarm' - detail_data = {"type": "state transition", - CeilProps.DETAIL: {CeilProps.STATE: "alarm"}} - alarm.update(detail_data) - entity = aodh_driver.enrich_event(alarm, - CeilometerEventType.STATE_TRANSITION) - - # Test assertions - # alarm state change: ok->alarm, need to be added - self.assertIsNotNone(entity) - self._validate_aodh_entity_comm_props(entity, alarm_info) - self.assertEqual(entity[CeilProps.STATE], - alarm[CeilProps.DETAIL][CeilProps.STATE]) - self.assertEqual(entity[CeilProps.SEVERITY], - alarm[CeilProps.SEVERITY]) - self.assertEqual(entity[DSProps.EVENT_TYPE], - CeilometerEventType.STATE_TRANSITION) - - # 3. delete alarm which is 'alarm' state - # prepare data - detail_data = {"type": "deletion"} - alarm.update(detail_data) - - # action - entity = aodh_driver.enrich_event( - alarm, CeilometerEventType.DELETION) - - # Test assertions - self.assertIsNotNone(entity) - self._validate_aodh_entity_comm_props(entity, alarm_info) - self.assertEqual(entity[DSProps.EVENT_TYPE], - CeilometerEventType.DELETION) - - # 4. alarm creation with 'alarm' state - # prepare data - detail_data = {"type": "creation", - CeilProps.DETAIL: - self._create_alarm_data_type_event(state="alarm")} - generators = \ - mock_driver.simple_aodh_alarm_notification_generators( - alarm_num=1, - update_events=1, - update_vals=detail_data) - alarm = mock_driver.generate_sequential_events_list(generators)[0] - alarm_info = alarm.copy() - - # action - entity = aodh_driver.enrich_event( - alarm, CeilometerEventType.CREATION) - - # Test assertions - # alarm with status 'alarm' need to be added - self.assertIsNotNone(entity) - self._validate_aodh_entity_comm_props(entity, alarm_info) - self.assertEqual(entity[CeilProps.STATE], - alarm[CeilProps.DETAIL][CeilProps.STATE]) - self.assertEqual(entity[CeilProps.SEVERITY], - alarm[CeilProps.SEVERITY]) - self.assertIsNone(entity[CeilProps.RESOURCE_ID]) - self.assertEqual("*", entity[CeilProps.EVENT_TYPE]) - self.assertEqual(entity[DSProps.EVENT_TYPE], - CeilometerEventType.CREATION) - - # 5. alarm rule change - # prepare data - detail_data = {"type": "rule change", - CeilProps.DETAIL: { - "severity": "critical", - CeilProps.RULE: - {"query": [{"field": "traits.resource_id", - "type": "", - "value": "1", - "op": "eq"}], - "event_type": "instance.update"}}} - alarm.update(detail_data) - - # action - entity = aodh_driver.enrich_event( - alarm, CeilometerEventType.RULE_CHANGE) - - # Test assertions - # alarm rule change: need to be update - self.assertIsNotNone(entity) - self._validate_aodh_entity_comm_props(entity, alarm_info) - self.assertEqual(entity[CeilProps.SEVERITY], - alarm[CeilProps.DETAIL][CeilProps.SEVERITY]) - self.assertEqual( - entity[CeilProps.EVENT_TYPE], - alarm[CeilProps.DETAIL][CeilProps.RULE][CeilProps.EVENT_TYPE]) - self.assertEqual("1", entity[CeilProps.RESOURCE_ID]) - self.assertEqual(entity[DSProps.EVENT_TYPE], - CeilometerEventType.RULE_CHANGE) - - # 6. alarm state change from 'alarm' to 'ok' - # prepare data - detail_data = {"type": "state transition", - CeilProps.DETAIL: {CeilProps.STATE: "ok"}} - alarm.update(detail_data) - - # action - entity = aodh_driver.enrich_event( - alarm, CeilometerEventType.STATE_TRANSITION) - - # Test assertions - # alarm state change: alarm->OK, need to be deleted - self.assertIsNotNone(entity) - self._validate_aodh_entity_comm_props(entity, alarm_info) - self.assertEqual(entity[DSProps.EVENT_TYPE], - CeilometerEventType.STATE_TRANSITION) - - # 7. delete alarm which is 'ok' state - # prepare data - detail_data = {"type": "deletion"} - alarm.update(detail_data) - - # action - entity = aodh_driver.enrich_event( - alarm, CeilometerEventType.DELETION) - - # Test assertions - self.assertIsNone(entity) - - def test_gnocchi_threshold_alarm_notifications(self): - aodh_driver = MockCeilometerDriver() - - # 1. alarm creation with 'ok' state - # prepare data - detail_data = {"type": "gnocchi_resources_threshold", - CeilProps.DETAIL: self._create_alarm_data_gnocchi()} - generators = \ - mock_driver.simple_aodh_alarm_notification_generators( - alarm_num=1, - update_events=1, - update_vals=detail_data) - alarm = mock_driver.generate_sequential_events_list(generators)[0] - alarm_info = alarm.copy() - - # action - entity = aodh_driver.enrich_event( - alarm, CeilometerEventType.CREATION) - - # Test assertions - # alarm with status OK should not be handled - self.assertIsNone(entity) - - # 2.alarm state transition from 'ok' to 'alarm' - detail_data = {"type": "state transition", - CeilProps.DETAIL: {CeilProps.STATE: "alarm"}} - alarm.update(detail_data) - entity = aodh_driver.enrich_event( - alarm, CeilometerEventType.STATE_TRANSITION) - - # Test assertions - # alarm state change: ok->alarm, need to be added - self.assertIsNotNone(entity) - self._validate_aodh_entity_comm_props(entity, alarm_info) - self.assertEqual(entity[CeilProps.STATE], - alarm[CeilProps.DETAIL][CeilProps.STATE]) - self.assertEqual(entity[CeilProps.SEVERITY], - alarm[CeilProps.SEVERITY]) - - # 3. delete alarm which is 'alarm' state - # prepare data - detail_data = {"type": "deletion"} - alarm.update(detail_data) - - # action - entity = aodh_driver.enrich_event( - alarm, CeilometerEventType.DELETION) - - # Test assertions - self.assertIsNotNone(entity) - self._validate_aodh_entity_comm_props(entity, alarm_info) - self.assertEqual(entity[DSProps.EVENT_TYPE], - CeilometerEventType.DELETION) - - # 4. alarm creation with 'alarm' state - # prepare data - detail_data = {"type": "gnocchi_resources_threshold", - CeilProps.DETAIL: - self._create_alarm_data_gnocchi(state="alarm")} - generators = \ - mock_driver.simple_aodh_alarm_notification_generators( - alarm_num=1, - update_events=1, - update_vals=detail_data) - alarm = mock_driver.generate_sequential_events_list(generators)[0] - alarm_info = alarm.copy() - - # action - entity = aodh_driver.enrich_event( - alarm, CeilometerEventType.CREATION) - - # Test assertions - # alarm with status 'alarm' need to be added - self.assertIsNotNone(entity) - self._validate_aodh_entity_comm_props(entity, alarm_info) - self.assertEqual(entity[CeilProps.STATE], - alarm[CeilProps.DETAIL][CeilProps.STATE]) - self.assertEqual(entity[CeilProps.SEVERITY], - alarm[CeilProps.SEVERITY]) - self.assertEqual(entity[DSProps.EVENT_TYPE], - CeilometerEventType.CREATION) - - # 5. alarm rule change - # prepare data - detail_data = {"type": "rule change", - CeilProps.DETAIL: { - "severity": "critical", - CeilProps.RULE: - {"granularity": "300", - "threshold": "0.0123", - "comparison_operator": "eq"}}} - alarm.update(detail_data) - - # action - entity = aodh_driver.enrich_event( - alarm, CeilometerEventType.RULE_CHANGE) - - # Test assertions - # alarm rule change: need to be update - self.assertIsNotNone(entity) - self._validate_aodh_entity_comm_props(entity, alarm_info) - self.assertEqual(entity[CeilProps.SEVERITY], - alarm[CeilProps.DETAIL][CeilProps.SEVERITY]) - self.assertEqual(entity[DSProps.EVENT_TYPE], - CeilometerEventType.RULE_CHANGE) - - # 6. alarm state change from 'alarm' to 'ok' - # prepare data - detail_data = {"type": "state transition", - CeilProps.DETAIL: {CeilProps.STATE: "ok"}} - alarm.update(detail_data) - - # action - entity = aodh_driver.enrich_event( - alarm, - CeilometerEventType.STATE_TRANSITION) - - # Test assertions - # alarm state change: alarm->OK, need to be deleted - self.assertIsNotNone(entity) - self._validate_aodh_entity_comm_props(entity, alarm_info) - self.assertEqual(entity[DSProps.EVENT_TYPE], - CeilometerEventType.STATE_TRANSITION) - - # 7. delete alarm which is 'ok' state - # prepare data - detail_data = {"type": "deletion"} - alarm.update(detail_data) - - # action - entity = aodh_driver.enrich_event( - alarm, CeilometerEventType.DELETION) - - # Test assertions - self.assertIsNone(entity) - - def _create_alarm_data_gnocchi(self, - state="ok", - type="gnocchi_resources_threshold", - rule=None): - - if rule is None: - rule = {"granularity": "300", - "threshold": "0.001", - "comparison_operator": "gt", - "resource_type": "instance" - } - return {CeilProps.DESCRIPTION: "test", - CeilProps.TIMESTAMP: "2016-11-09T01:39:13.839584", - CeilProps.ENABLED: True, - CeilProps.STATE_TIMESTAMP: "2016-11-09T01:39:13.839584", - CeilProps.ALARM_ID: "7e5c3754-e2eb-4782-ae00-7da5ded8568b", - CeilProps.REPEAT_ACTIONS: False, - CeilProps.PROJECT_ID: "c365d18fcc03493187016ae743f0cc4d", - CeilProps.NAME: "test", - CeilProps.SEVERITY: "low", - CeilProps.RESOURCE_ID: "88cd2d1d-8af4-4d00-9b5e-f82f8c8b0f8d", - CeilProps.TYPE: type, - CeilProps.STATE: state, - CeilProps.RULE: rule, - CeilProps.STATE_REASON: 'for test'} - - def _create_alarm_data_type_event(self, - state="ok", - type="event", - rule=None): - - if rule is None: - rule = {"query": [], "event_type": "*"} - return {CeilProps.DESCRIPTION: "test", - CeilProps.TIMESTAMP: "2016-11-09T01:39:13.839584", - CeilProps.ENABLED: True, - CeilProps.STATE_TIMESTAMP: "2016-11-09T01:39:13.839584", - CeilProps.ALARM_ID: "7e5c3754-e2eb-4782-ae00-7da5ded8568b", - CeilProps.REPEAT_ACTIONS: False, - CeilProps.PROJECT_ID: "c365d18fcc03493187016ae743f0cc4d", - CeilProps.NAME: "test", - CeilProps.SEVERITY: "low", - CeilProps.TYPE: type, - CeilProps.STATE: state, - CeilProps.RULE: rule, - CeilProps.STATE_REASON: 'for test'} - - def _validate_aodh_entity_comm_props(self, entity, alarm): - - self.assertEqual(entity[CeilProps.ALARM_ID], - alarm[CeilProps.ALARM_ID]) - self.assertEqual(entity[CeilProps.PROJECT_ID], - alarm[CeilProps.PROJECT_ID]) - self.assertEqual(entity[CeilProps.TIMESTAMP], - alarm[CeilProps.TIMESTAMP]) - self.assertEqual(entity[CeilProps.DESCRIPTION], - alarm[CeilProps.DETAIL][CeilProps.DESCRIPTION]) - self.assertEqual(entity[CeilProps.ENABLED], - alarm[CeilProps.DETAIL][CeilProps.ENABLED]) - self.assertEqual(entity[CeilProps.NAME], - alarm[CeilProps.DETAIL][CeilProps.NAME]) - self.assertEqual(entity[CeilProps.REPEAT_ACTIONS], - alarm[CeilProps.DETAIL][CeilProps.REPEAT_ACTIONS]) - self.assertEqual(entity[CeilProps.TYPE], - alarm[CeilProps.DETAIL][CeilProps.TYPE]) diff --git a/vitrage/tests/unit/datasources/ceilometer/test_ceilometer_transformer.py b/vitrage/tests/unit/datasources/ceilometer/test_ceilometer_transformer.py deleted file mode 100644 index 3d26a2a96..000000000 --- a/vitrage/tests/unit/datasources/ceilometer/test_ceilometer_transformer.py +++ /dev/null @@ -1,166 +0,0 @@ -# Copyright 2016 - ZTE, Nokia -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from oslo_config import cfg -from oslo_log import log as logging -from testtools import matchers - -from vitrage.common.constants import DatasourceOpts as DSOpts -from vitrage.common.constants import DatasourceProperties as DSProps -from vitrage.common.constants import EntityCategory -from vitrage.common.constants import UpdateMethod -from vitrage.datasources.ceilometer import CEILOMETER_DATASOURCE -from vitrage.datasources.ceilometer.properties \ - import CeilometerProperties as CeilProps -from vitrage.datasources.ceilometer.transformer import CeilometerTransformer -from vitrage.datasources.transformer_base import TransformerBase -from vitrage.tests.mocks import mock_transformer as mock_sync -from vitrage.tests.unit.datasources.ceilometer.\ - ceilometer_transformer_base_test \ - import CeilometerTransformerBaseTest - -LOG = logging.getLogger(__name__) - - -class TestCeilometerAlarmTransformer(CeilometerTransformerBaseTest): - - OPTS = [ - cfg.StrOpt(DSOpts.UPDATE_METHOD, - default=UpdateMethod.PULL), - ] - - # noinspection PyPep8Naming - @classmethod - def setUpClass(cls): - super(TestCeilometerAlarmTransformer, cls).setUpClass() - cls.transformers = {} - cls.conf = cfg.ConfigOpts() - cls.conf.register_opts(cls.OPTS, group=CEILOMETER_DATASOURCE) - cls.transformers[CEILOMETER_DATASOURCE] = \ - CeilometerTransformer(cls.transformers) - - def test_key_values_with_vitrage_alarm(self): - LOG.debug('Ceilometer transformer test: ' - 'get key values(vitrage_alarm)') - - # Test setup - entity = {CeilProps.VITRAGE_ID: 'test', - DSProps.ENTITY_TYPE: CEILOMETER_DATASOURCE, - CeilProps.ALARM_ID: '12345'} - transformer = self.transformers[CEILOMETER_DATASOURCE] - - # Test action - observed_key_fields = transformer._create_entity_key(entity) - - # Test assertions - self.assertEqual('test', observed_key_fields) - - def test_key_values(self): - LOG.debug('Ceilometer transformer test: get key values(aodh alarm)') - - # Test setup - entity = {DSProps.ENTITY_TYPE: CEILOMETER_DATASOURCE, - CeilProps.ALARM_ID: '12345'} - transformer = self.transformers[CEILOMETER_DATASOURCE] - - # Test action - entity_key_fields = transformer._create_entity_key(entity).split(":") - - # Test assertions - self.assertEqual(EntityCategory.ALARM, entity_key_fields[0]) - self.assertEqual(CEILOMETER_DATASOURCE, entity_key_fields[1]) - self.assertEqual(entity[CeilProps.ALARM_ID], entity_key_fields[2]) - - def test_snapshot_transform(self): - LOG.debug('Ceilometer alarm transformer test: ' - 'transform entity event snapshot') - - # Test setup - spec_list = mock_sync.simple_aodh_alarm_generators(alarm_num=3, - snapshot_events=3) - static_events = mock_sync.generate_random_events_list(spec_list) - - for event in static_events: - # convert neighbor from dict to vertex object - neighbors = event[TransformerBase.QUERY_RESULT] - vertices = [] - for neighbor in neighbors: - neighbor_vertex = self._convert_dist_to_vertex(neighbor) - vertices.append(self.transformers[CEILOMETER_DATASOURCE]. - update_uuid_in_vertex(neighbor_vertex)) - event[TransformerBase.QUERY_RESULT] = vertices - - # Test action - wrapper = self.transformers[CEILOMETER_DATASOURCE].transform(event) - - # Test assertions - vertex = wrapper.vertex - self._validate_aodh_vertex_props(vertex, event) - - neighbors = wrapper.neighbors - self.assertThat(neighbors, matchers.HasLength(1)) - self._validate_neighbors(neighbors, vertex.vertex_id, event) - - self._validate_action(event, wrapper) - - -class TestCeilometerAlarmPushTransformer(CeilometerTransformerBaseTest): - - OPTS = [ - cfg.StrOpt(DSOpts.UPDATE_METHOD, - default=UpdateMethod.PUSH), - ] - - # noinspection PyPep8Naming - @classmethod - def setUpClass(cls): - super(TestCeilometerAlarmPushTransformer, cls).setUpClass() - cls.transformers = {} - cls.conf = cfg.ConfigOpts() - cls.conf.register_opts(cls.OPTS, group=CEILOMETER_DATASOURCE) - cls.transformers[CEILOMETER_DATASOURCE] = \ - CeilometerTransformer(cls.transformers) - - def test_update_transform(self): - LOG.debug('Ceilometer update alarm transformer test:' - 'transform entity event update') - - # Test setup - spec_list = \ - mock_sync.simple_aodh_update_alarm_generators(alarm_num=5, - update_events=5) - static_events = mock_sync.generate_random_events_list(spec_list) - - for event in static_events: - # convert neighbor from dict to vertex object - neighbors = event[TransformerBase.QUERY_RESULT] - vertices = [] - for neighbor in neighbors: - neighbor_vertex = self._convert_dist_to_vertex(neighbor) - vertices.append(self.transformers[CEILOMETER_DATASOURCE]. - update_uuid_in_vertex(neighbor_vertex)) - event[TransformerBase.QUERY_RESULT] = vertices - - # Test action - wrapper = self.transformers[CEILOMETER_DATASOURCE].transform(event) - - # Test assertions - vertex = wrapper.vertex - self._validate_aodh_vertex_props(vertex, event) - - neighbors = wrapper.neighbors - self.assertThat(neighbors, matchers.HasLength(1)) - self._validate_neighbors(neighbors, vertex.vertex_id, event) - - self._validate_action(event, wrapper)