From 7b21a4a985382a0f61ab3e3c0fdad559f83fdd71 Mon Sep 17 00:00:00 2001 From: Alexey Weyl Date: Wed, 25 May 2016 08:26:41 +0300 Subject: [PATCH] Rearrange state_manager Decouple the aggregated and operational values Rename statemanager to datasource_info_mapper Change-Id: Ied6220c08f10b6684e21dd22e011af246ec28d3 --- doc/source/alarm-state-config.rst | 2 +- doc/source/resource-state-config.rst | 2 +- etc/vitrage/datasources_values/aodh.yaml | 29 ++- .../datasources_values/cinder.volume.yaml | 40 +-- etc/vitrage/datasources_values/nagios.yaml | 26 +- .../datasources_values/neutron.network.yaml | 29 +-- .../datasources_values/neutron.port.yaml | 33 +-- etc/vitrage/datasources_values/nova.host.yaml | 26 +- .../datasources_values/nova.instance.yaml | 65 ++--- etc/vitrage/datasources_values/nova.zone.yaml | 26 +- .../datasources_values/openstack.cluster.yaml | 26 +- .../datasources_values/static_physical.yaml | 20 +- etc/vitrage/datasources_values/switch.yaml | 24 +- etc/vitrage/datasources_values/vitrage.yaml | 24 +- vitrage/common/constants.py | 4 +- .../{states => mappings}/__init__.py | 0 .../entity_graph/mappings/alarm_handler.py | 42 +++ .../mappings/datasource_info_mapper.py | 225 ++++++++++++++++ .../handler_base.py} | 18 +- .../operational_alarm_severity.py} | 7 +- .../operational_resource_state.py} | 14 +- .../entity_graph/mappings/resource_handler.py | 42 +++ vitrage/entity_graph/processor/processor.py | 5 +- .../entity_graph/states/alarm_normalizator.py | 45 ---- .../states/resource_normalizator.py | 44 ---- vitrage/entity_graph/states/state_manager.py | 244 ------------------ .../notifier/plugins/aodh/aodh_notifier.py | 10 +- ...ager.py => test_datasource_info_mapper.py} | 18 +- .../evaluator/test_action_executor.py | 18 +- .../evaluator/test_scenario_evaluator.py | 4 +- .../erroneous_values/nagios.yaml | 28 +- .../erroneous_values/nova.host.yaml | 25 +- .../erroneous_values/nova.instance.yaml | 65 ++--- .../resources/datasources_values/nagios.yaml | 26 +- .../datasources_values/nova.host.yaml | 26 +- .../datasources_values/nova.instance.yaml | 65 ++--- .../datasources_values/nova.zone.yaml | 26 +- .../resources/datasources_values/vitrage.yaml | 22 +- .../entity_graph/processor/test_processor.py | 28 +- ...ager.py => test_datasource_info_mapper.py} | 145 ++++++++--- vitrage_tempest_tests/tests/utils.py | 8 +- 41 files changed, 813 insertions(+), 763 deletions(-) rename vitrage/entity_graph/{states => mappings}/__init__.py (100%) create mode 100644 vitrage/entity_graph/mappings/alarm_handler.py create mode 100644 vitrage/entity_graph/mappings/datasource_info_mapper.py rename vitrage/entity_graph/{states/normalizator_base.py => mappings/handler_base.py} (69%) rename vitrage/entity_graph/{states/normalized_alarm_severity.py => mappings/operational_alarm_severity.py} (84%) rename vitrage/entity_graph/{states/normalized_resource_state.py => mappings/operational_resource_state.py} (73%) create mode 100644 vitrage/entity_graph/mappings/resource_handler.py delete mode 100644 vitrage/entity_graph/states/alarm_normalizator.py delete mode 100644 vitrage/entity_graph/states/resource_normalizator.py delete mode 100644 vitrage/entity_graph/states/state_manager.py rename vitrage/tests/functional/entity_graph/states/{test_state_manager.py => test_datasource_info_mapper.py} (80%) rename vitrage/tests/unit/entity_graph/states/{test_state_manager.py => test_datasource_info_mapper.py} (54%) diff --git a/doc/source/alarm-state-config.rst b/doc/source/alarm-state-config.rst index 94766f3ef..e628ed159 100644 --- a/doc/source/alarm-state-config.rst +++ b/doc/source/alarm-state-config.rst @@ -40,7 +40,7 @@ The alarm severity configuration files configure how the severity of each alarm is normalized. There are several guidelines for creating a config file: - Normalized alarm values which can be mapped to can be found in - normalized_alarm_severity.py (NormalizedAlarmSeverity class). + normalized_alarm_severity.py (OperationalAlarmSeverity class). - Each normalized severity also comes with a priority, so that if an alarm is given different severities from different sources (e.g., a host alarm raised both by nagios and Vitrage), the severity with the diff --git a/doc/source/resource-state-config.rst b/doc/source/resource-state-config.rst index 9a9675fe3..62e1ca5f9 100644 --- a/doc/source/resource-state-config.rst +++ b/doc/source/resource-state-config.rst @@ -40,7 +40,7 @@ The resource state configuration files configure how the state of each resource is normalized. Some guidelines for creating a config file: - Normalized state values, to which states should be mapped, can be found in - normalized_resource_state.py (NormalizedResourceState class). + normalized_resource_state.py (OperationalResourceState class). - Each normalized state also comes with a priority, so that if a resource is given different states from different sources (e.g., a host state set both by nagios and Vitrage), the state with the diff --git a/etc/vitrage/datasources_values/aodh.yaml b/etc/vitrage/datasources_values/aodh.yaml index 1d9962a56..14d891884 100644 --- a/etc/vitrage/datasources_values/aodh.yaml +++ b/etc/vitrage/datasources_values/aodh.yaml @@ -1,28 +1,29 @@ category: ALARM values: - - normalized value: - name: CRITICAL - priority: 50 - original values: - - name: critical - - normalized value: - name: SEVERE + - aggregated values: priority: 40 original values: - - name: moderate - - normalized value: - name: WARNING + - name: critical + operational_value: CRITICAL + - aggregated values: priority: 30 + original values: + - name: moderate + operational_value: SEVERE + - aggregated values: + priority: 20 original values: - name: low - - normalized value: - name: UNKNOWN + operational_value: WARNING + - aggregated values: priority: 20 original values: - name: insufficient data - - normalized value: - name: DISABLED + operational_value: N/A + - aggregated values: priority: 10 original values: - name: OK + operational_value: OK - name: UP + operational_value: OK diff --git a/etc/vitrage/datasources_values/cinder.volume.yaml b/etc/vitrage/datasources_values/cinder.volume.yaml index fb20e0982..585b96f53 100644 --- a/etc/vitrage/datasources_values/cinder.volume.yaml +++ b/etc/vitrage/datasources_values/cinder.volume.yaml @@ -1,36 +1,40 @@ category: RESOURCE values: - - normalized value: - name: ERROR - priority: 50 - original values: - - name: ERROR - - name: ERROR_DELETING - - name: ERROR_RESTORING - - name: ERROR_EXTENDING - - normalized value: - name: UNRECOGNIZED + - aggregated values: priority: 40 original values: - - name: UNRECOGNIZED - - normalized value: - name: TRANSIENT + - name: ERROR + operational_value: ERROR + - name: ERROR_DELETING + operational_value: ERROR + - name: ERROR_RESTORING + operational_value: ERROR + - name: ERROR_EXTENDING + operational_value: ERROR + - aggregated values: priority: 30 original values: - name: CREATING + operational_value: TRANSIENT - name: ATTACHING + operational_value: TRANSIENT - name: DELETING + operational_value: TRANSIENT - name: RESTORING-BACKUP + operational_value: TRANSIENT - name: BACKING-UP + operational_value: TRANSIENT - name: DETACHING - - normalized value: - name: SUBOPTIMAL + operational_value: TRANSIENT + - aggregated values: priority: 20 original values: - name: SUBOPTIMAL - - normalized value: - name: RUNNING + operational_value: SUBOPTIMAL + - aggregated values: priority: 10 original values: - - name: IN-USE - name: AVAILABLE + operational_value: OK + - name: IN-USE + operational_value: OK diff --git a/etc/vitrage/datasources_values/nagios.yaml b/etc/vitrage/datasources_values/nagios.yaml index 0027ce6f6..36137da95 100644 --- a/etc/vitrage/datasources_values/nagios.yaml +++ b/etc/vitrage/datasources_values/nagios.yaml @@ -1,28 +1,26 @@ category: ALARM values: - - normalized value: - name: CRITICAL - priority: 50 - original values: - - name: CRITICAL - - name: DOWN - - normalized value: - name: SEVERE + - aggregated values: priority: 40 original values: - - normalized value: - name: WARNING + - name: CRITICAL + operational_value: CRITICAL + - name: DOWN + operational_value: CRITICAL + - aggregated values: priority: 30 original values: - name: WARNING - - normalized value: - name: UNKNOWN + operational_value: WARNING + - aggregated values: priority: 20 original values: - name: UNKNOWN - - normalized value: - name: DISABLED + operational_value: N/A + - aggregated values: priority: 10 original values: - name: OK + operational_value: OK - name: UP + operational_value: OK diff --git a/etc/vitrage/datasources_values/neutron.network.yaml b/etc/vitrage/datasources_values/neutron.network.yaml index ac50e77d6..a55a0261c 100644 --- a/etc/vitrage/datasources_values/neutron.network.yaml +++ b/etc/vitrage/datasources_values/neutron.network.yaml @@ -1,32 +1,27 @@ category: RESOURCE values: - - normalized value: - name: ERROR - priority: 60 - original values: - - name: ERROR - - normalized value: - name: UNRECOGNIZED + - aggregated values: priority: 50 original values: - - name: UNRECOGNIZED - - normalized value: - name: SUSPENDED + - name: ERROR + operational_value: ERROR + - aggregated values: priority: 40 original values: - name: DOWN - - normalized value: - name: TRANSIENT + operational_value: ERROR + - aggregated values: priority: 30 original values: - name: BUILD - - normalized value: - name: SUBOPTIMAL + operational_value: TRANSIENT + - aggregated values: priority: 20 original values: - name: SUBOPTIMAL - - normalized value: - name: RUNNING + operational_value: SUBOPTIMAL + - aggregated values: priority: 10 original values: - - name: ACTIVE \ No newline at end of file + - name: ACTIVE + operational_value: OK diff --git a/etc/vitrage/datasources_values/neutron.port.yaml b/etc/vitrage/datasources_values/neutron.port.yaml index db3631eaf..197add4a1 100644 --- a/etc/vitrage/datasources_values/neutron.port.yaml +++ b/etc/vitrage/datasources_values/neutron.port.yaml @@ -1,37 +1,32 @@ category: RESOURCE values: - - normalized value: - name: ERROR - priority: 70 - original values: - - name: ERROR - - normalized value: - name: UNRECOGNIZED + - aggregated values: priority: 60 original values: - - name: UNRECOGNIZED - - normalized value: - name: SUSPENDED + - name: ERROR + operational_value: ERROR + - aggregated values: priority: 50 original values: - name: DOWN - - normalized value: - name: TRANSIENT + operational_value: ERROR + - aggregated values: priority: 40 original values: - name: BUILD - - normalized value: - name: UNDEFINED + operational_value: TRANSIENT + - aggregated values: priority: 30 original values: - name: 'N/A' - - normalized value: - name: SUBOPTIMAL + operational_value: N/A + - aggregated values: priority: 20 original values: - name: SUBOPTIMAL - - normalized value: - name: RUNNING + operational_value: SUBOPTIMAL + - aggregated values: priority: 10 original values: - - name: ACTIVE \ No newline at end of file + - name: ACTIVE + operational_value: OK diff --git a/etc/vitrage/datasources_values/nova.host.yaml b/etc/vitrage/datasources_values/nova.host.yaml index e3b24252a..129ba9800 100644 --- a/etc/vitrage/datasources_values/nova.host.yaml +++ b/etc/vitrage/datasources_values/nova.host.yaml @@ -1,26 +1,22 @@ category: RESOURCE values: - - normalized value: - name: TERMINATED - priority: 50 - original values: - - name: DELETED - - normalized value: - name: ERROR + - aggregated values: priority: 40 original values: - - name: ERROR - - normalized value: - name: UNRECOGNIZED + - name: DELETED + operational_value: DELETED + - aggregated values: priority: 30 original values: - - normalized value: - name: SUBOPTIMAL + - name: ERROR + operational_value: ERROR + - aggregated values: priority: 20 original values: - name: SUBOPTIMAL - - normalized value: - name: RUNNING + operational_value: SUBOPTIMAL + - aggregated values: priority: 10 original values: - - name: available + - name: AVAILABLE + operational_value: OK diff --git a/etc/vitrage/datasources_values/nova.instance.yaml b/etc/vitrage/datasources_values/nova.instance.yaml index ef0f19f12..bccb3a84e 100644 --- a/etc/vitrage/datasources_values/nova.instance.yaml +++ b/etc/vitrage/datasources_values/nova.instance.yaml @@ -1,55 +1,56 @@ category: RESOURCE values: - - normalized value: - name: TERMINATED - priority: 90 - original values: - - name: DELETED - - name: HARD_DELETED - - name: SHELVED_OFFLOADED - - name: SOFT_DELETED - - normalized value: - name: ERROR + - aggregated values: priority: 80 original values: - - name: ERROR - - normalized value: - name: UNRECOGNIZED + - name: DELETED + operational_value: DELETED + - name: HARD_DELETED + operational_value: DELETED + - name: SHELVED_OFFLOADED + operational_value: DELETED + - name: SOFT_DELETED + operational_value: DELETED + - aggregated values: priority: 70 original values: - - name: UNRECOGNIZED - - normalized value: - name: SUSPENDED + - name: ERROR + operational_value: ERROR + - aggregated values: priority: 60 original values: - name: SUSPENDED + operational_value: SUBOPTIMAL - name: PAUSED + operational_value: SUBOPTIMAL - name: STOPPED + operational_value: SUBOPTIMAL - name: SHELVED - - normalized value: - name: RESCUED + operational_value: SUBOPTIMAL + - aggregated values: priority: 50 original values: - - name: RESCUED - - normalized value: - name: RESIZED + - name: RESIZED + operational_value: SUBOPTIMAL + - aggregated values: priority: 40 original values: - - name: RESIZED - - normalized value: - name: TRANSIENT + - name: BUILDING + operational_value: TRANSIENT + - name: INITIALIZED + operational_value: TRANSIENT + - aggregated values: priority: 30 original values: - - name: BUILDING - - name: INITIALIZED - - normalized value: - name: SUBOPTIMAL + - name: SUBOPTIMAL + operational_value: SUBOPTIMAL + - aggregated values: priority: 20 original values: - - name: SUBOPTIMAL - - normalized value: - name: RUNNING + - name: RESCUED + operational_value: OK + - aggregated values: priority: 10 original values: - name: ACTIVE - - name: RESIZED + operational_value: OK diff --git a/etc/vitrage/datasources_values/nova.zone.yaml b/etc/vitrage/datasources_values/nova.zone.yaml index e3b24252a..129ba9800 100644 --- a/etc/vitrage/datasources_values/nova.zone.yaml +++ b/etc/vitrage/datasources_values/nova.zone.yaml @@ -1,26 +1,22 @@ category: RESOURCE values: - - normalized value: - name: TERMINATED - priority: 50 - original values: - - name: DELETED - - normalized value: - name: ERROR + - aggregated values: priority: 40 original values: - - name: ERROR - - normalized value: - name: UNRECOGNIZED + - name: DELETED + operational_value: DELETED + - aggregated values: priority: 30 original values: - - normalized value: - name: SUBOPTIMAL + - name: ERROR + operational_value: ERROR + - aggregated values: priority: 20 original values: - name: SUBOPTIMAL - - normalized value: - name: RUNNING + operational_value: SUBOPTIMAL + - aggregated values: priority: 10 original values: - - name: available + - name: AVAILABLE + operational_value: OK diff --git a/etc/vitrage/datasources_values/openstack.cluster.yaml b/etc/vitrage/datasources_values/openstack.cluster.yaml index e3b24252a..129ba9800 100644 --- a/etc/vitrage/datasources_values/openstack.cluster.yaml +++ b/etc/vitrage/datasources_values/openstack.cluster.yaml @@ -1,26 +1,22 @@ category: RESOURCE values: - - normalized value: - name: TERMINATED - priority: 50 - original values: - - name: DELETED - - normalized value: - name: ERROR + - aggregated values: priority: 40 original values: - - name: ERROR - - normalized value: - name: UNRECOGNIZED + - name: DELETED + operational_value: DELETED + - aggregated values: priority: 30 original values: - - normalized value: - name: SUBOPTIMAL + - name: ERROR + operational_value: ERROR + - aggregated values: priority: 20 original values: - name: SUBOPTIMAL - - normalized value: - name: RUNNING + operational_value: SUBOPTIMAL + - aggregated values: priority: 10 original values: - - name: available + - name: AVAILABLE + operational_value: OK diff --git a/etc/vitrage/datasources_values/static_physical.yaml b/etc/vitrage/datasources_values/static_physical.yaml index 804d7c855..129ba9800 100644 --- a/etc/vitrage/datasources_values/static_physical.yaml +++ b/etc/vitrage/datasources_values/static_physical.yaml @@ -1,6 +1,22 @@ category: RESOURCE values: - - normalized value: - name: UNRECOGNIZED + - aggregated values: + priority: 40 + original values: + - name: DELETED + operational_value: DELETED + - aggregated values: + priority: 30 + original values: + - name: ERROR + operational_value: ERROR + - aggregated values: + priority: 20 + original values: + - name: SUBOPTIMAL + operational_value: SUBOPTIMAL + - aggregated values: priority: 10 original values: + - name: AVAILABLE + operational_value: OK diff --git a/etc/vitrage/datasources_values/switch.yaml b/etc/vitrage/datasources_values/switch.yaml index e3b24252a..358c6c2d2 100644 --- a/etc/vitrage/datasources_values/switch.yaml +++ b/etc/vitrage/datasources_values/switch.yaml @@ -1,26 +1,22 @@ category: RESOURCE values: - - normalized value: - name: TERMINATED - priority: 50 - original values: - - name: DELETED - - normalized value: - name: ERROR + - aggregated values: priority: 40 original values: - - name: ERROR - - normalized value: - name: UNRECOGNIZED + - name: DELETED + operational_value: DELETED + - aggregated values: priority: 30 original values: - - normalized value: - name: SUBOPTIMAL + - name: ERROR + operational_value: ERROR + - aggregated values: priority: 20 original values: - name: SUBOPTIMAL - - normalized value: - name: RUNNING + operational_value: SUBOPTIMAL + - aggregated values: priority: 10 original values: - name: available + operational_value: OK diff --git a/etc/vitrage/datasources_values/vitrage.yaml b/etc/vitrage/datasources_values/vitrage.yaml index 690ec2150..05aa36406 100644 --- a/etc/vitrage/datasources_values/vitrage.yaml +++ b/etc/vitrage/datasources_values/vitrage.yaml @@ -1,27 +1,31 @@ category: ALARM values: - - normalized value: - name: CRITICAL + - aggregated values: priority: 50 original values: - name: CRITICAL - - normalized value: - name: SEVERE + operational_value: CRITICAL + - aggregated values: priority: 40 original values: - name: SEVERE - - normalized value: - name: WARNING + operational_value: SEVERE + - name: MAJOR + operational_value: SEVERE + - aggregated values: priority: 30 original values: - name: WARNING - - normalized value: - name: UNKNOWN + operational_value: WARNING + - name: MINOR + operational_value: WARNING + - aggregated values: priority: 20 original values: - name: UNKNOWN - - normalized value: - name: DISABLED + operational_value: N/A + - aggregated values: priority: 10 original values: - name: OK + operational_value: OK \ No newline at end of file diff --git a/vitrage/common/constants.py b/vitrage/common/constants.py index 4e98d4038..33b1793f2 100644 --- a/vitrage/common/constants.py +++ b/vitrage/common/constants.py @@ -22,13 +22,15 @@ class VertexProperties(object): STATE = 'state' VITRAGE_STATE = 'vitrage_state' AGGREGATED_STATE = 'aggregated_state' + OPERATIONAL_STATE = 'operational_state' PROJECT_ID = 'project_id' UPDATE_TIMESTAMP = 'update_timestamp' SAMPLE_TIMESTAMP = 'sample_timestamp' NAME = 'name' IS_PLACEHOLDER = 'is_placeholder' SEVERITY = 'severity' - NORMALIZED_SEVERITY = 'normalized_severity' + AGGREGATED_SEVERITY = 'aggregated_severity' + OPERATIONAL_SEVERITY = 'operational_severity' VITRAGE_ID = 'vitrage_id' INFO = 'info' GRAPH_INDEX = 'graph_index' diff --git a/vitrage/entity_graph/states/__init__.py b/vitrage/entity_graph/mappings/__init__.py similarity index 100% rename from vitrage/entity_graph/states/__init__.py rename to vitrage/entity_graph/mappings/__init__.py diff --git a/vitrage/entity_graph/mappings/alarm_handler.py b/vitrage/entity_graph/mappings/alarm_handler.py new file mode 100644 index 000000000..6f52579a1 --- /dev/null +++ b/vitrage/entity_graph/mappings/alarm_handler.py @@ -0,0 +1,42 @@ +# 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 VertexProperties as VProps +from vitrage.entity_graph.mappings.handler_base import HandlerBase +from vitrage.entity_graph.mappings.operational_alarm_severity \ + import OperationalAlarmSeverity + + +class AlarmHandler(HandlerBase): + + def __init__(self): + super(AlarmHandler, self).__init__() + + def undefined_property(self): + return OperationalAlarmSeverity.NA + + def value_properties(self): + return [VProps.SEVERITY] + + def set_operational_value(self, new_vertex, operational_value): + new_vertex[VProps.OPERATIONAL_SEVERITY] = operational_value + + def set_aggregated_value(self, new_vertex, aggregated_value): + new_vertex[VProps.AGGREGATED_SEVERITY] = aggregated_value + + def default_values(self): + return [(None, OperationalAlarmSeverity.NA, 0)] + + def get_value_class_instance(self): + return OperationalAlarmSeverity() diff --git a/vitrage/entity_graph/mappings/datasource_info_mapper.py b/vitrage/entity_graph/mappings/datasource_info_mapper.py new file mode 100644 index 000000000..51ae5f266 --- /dev/null +++ b/vitrage/entity_graph/mappings/datasource_info_mapper.py @@ -0,0 +1,225 @@ +# 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. + +import os + +from oslo_log import log + +from vitrage.common.constants import EntityCategory +from vitrage.common.constants import VertexProperties as VProps +from vitrage.common import file_utils +from vitrage.entity_graph.mappings.alarm_handler import AlarmHandler +from vitrage.entity_graph.mappings.resource_handler import \ + ResourceHandler + +LOG = log.getLogger(__name__) + + +class DatasourceInfoMapper(object): + OPERATIONAL_VALUES = 'operational_values' + PRIORITY_VALUES = 'priority_values' + UNDEFINED_DATASOURCE = 'undefined datasource' + + def __init__(self, conf): + self.conf = conf + self.category_normalizer = self._init_category_normalizer() + self.datasources_state_confs = self._load_state_configurations() + + def operational_state(self, datasource_name, state): + return self._get_state_data(datasource_name, + state, + self.OPERATIONAL_VALUES) + + def state_priority(self, datasource_name, state): + return self._get_state_data(datasource_name, + state, + self.PRIORITY_VALUES) + + def aggregated_state(self, new_vertex, graph_vertex): + datasource_name = new_vertex[VProps.TYPE] if \ + VProps.TYPE in new_vertex.properties else \ + graph_vertex[VProps.TYPE] + + category = new_vertex[VProps.CATEGORY] if \ + VProps.CATEGORY in new_vertex.properties else \ + graph_vertex[VProps.CATEGORY] + + if datasource_name in self.datasources_state_confs: + value_properties = \ + self.category_normalizer[category].value_properties() + operational_state, aggregated_state, state_priority = \ + self._find_operational_state_and_priority(new_vertex, + graph_vertex, + value_properties[0], + datasource_name) + value_properties.pop(0) + + for property_ in value_properties: + t_operational_state, t_aggregated_state, t_state_priority = \ + self._find_operational_state_and_priority(new_vertex, + graph_vertex, + property_, + datasource_name) + if t_state_priority > state_priority: + operational_state = t_operational_state + aggregated_state = t_aggregated_state + state_priority = t_state_priority + + self.category_normalizer[category].set_aggregated_value( + new_vertex, aggregated_state) + self.category_normalizer[category].set_operational_value( + new_vertex, operational_state) + else: + self.category_normalizer[category].set_aggregated_value( + new_vertex, self.UNDEFINED_DATASOURCE) + self.category_normalizer[category].set_operational_value( + new_vertex, self.UNDEFINED_DATASOURCE) + + @staticmethod + def _init_category_normalizer(): + return { + EntityCategory.RESOURCE: ResourceHandler(), + EntityCategory.ALARM: AlarmHandler() + } + + def _load_state_configurations(self): + valid_datasources_conf = {} + erroneous_datasources_conf = [] + + files = file_utils.load_files( + self.conf.entity_graph.datasources_values_dir, '.yaml') + + for file_name in files: + try: + full_path = self.conf.entity_graph.datasources_values_dir \ + + '/' + file_name + operational_values, priority_values = \ + self._retrieve_states_and_priorities_from_file(full_path) + valid_datasources_conf[os.path.splitext(file_name)[0]] = { + self.OPERATIONAL_VALUES: operational_values, + self.PRIORITY_VALUES: priority_values + } + except Exception as e: + LOG.exception("Exception: %s", e) + datasource = os.path.splitext(file_name)[0] + LOG.error('erroneous data sources is %s', + erroneous_datasources_conf.append(datasource)) + + self._check_state_confs_exists( + [key for key in valid_datasources_conf.keys()], + erroneous_datasources_conf) + + return valid_datasources_conf + + def _retrieve_states_and_priorities_from_file(self, full_path): + states = {} + priorities = {} + config = file_utils.load_yaml_file(full_path, with_exception=True) + category = config['category'] + + for item in config['values']: + aggregated_values = item['aggregated values'] + priority_value = int(aggregated_values['priority']) + + # original to operational value + for original_state in aggregated_values['original values']: + original_value = original_state['name'] + operational_value = original_state['operational_value'] + states[original_value.upper()] = operational_value + priorities[original_value.upper()] = priority_value + + self._check_validity(category, states, priorities, full_path) + + self._add_default_states(states, priorities, category) + + return states, priorities + + def _add_default_states(self, states, priorities, category): + default_values = self.category_normalizer[category].default_values() + for original_val, operational_val, priority_val in default_values: + states[original_val] = operational_val + priorities[original_val] = priority_val + + def _check_validity(self, category, states, priorities, full_path): + # check that all the operational values exists + state_class_instance = \ + self.category_normalizer[category].get_value_class_instance() + operational_values = DatasourceInfoMapper.\ + _get_all_local_variables_of_class(state_class_instance) + for operational_value in states.values(): + if operational_value not in operational_values: + raise ValueError('operational value %s for %s is not in %s', + operational_value, full_path, + state_class_instance.__class__.__name__) + + def _get_state_data(self, datasource_name, state, data_type): + try: + upper_state = state if not state else state.upper() + + if datasource_name in self.datasources_state_confs: + values_conf = self.datasources_state_confs[ + datasource_name][data_type] + + return values_conf[upper_state] if upper_state in values_conf \ + else values_conf[None] + else: + return self.UNDEFINED_DATASOURCE + except Exception: + LOG.error('Exception in datasource: %s', datasource_name) + raise + + def _find_operational_state_and_priority(self, + new_vertex, + graph_vertex, + property_, + datasource_name): + state = self._get_updated_property(new_vertex, + graph_vertex, + property_) + + upper_state = state if not state else state.upper() + + operational_state = self.operational_state(datasource_name, + upper_state) + + state_priority = self.state_priority(datasource_name, + upper_state) + + return operational_state, upper_state, state_priority + + @staticmethod + def _get_all_local_variables_of_class(class_instance): + return [getattr(class_instance, attr) for attr in dir(class_instance) + if not callable(attr) and not attr.startswith("__")] + + def _check_state_confs_exists(self, + ok_datasources, + error_datasources): + + datasource_types = self.conf.datasources.types + datasources_with_state_conf = ok_datasources + error_datasources + + for datasource_type in datasource_types: + if datasource_type not in datasources_with_state_conf: + LOG.info("No state configuration file for: %s", + datasource_type) + + @staticmethod + def _get_updated_property(new_vertex, graph_vertex, prop): + if new_vertex and prop in new_vertex.properties: + return new_vertex[prop] + elif graph_vertex and prop in graph_vertex.properties: + return graph_vertex[prop] + + return None diff --git a/vitrage/entity_graph/states/normalizator_base.py b/vitrage/entity_graph/mappings/handler_base.py similarity index 69% rename from vitrage/entity_graph/states/normalizator_base.py rename to vitrage/entity_graph/mappings/handler_base.py index b8c6f833a..0207a15ec 100644 --- a/vitrage/entity_graph/states/normalizator_base.py +++ b/vitrage/entity_graph/mappings/handler_base.py @@ -13,40 +13,36 @@ # under the License. import abc -from collections import namedtuple import six -ImportantStates = namedtuple('ImportantStates', ['unknown', 'undefined']) - - @six.add_metaclass(abc.ABCMeta) -class NormalizatorBase(object): +class HandlerBase(object): def __init__(self): pass @abc.abstractmethod - def important_states(self): + def undefined_property(self): pass @abc.abstractmethod - def state_properties(self): + def value_properties(self): pass @abc.abstractmethod - def set_aggregated_state(self, new_vertex, normalized_state): + def set_aggregated_value(self, new_vertex, aggregated_value): pass @abc.abstractmethod - def set_undefined_state(self, new_vertex): + def set_operational_value(self, new_vertex, operational_value): pass @abc.abstractmethod - def default_states(self): + def default_values(self): pass @abc.abstractmethod - def get_state_class_instance(self): + def get_value_class_instance(self): pass diff --git a/vitrage/entity_graph/states/normalized_alarm_severity.py b/vitrage/entity_graph/mappings/operational_alarm_severity.py similarity index 84% rename from vitrage/entity_graph/states/normalized_alarm_severity.py rename to vitrage/entity_graph/mappings/operational_alarm_severity.py index 2ff5eeaf2..78278c415 100644 --- a/vitrage/entity_graph/states/normalized_alarm_severity.py +++ b/vitrage/entity_graph/mappings/operational_alarm_severity.py @@ -13,10 +13,9 @@ # under the License. -class NormalizedAlarmSeverity(object): +class OperationalAlarmSeverity(object): CRITICAL = 'CRITICAL' SEVERE = 'SEVERE' WARNING = 'WARNING' - DISABLED = 'DISABLED' - UNKNOWN = 'UNKNOWN' - UNDEFINED = 'UNDEFINED' + NA = 'N/A' + OK = 'OK' diff --git a/vitrage/entity_graph/states/normalized_resource_state.py b/vitrage/entity_graph/mappings/operational_resource_state.py similarity index 73% rename from vitrage/entity_graph/states/normalized_resource_state.py rename to vitrage/entity_graph/mappings/operational_resource_state.py index 5af7a8d5b..2a298fa9a 100644 --- a/vitrage/entity_graph/states/normalized_resource_state.py +++ b/vitrage/entity_graph/mappings/operational_resource_state.py @@ -13,14 +13,10 @@ # under the License. -class NormalizedResourceState(object): - TERMINATED = 'TERMINATED' - ERROR = 'ERROR' - UNRECOGNIZED = 'UNRECOGNIZED' - SUSPENDED = 'SUSPENDED' - RESCUED = 'RESCUED' - RESIZED = 'RESIZED' +class OperationalResourceState(object): + NA = 'N/A' + OK = 'OK' TRANSIENT = 'TRANSIENT' SUBOPTIMAL = 'SUBOPTIMAL' - RUNNING = 'RUNNING' - UNDEFINED = 'UNDEFINED' + ERROR = 'ERROR' + DELETED = 'DELETED' diff --git a/vitrage/entity_graph/mappings/resource_handler.py b/vitrage/entity_graph/mappings/resource_handler.py new file mode 100644 index 000000000..4b4c49277 --- /dev/null +++ b/vitrage/entity_graph/mappings/resource_handler.py @@ -0,0 +1,42 @@ +# 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 VertexProperties as VProps +from vitrage.entity_graph.mappings.handler_base import HandlerBase +from vitrage.entity_graph.mappings.operational_resource_state \ + import OperationalResourceState + + +class ResourceHandler(HandlerBase): + + def __init__(self): + super(ResourceHandler, self).__init__() + + def undefined_property(self): + return OperationalResourceState.NA + + def value_properties(self): + return [VProps.STATE, VProps.VITRAGE_STATE] + + def set_operational_value(self, new_vertex, operational_value): + new_vertex[VProps.OPERATIONAL_STATE] = operational_value + + def set_aggregated_value(self, new_vertex, aggregated_value): + new_vertex[VProps.AGGREGATED_STATE] = aggregated_value + + def default_values(self): + return [(None, OperationalResourceState.NA, 0)] + + def get_value_class_instance(self): + return OperationalResourceState() diff --git a/vitrage/entity_graph/processor/processor.py b/vitrage/entity_graph/processor/processor.py index 8fdba317c..c6ff6b981 100644 --- a/vitrage/entity_graph/processor/processor.py +++ b/vitrage/entity_graph/processor/processor.py @@ -18,11 +18,12 @@ from oslo_log import log from vitrage.common.constants import EventAction from vitrage.common.constants import VertexProperties as VProps from vitrage.datasources.transformer_base import TransformerBase +from vitrage.entity_graph.mappings.datasource_info_mapper import \ + DatasourceInfoMapper from vitrage.entity_graph.processor import base as processor from vitrage.entity_graph.processor import entity_graph from vitrage.entity_graph.processor.notifier import DeducedAlarmNotifier from vitrage.entity_graph.processor import processor_utils as PUtils -from vitrage.entity_graph.states.state_manager import StateManager from vitrage.entity_graph.transformer_manager import TransformerManager from vitrage.graph import Direction @@ -35,7 +36,7 @@ class Processor(processor.ProcessorBase): super(Processor, self).__init__() self.conf = conf self.transformer_manager = TransformerManager(self.conf) - self.state_manager = StateManager(self.conf) + self.state_manager = DatasourceInfoMapper(self.conf) self._initialize_events_actions() self.initialization_status = initialization_status self.entity_graph = entity_graph.EntityGraph("Entity Graph") if \ diff --git a/vitrage/entity_graph/states/alarm_normalizator.py b/vitrage/entity_graph/states/alarm_normalizator.py deleted file mode 100644 index a060c035b..000000000 --- a/vitrage/entity_graph/states/alarm_normalizator.py +++ /dev/null @@ -1,45 +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 VertexProperties as VProps -from vitrage.entity_graph.states.normalizator_base import ImportantStates -from vitrage.entity_graph.states.normalizator_base import NormalizatorBase -from vitrage.entity_graph.states.normalized_alarm_severity \ - import NormalizedAlarmSeverity - - -class AlarmNormalizator(NormalizatorBase): - - def __init__(self): - super(AlarmNormalizator, self).__init__() - - def important_states(self): - return ImportantStates(NormalizedAlarmSeverity.UNKNOWN, - NormalizedAlarmSeverity.UNDEFINED) - - def state_properties(self): - return [VProps.SEVERITY] - - def set_aggregated_state(self, new_vertex, normalized_state): - new_vertex[VProps.NORMALIZED_SEVERITY] = normalized_state - - def set_undefined_state(self, new_vertex): - new_vertex[VProps.NORMALIZED_SEVERITY] = \ - NormalizedAlarmSeverity.UNDEFINED - - def default_states(self): - return [(NormalizedAlarmSeverity.UNDEFINED, 0)] - - def get_state_class_instance(self): - return NormalizedAlarmSeverity() diff --git a/vitrage/entity_graph/states/resource_normalizator.py b/vitrage/entity_graph/states/resource_normalizator.py deleted file mode 100644 index 8cd85f108..000000000 --- a/vitrage/entity_graph/states/resource_normalizator.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 vitrage.common.constants import VertexProperties as VProps -from vitrage.entity_graph.states.normalizator_base import ImportantStates -from vitrage.entity_graph.states.normalizator_base import NormalizatorBase -from vitrage.entity_graph.states.normalized_resource_state \ - import NormalizedResourceState - - -class ResourceNormalizator(NormalizatorBase): - - def __init__(self): - super(ResourceNormalizator, self).__init__() - - def important_states(self): - return ImportantStates(NormalizedResourceState.UNRECOGNIZED, - NormalizedResourceState.UNDEFINED) - - def state_properties(self): - return [VProps.STATE, VProps.VITRAGE_STATE] - - def set_undefined_state(self, new_vertex): - new_vertex[VProps.AGGREGATED_STATE] = NormalizedResourceState.UNDEFINED - - def set_aggregated_state(self, new_vertex, normalized_state): - new_vertex[VProps.AGGREGATED_STATE] = normalized_state - - def default_states(self): - return [(NormalizedResourceState.UNDEFINED, 0)] - - def get_state_class_instance(self): - return NormalizedResourceState() diff --git a/vitrage/entity_graph/states/state_manager.py b/vitrage/entity_graph/states/state_manager.py deleted file mode 100644 index 7126b8d5f..000000000 --- a/vitrage/entity_graph/states/state_manager.py +++ /dev/null @@ -1,244 +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. - -import os - -from oslo_log import log - -from vitrage.common.constants import EntityCategory -from vitrage.common.constants import VertexProperties as VProps -from vitrage.common import file_utils -from vitrage.entity_graph.states.alarm_normalizator import AlarmNormalizator -from vitrage.entity_graph.states.normalized_resource_state \ - import NormalizedResourceState -from vitrage.entity_graph.states.resource_normalizator import \ - ResourceNormalizator - -LOG = log.getLogger(__name__) - - -class StateManager(object): - VALUES = 'values' - PRIORITIES = 'priorities' - - def __init__(self, conf): - self.conf = conf - self.category_normalizator = self._init_category_normalizator() - self.datasources_state_confs = self._load_state_configurations() - - def normalize_state(self, category, datasource_name, state): - try: - upper_state = state if not state else state.upper() - important_states = \ - self.category_normalizator[category].important_states() - - if datasource_name in self.datasources_state_confs: - - states_conf = self.datasources_state_confs[datasource_name] - - return states_conf[self.VALUES][upper_state] \ - if upper_state in states_conf[self.VALUES] \ - else states_conf[self.VALUES][important_states.unknown] - else: - return important_states.undefined - except Exception: - LOG.error('Exception in datasource: %s', datasource_name) - raise - - def state_priority(self, datasource_name, normalized_state): - try: - # no need to check if normalized_state exists, cause it exists for - # sure - upper_state = normalized_state if not normalized_state else \ - normalized_state.upper() - - if datasource_name in self.datasources_state_confs: - states_conf = self.datasources_state_confs[datasource_name] - return states_conf[self.PRIORITIES][upper_state] - else: - # default UNDEFINED priority - return 0 - except Exception: - LOG.error('Exception in datasource: %s', datasource_name) - raise - - def aggregated_state(self, new_vertex, graph_vertex, is_normalized=False): - datasource_name = new_vertex[VProps.TYPE] if \ - VProps.TYPE in new_vertex.properties else \ - graph_vertex[VProps.TYPE] - - category = new_vertex[VProps.CATEGORY] if \ - VProps.CATEGORY in new_vertex.properties else \ - graph_vertex[VProps.CATEGORY] - - if datasource_name in self.datasources_state_confs: - state_properties = \ - self.category_normalizator[category].state_properties() - normalized_state, state_priority = \ - self._find_normalized_state_and_priority(new_vertex, - graph_vertex, - state_properties[0], - category, - datasource_name, - is_normalized) - state_properties.pop(0) - - for property_ in state_properties: - tmp_normalized_state, tmp_state_priority = \ - self._find_normalized_state_and_priority(new_vertex, - graph_vertex, - property_, - category, - datasource_name, - is_normalized) - if tmp_state_priority > state_priority: - normalized_state = tmp_normalized_state - state_priority = tmp_state_priority - - self.category_normalizator[category].set_aggregated_state( - new_vertex, normalized_state) - else: - self.category_normalizator[category].set_undefined_state( - new_vertex) - - @staticmethod - def _init_category_normalizator(): - return { - EntityCategory.RESOURCE: ResourceNormalizator(), - EntityCategory.ALARM: AlarmNormalizator() - } - - def _load_state_configurations(self): - ok_datasources = {} - erroneous_datasources = [] - - files = file_utils.load_files( - self.conf.entity_graph.datasources_values_dir, '.yaml') - - for file_name in files: - try: - full_path = self.conf.entity_graph.datasources_values_dir \ - + '/' + file_name - states, priorities = \ - self._retrieve_states_and_priorities_from_file(full_path) - ok_datasources[os.path.splitext(file_name)[0]] = { - self.VALUES: states, - self.PRIORITIES: priorities - } - except Exception as e: - LOG.exception("Exception: %s", e) - datasource = os.path.splitext(file_name)[0] - LOG.error('erroneous data sources is %s', - erroneous_datasources.append(datasource)) - - self._check_state_confs_exists( - [key for key in ok_datasources.keys()], - erroneous_datasources) - - return ok_datasources - - def _retrieve_states_and_priorities_from_file(self, full_path): - states = {} - priorities = {} - config = file_utils.load_yaml_file(full_path, with_exception=True) - category = config['category'] - - for item in config[self.VALUES]: - normalized_state = item['normalized value'] - - # original to normalized value - normalized_state_name = normalized_state['name'] - for original_state in normalized_state['original values']: - states[original_state['name'].upper()] = normalized_state_name - - self._add_default_states(states, priorities, category) - - # normalized value priority - priorities[normalized_state_name] = \ - int(normalized_state['priority']) - - self.check_validity(category, priorities, full_path) - - return states, priorities - - def _add_default_states(self, states, priorities, category): - default_values = self.category_normalizator[category].default_states() - for state, priority in default_values: - states[None] = state - priorities[NormalizedResourceState.UNDEFINED] = priority - - def check_validity(self, category, priorities, full_path): - important_states = \ - self.category_normalizator[category].important_states() - if important_states.unknown not in priorities: - raise ValueError('%s state is not defined in %s', - important_states.unknown, full_path) - - # check that all the normalized values exists - state_class_instance = \ - self.category_normalizator[category].get_state_class_instance() - normalized_values = StateManager._get_all_local_variables_of_class( - state_class_instance) - for key in priorities.keys(): - if key not in normalized_values: - raise ValueError('normalized value %s for %s is not in %s', - key, full_path, - state_class_instance.__class__.__name__) - - def _find_normalized_state_and_priority(self, - new_vertex, - graph_vertex, - property_, - category, - datasource_name, - is_normalized=False): - state = self._get_updated_property(new_vertex, - graph_vertex, - property_) - - upper_state1 = state if not state else state.upper() - - normalized_state = upper_state1 if is_normalized else \ - self.normalize_state(category, datasource_name, upper_state1) - - state_priority = self.state_priority(datasource_name, - normalized_state) - - return normalized_state, state_priority - - @staticmethod - def _get_all_local_variables_of_class(class_instance): - return [attr for attr in dir(class_instance) if not callable(attr) and - not attr.startswith("__")] - - def _check_state_confs_exists(self, - ok_datasources, - error_datasources): - - datasource_types = self.conf.datasources.types - datasources_with_state_conf = ok_datasources + error_datasources - - for datasource_type in datasource_types: - if datasource_type not in datasources_with_state_conf: - LOG.info("No state configuration file for: %s", - datasource_type) - - @staticmethod - def _get_updated_property(new_vertex, graph_vertex, prop): - if new_vertex and prop in new_vertex.properties: - return new_vertex[prop] - elif graph_vertex and prop in graph_vertex.properties: - return graph_vertex[prop] - - return None diff --git a/vitrage/notifier/plugins/aodh/aodh_notifier.py b/vitrage/notifier/plugins/aodh/aodh_notifier.py index 4993023ac..dbda3bd10 100644 --- a/vitrage/notifier/plugins/aodh/aodh_notifier.py +++ b/vitrage/notifier/plugins/aodh/aodh_notifier.py @@ -17,8 +17,8 @@ from vitrage import clients from vitrage.common.constants import NotifierEventTypes from vitrage.common.constants import VertexProperties as VProps from vitrage.datasources.aodh.properties import AodhState -from vitrage.entity_graph.states.normalized_alarm_severity import \ - NormalizedAlarmSeverity +from vitrage.entity_graph.mappings.operational_alarm_severity import \ + OperationalAlarmSeverity from vitrage.notifier.plugins.base import NotifierBase @@ -26,9 +26,9 @@ LOG = logging.getLogger(__name__) severity_translation = { - NormalizedAlarmSeverity.CRITICAL: 'critical', - NormalizedAlarmSeverity.SEVERE: 'moderate', - NormalizedAlarmSeverity.WARNING: 'low', + OperationalAlarmSeverity.CRITICAL: 'critical', + OperationalAlarmSeverity.SEVERE: 'moderate', + OperationalAlarmSeverity.WARNING: 'low', } diff --git a/vitrage/tests/functional/entity_graph/states/test_state_manager.py b/vitrage/tests/functional/entity_graph/states/test_datasource_info_mapper.py similarity index 80% rename from vitrage/tests/functional/entity_graph/states/test_state_manager.py rename to vitrage/tests/functional/entity_graph/states/test_datasource_info_mapper.py index b383f8788..d8e07f456 100644 --- a/vitrage/tests/functional/entity_graph/states/test_state_manager.py +++ b/vitrage/tests/functional/entity_graph/states/test_datasource_info_mapper.py @@ -19,18 +19,18 @@ from vitrage.common.constants import SyncMode from vitrage.common.constants import VertexProperties as VProps from vitrage.datasources.nova.instance.transformer import InstanceTransformer from vitrage.entity_graph.initialization_status import InitializationStatus +from vitrage.entity_graph.mappings.operational_resource_state import \ + OperationalResourceState from vitrage.entity_graph.processor import processor as proc -from vitrage.entity_graph.states.normalized_resource_state import \ - NormalizedResourceState from vitrage.tests.functional.base import TestFunctionalBase -class TestStateManagerFunctional(TestFunctionalBase): +class TestDatasourceInfoMapperFunctional(TestFunctionalBase): # noinspection PyAttributeOutsideInit,PyPep8Naming @classmethod def setUpClass(cls): - super(TestStateManagerFunctional, cls).setUpClass() + super(TestDatasourceInfoMapperFunctional, cls).setUpClass() cls.conf = cfg.ConfigOpts() cls.conf.register_opts(cls.PROCESSOR_OPTS, group='entity_graph') cls.conf.register_opts(cls.DATASOURCES_OPTS, group='datasources') @@ -49,8 +49,9 @@ class TestStateManagerFunctional(TestFunctionalBase): instance_transformer = InstanceTransformer({}) vitrage_id = instance_transformer._create_entity_key(event) vertex = processor.entity_graph.get_vertex(vitrage_id) - self.assertEqual(NormalizedResourceState.RUNNING, - vertex[VProps.AGGREGATED_STATE]) + self.assertEqual('ACTIVE', vertex[VProps.AGGREGATED_STATE]) + self.assertEqual(OperationalResourceState.OK, + vertex[VProps.OPERATIONAL_STATE]) def test_state_on_neighbor_update(self): # setup @@ -68,5 +69,6 @@ class TestStateManagerFunctional(TestFunctionalBase): # test assertions neighbor_vertex = processor.entity_graph.get_vertex( neighbors[0].vertex.vertex_id) - self.assertEqual(NormalizedResourceState.RUNNING, - neighbor_vertex[VProps.AGGREGATED_STATE]) + self.assertEqual('AVAILABLE', neighbor_vertex[VProps.AGGREGATED_STATE]) + self.assertEqual(OperationalResourceState.OK, + neighbor_vertex[VProps.OPERATIONAL_STATE]) diff --git a/vitrage/tests/functional/evaluator/test_action_executor.py b/vitrage/tests/functional/evaluator/test_action_executor.py index 7dc8e81b2..9731ea0b5 100644 --- a/vitrage/tests/functional/evaluator/test_action_executor.py +++ b/vitrage/tests/functional/evaluator/test_action_executor.py @@ -23,8 +23,8 @@ from vitrage.common.constants import VertexProperties as VProps from vitrage.datasources.alarm_properties import AlarmProperties as AlarmProps from vitrage.datasources.nagios import NAGIOS_DATASOURCE from vitrage.datasources.nova.host import NOVA_HOST_DATASOURCE -from vitrage.entity_graph.states.normalized_resource_state import \ - NormalizedResourceState +from vitrage.entity_graph.mappings.operational_resource_state import \ + OperationalResourceState from vitrage.evaluator.actions.action_executor import ActionExecutor from vitrage.evaluator.actions.base import ActionMode from vitrage.evaluator.actions.base import ActionType @@ -62,7 +62,7 @@ class TestActionExecutor(TestFunctionalBase): host_vertex_before = host_vertices[0] targets = {TFields.TARGET: host_vertex_before} - props = {TFields.STATE: NormalizedResourceState.SUBOPTIMAL} + props = {TFields.STATE: OperationalResourceState.SUBOPTIMAL} action_spec = ActionSpecs(ActionType.SET_STATE, targets, props) event_queue = queue.Queue() @@ -77,13 +77,14 @@ class TestActionExecutor(TestFunctionalBase): # Test Assertions agg_state_before = host_vertex_before.get(VProps.AGGREGATED_STATE) - self.assertTrue(agg_state_before != NormalizedResourceState.SUBOPTIMAL) + self.assertTrue(agg_state_before != + OperationalResourceState.SUBOPTIMAL) self.assertFalse(VProps.VITRAGE_STATE in host_vertex_before.properties) agg_state_after = host_vertex_after.get(VProps.AGGREGATED_STATE) - self.assertEqual(agg_state_after, NormalizedResourceState.SUBOPTIMAL) + self.assertEqual(agg_state_after, OperationalResourceState.SUBOPTIMAL) v_state_after = host_vertex_after.get(VProps.VITRAGE_STATE) - self.assertEqual(v_state_after, NormalizedResourceState.SUBOPTIMAL) + self.assertEqual(v_state_after, OperationalResourceState.SUBOPTIMAL) # Test Action - undo action_executor.execute(action_spec, ActionMode.UNDO) @@ -197,10 +198,11 @@ class TestActionExecutor(TestFunctionalBase): self.assertEqual(alarm.properties[VProps.CATEGORY], EntityCategory.ALARM) - self.assertEqual(alarm.properties[VProps.TYPE], VITRAGE_TYPE) + self.assertEqual(alarm.properties[VProps.TYPE], + VITRAGE_TYPE) self.assertEqual(alarm.properties[VProps.SEVERITY], props[TFields.SEVERITY]) - self.assertEqual(alarm.properties[VProps.NORMALIZED_SEVERITY], + self.assertEqual(alarm.properties[VProps.OPERATIONAL_SEVERITY], props[TFields.SEVERITY]) self.assertEqual(alarm.properties[VProps.STATE], AlarmProps.ALARM_ACTIVE_STATE) diff --git a/vitrage/tests/functional/evaluator/test_scenario_evaluator.py b/vitrage/tests/functional/evaluator/test_scenario_evaluator.py index dfc0bfa75..3194f6e30 100644 --- a/vitrage/tests/functional/evaluator/test_scenario_evaluator.py +++ b/vitrage/tests/functional/evaluator/test_scenario_evaluator.py @@ -62,7 +62,7 @@ class TestScenarioEvaluator(TestFunctionalBase): target_host = 'host-2' host_v = self._get_host_from_graph(target_host, processor.entity_graph) - self.assertEqual('RUNNING', host_v[VProps.AGGREGATED_STATE], + self.assertEqual('AVAILABLE', host_v[VProps.AGGREGATED_STATE], 'host should be RUNNING when starting') nagios_event = {'last_check': '2016-02-07 15:26:04', @@ -89,7 +89,7 @@ class TestScenarioEvaluator(TestFunctionalBase): processor.process_event(event_queue.get()) host_v = self._get_host_from_graph(target_host, processor.entity_graph) - self.assertEqual('RUNNING', host_v[VProps.AGGREGATED_STATE], + self.assertEqual('AVAILABLE', host_v[VProps.AGGREGATED_STATE], 'host should be RUNNING when starting') @staticmethod diff --git a/vitrage/tests/resources/datasources_values/erroneous_values/nagios.yaml b/vitrage/tests/resources/datasources_values/erroneous_values/nagios.yaml index 0027ce6f6..3e70eca05 100644 --- a/vitrage/tests/resources/datasources_values/erroneous_values/nagios.yaml +++ b/vitrage/tests/resources/datasources_values/erroneous_values/nagios.yaml @@ -1,28 +1,28 @@ category: ALARM values: - - normalized value: - name: CRITICAL - priority: 50 - original values: - - name: CRITICAL - - name: DOWN - - normalized value: - name: SEVERE + - aggregated values: priority: 40 original values: - - normalized value: - name: WARNING + - name: CRITICAL + operational_value: CRITICAL + - name: DOWN + operational_value: CRITICAL + - aggregated values: priority: 30 original values: - name: WARNING - - normalized value: - name: UNKNOWN + operational_value: WARNING + - aggregated values: priority: 20 original values: - name: UNKNOWN - - normalized value: - name: DISABLED + operational_value: N/A + - name: UNDEFINED + operational_value: N/A + - aggregated values: priority: 10 original values: - name: OK + operational_value: OK - name: UP + operational_value: OK \ No newline at end of file diff --git a/vitrage/tests/resources/datasources_values/erroneous_values/nova.host.yaml b/vitrage/tests/resources/datasources_values/erroneous_values/nova.host.yaml index 91c3e16e1..129ba9800 100644 --- a/vitrage/tests/resources/datasources_values/erroneous_values/nova.host.yaml +++ b/vitrage/tests/resources/datasources_values/erroneous_values/nova.host.yaml @@ -1,23 +1,22 @@ -# erroneous yaml file - missing normalized UNRECOGNIZED value category: RESOURCE values: - - normalized value: - name: TERMINATED - priority: 50 - original values: - - name: DELETED - - normalized value: - name: ERROR + - aggregated values: priority: 40 + original values: + - name: DELETED + operational_value: DELETED + - aggregated values: + priority: 30 original values: - name: ERROR - - normalized value: - name: SUBOPTIMAL + operational_value: ERROR + - aggregated values: priority: 20 original values: - name: SUBOPTIMAL - - normalized value: - name: RUNNING + operational_value: SUBOPTIMAL + - aggregated values: priority: 10 original values: - - name: available + - name: AVAILABLE + operational_value: OK diff --git a/vitrage/tests/resources/datasources_values/erroneous_values/nova.instance.yaml b/vitrage/tests/resources/datasources_values/erroneous_values/nova.instance.yaml index 7e4fd512c..fbdb1a778 100644 --- a/vitrage/tests/resources/datasources_values/erroneous_values/nova.instance.yaml +++ b/vitrage/tests/resources/datasources_values/erroneous_values/nova.instance.yaml @@ -1,56 +1,57 @@ # erroneous yaml file - parsing error in DELETED value category: RESOURCE values: - - normalized value: - name: TERMINATED - priority: 90 - original values: - - name: DELETED - - name: HARD_DELETED - - name: SHELVED_OFFLOADED - - name: SOFT_DELETED - - normalized value: - name: ERROR + - aggregated values: priority: 80 original values: - - name: ERROR - - normalized value: - name: UNRECOGNIZED + - name: DELETED + operational_value: DELETED + - name: HARD_DELETED + operational_value: DELETED + - name: SHELVED_OFFLOADED + operational_value: DELETED + - name: SOFT_DELETED + operational_value: DELETED + - aggregated values: priority: 70 original values: - - name: UNRECOGNIZED - - normalized value: - name: SUSPENDED + - name: ERROR + operational_value: ERROR + - aggregated values: priority: 60 original values: - name: SUSPENDED + operational_value: SUBOPTIMAL - name: PAUSED + operational_value: SUBOPTIMAL - name: STOPPED + operational_value: SUBOPTIMAL - name: SHELVED - - normalized value: - name: RESCUED + operational_value: SUBOPTIMAL + - aggregated values: priority: 50 original values: - - name: RESCUED - - normalized value: - name: RESIZED + - name: RESIZED + operational_value: SUBOPTIMAL + - aggregated values: priority: 40 original values: - - name: RESIZED - - normalized value: - name: TRANSIENT + - name: BUILDING + operational_value: TRANSIENT + - name: INITIALIZED + operational_value: TRANSIENT + - aggregated values: priority: 30 original values: - - name: BUILDING - - name: INITIALIZED - - normalized value: - name: SUBOPTIMAL + - name: SUBOPTIMAL + operational_value: SUBOPTIMAL + - aggregated values: priority: 20 original values: - - name: SUBOPTIMAL - - normalized value: - name: RUNNING + - name: RESCUED + operational_value: OK + - aggregated values: priority: 10 original values: - name: ACTIVE - - name: RESIZED + operational_value: OK diff --git a/vitrage/tests/resources/datasources_values/nagios.yaml b/vitrage/tests/resources/datasources_values/nagios.yaml index 0027ce6f6..36137da95 100644 --- a/vitrage/tests/resources/datasources_values/nagios.yaml +++ b/vitrage/tests/resources/datasources_values/nagios.yaml @@ -1,28 +1,26 @@ category: ALARM values: - - normalized value: - name: CRITICAL - priority: 50 - original values: - - name: CRITICAL - - name: DOWN - - normalized value: - name: SEVERE + - aggregated values: priority: 40 original values: - - normalized value: - name: WARNING + - name: CRITICAL + operational_value: CRITICAL + - name: DOWN + operational_value: CRITICAL + - aggregated values: priority: 30 original values: - name: WARNING - - normalized value: - name: UNKNOWN + operational_value: WARNING + - aggregated values: priority: 20 original values: - name: UNKNOWN - - normalized value: - name: DISABLED + operational_value: N/A + - aggregated values: priority: 10 original values: - name: OK + operational_value: OK - name: UP + operational_value: OK diff --git a/vitrage/tests/resources/datasources_values/nova.host.yaml b/vitrage/tests/resources/datasources_values/nova.host.yaml index e3b24252a..129ba9800 100644 --- a/vitrage/tests/resources/datasources_values/nova.host.yaml +++ b/vitrage/tests/resources/datasources_values/nova.host.yaml @@ -1,26 +1,22 @@ category: RESOURCE values: - - normalized value: - name: TERMINATED - priority: 50 - original values: - - name: DELETED - - normalized value: - name: ERROR + - aggregated values: priority: 40 original values: - - name: ERROR - - normalized value: - name: UNRECOGNIZED + - name: DELETED + operational_value: DELETED + - aggregated values: priority: 30 original values: - - normalized value: - name: SUBOPTIMAL + - name: ERROR + operational_value: ERROR + - aggregated values: priority: 20 original values: - name: SUBOPTIMAL - - normalized value: - name: RUNNING + operational_value: SUBOPTIMAL + - aggregated values: priority: 10 original values: - - name: available + - name: AVAILABLE + operational_value: OK diff --git a/vitrage/tests/resources/datasources_values/nova.instance.yaml b/vitrage/tests/resources/datasources_values/nova.instance.yaml index ef0f19f12..bccb3a84e 100644 --- a/vitrage/tests/resources/datasources_values/nova.instance.yaml +++ b/vitrage/tests/resources/datasources_values/nova.instance.yaml @@ -1,55 +1,56 @@ category: RESOURCE values: - - normalized value: - name: TERMINATED - priority: 90 - original values: - - name: DELETED - - name: HARD_DELETED - - name: SHELVED_OFFLOADED - - name: SOFT_DELETED - - normalized value: - name: ERROR + - aggregated values: priority: 80 original values: - - name: ERROR - - normalized value: - name: UNRECOGNIZED + - name: DELETED + operational_value: DELETED + - name: HARD_DELETED + operational_value: DELETED + - name: SHELVED_OFFLOADED + operational_value: DELETED + - name: SOFT_DELETED + operational_value: DELETED + - aggregated values: priority: 70 original values: - - name: UNRECOGNIZED - - normalized value: - name: SUSPENDED + - name: ERROR + operational_value: ERROR + - aggregated values: priority: 60 original values: - name: SUSPENDED + operational_value: SUBOPTIMAL - name: PAUSED + operational_value: SUBOPTIMAL - name: STOPPED + operational_value: SUBOPTIMAL - name: SHELVED - - normalized value: - name: RESCUED + operational_value: SUBOPTIMAL + - aggregated values: priority: 50 original values: - - name: RESCUED - - normalized value: - name: RESIZED + - name: RESIZED + operational_value: SUBOPTIMAL + - aggregated values: priority: 40 original values: - - name: RESIZED - - normalized value: - name: TRANSIENT + - name: BUILDING + operational_value: TRANSIENT + - name: INITIALIZED + operational_value: TRANSIENT + - aggregated values: priority: 30 original values: - - name: BUILDING - - name: INITIALIZED - - normalized value: - name: SUBOPTIMAL + - name: SUBOPTIMAL + operational_value: SUBOPTIMAL + - aggregated values: priority: 20 original values: - - name: SUBOPTIMAL - - normalized value: - name: RUNNING + - name: RESCUED + operational_value: OK + - aggregated values: priority: 10 original values: - name: ACTIVE - - name: RESIZED + operational_value: OK diff --git a/vitrage/tests/resources/datasources_values/nova.zone.yaml b/vitrage/tests/resources/datasources_values/nova.zone.yaml index e3b24252a..129ba9800 100644 --- a/vitrage/tests/resources/datasources_values/nova.zone.yaml +++ b/vitrage/tests/resources/datasources_values/nova.zone.yaml @@ -1,26 +1,22 @@ category: RESOURCE values: - - normalized value: - name: TERMINATED - priority: 50 - original values: - - name: DELETED - - normalized value: - name: ERROR + - aggregated values: priority: 40 original values: - - name: ERROR - - normalized value: - name: UNRECOGNIZED + - name: DELETED + operational_value: DELETED + - aggregated values: priority: 30 original values: - - normalized value: - name: SUBOPTIMAL + - name: ERROR + operational_value: ERROR + - aggregated values: priority: 20 original values: - name: SUBOPTIMAL - - normalized value: - name: RUNNING + operational_value: SUBOPTIMAL + - aggregated values: priority: 10 original values: - - name: available + - name: AVAILABLE + operational_value: OK diff --git a/vitrage/tests/resources/datasources_values/vitrage.yaml b/vitrage/tests/resources/datasources_values/vitrage.yaml index f0373ea5f..35ba0e209 100644 --- a/vitrage/tests/resources/datasources_values/vitrage.yaml +++ b/vitrage/tests/resources/datasources_values/vitrage.yaml @@ -1,29 +1,31 @@ category: ALARM values: - - normalized value: - name: CRITICAL + - aggregated values: priority: 50 original values: - name: CRITICAL - - normalized value: - name: SEVERE + operational_value: CRITICAL + - aggregated values: priority: 40 original values: - name: SEVERE + operational_value: SEVERE - name: MAJOR - - normalized value: - name: WARNING + operational_value: SEVERE + - aggregated values: priority: 30 original values: - name: WARNING + operational_value: WARNING - name: MINOR - - normalized value: - name: UNKNOWN + operational_value: WARNING + - aggregated values: priority: 20 original values: - name: UNKNOWN - - normalized value: - name: DISABLED + operational_value: N/A + - aggregated values: priority: 10 original values: - name: OK + operational_value: OK diff --git a/vitrage/tests/unit/entity_graph/processor/test_processor.py b/vitrage/tests/unit/entity_graph/processor/test_processor.py index ff873c080..cbf834e64 100644 --- a/vitrage/tests/unit/entity_graph/processor/test_processor.py +++ b/vitrage/tests/unit/entity_graph/processor/test_processor.py @@ -21,9 +21,9 @@ from vitrage.common.constants import VertexProperties as VProps from vitrage.common.datetime_utils import utcnow from vitrage.datasources.transformer_base import Neighbor from vitrage.entity_graph.initialization_status import InitializationStatus +from vitrage.entity_graph.mappings.operational_resource_state import \ + OperationalResourceState from vitrage.entity_graph.processor import processor as proc -from vitrage.entity_graph.states.normalized_resource_state import \ - NormalizedResourceState import vitrage.graph.utils as graph_utils from vitrage.tests.unit.entity_graph.base import TestEntityGraphUnitBase @@ -273,18 +273,30 @@ class TestProcessor(TestEntityGraphUnitBase): EventAction.UPDATE_ENTITY) # test assertions - self.assertEqual(NormalizedResourceState.SUSPENDED, + self.assertEqual('SUSPENDED', instances[0][0][VProps.AGGREGATED_STATE]) - self.assertEqual(NormalizedResourceState.SUBOPTIMAL, + self.assertEqual(OperationalResourceState.SUBOPTIMAL, + instances[0][0][VProps.OPERATIONAL_STATE]) + self.assertEqual('SUBOPTIMAL', instances[1][0][VProps.AGGREGATED_STATE]) - self.assertEqual(NormalizedResourceState.SUBOPTIMAL, + self.assertEqual(OperationalResourceState.SUBOPTIMAL, + instances[1][0][VProps.OPERATIONAL_STATE]) + self.assertEqual('SUBOPTIMAL', instances[2][0][VProps.AGGREGATED_STATE]) - self.assertEqual(NormalizedResourceState.SUSPENDED, + self.assertEqual(OperationalResourceState.SUBOPTIMAL, + instances[2][0][VProps.OPERATIONAL_STATE]) + self.assertEqual('SUSPENDED', instances[3][0][VProps.AGGREGATED_STATE]) - self.assertEqual(NormalizedResourceState.SUSPENDED, + self.assertEqual(OperationalResourceState.SUBOPTIMAL, + instances[3][0][VProps.OPERATIONAL_STATE]) + self.assertEqual('SUSPENDED', instances[4][0][VProps.AGGREGATED_STATE]) - self.assertEqual(NormalizedResourceState.SUBOPTIMAL, + self.assertEqual(OperationalResourceState.SUBOPTIMAL, + instances[4][0][VProps.OPERATIONAL_STATE]) + self.assertEqual('SUBOPTIMAL', instances[5][0][VProps.AGGREGATED_STATE]) + self.assertEqual(OperationalResourceState.SUBOPTIMAL, + instances[5][0][VProps.OPERATIONAL_STATE]) def _create_and_check_entity(self, processor=None, **kwargs): # create instance event with host neighbor diff --git a/vitrage/tests/unit/entity_graph/states/test_state_manager.py b/vitrage/tests/unit/entity_graph/states/test_datasource_info_mapper.py similarity index 54% rename from vitrage/tests/unit/entity_graph/states/test_state_manager.py rename to vitrage/tests/unit/entity_graph/states/test_datasource_info_mapper.py index 925410821..f3d9f6276 100644 --- a/vitrage/tests/unit/entity_graph/states/test_state_manager.py +++ b/vitrage/tests/unit/entity_graph/states/test_datasource_info_mapper.py @@ -20,16 +20,17 @@ from vitrage.datasources.nagios import NAGIOS_DATASOURCE from vitrage.datasources.nova.host import NOVA_HOST_DATASOURCE from vitrage.datasources.nova.instance import NOVA_INSTANCE_DATASOURCE from vitrage.datasources.nova.zone import NOVA_ZONE_DATASOURCE -from vitrage.entity_graph.states.normalized_resource_state import \ - NormalizedResourceState -from vitrage.entity_graph.states.state_manager import StateManager +from vitrage.entity_graph.mappings.datasource_info_mapper import \ + DatasourceInfoMapper +from vitrage.entity_graph.mappings.operational_resource_state import \ + OperationalResourceState from vitrage.graph.utils import create_vertex from vitrage.service import load_datasource from vitrage.tests import base from vitrage.tests.mocks import utils -class TestStateManager(base.BaseTest): +class TestDatasourceInfoMapper(base.BaseTest): ENTITY_GRAPH_OPTS = [ cfg.StrOpt('datasources_values_dir', @@ -57,7 +58,7 @@ class TestStateManager(base.BaseTest): # noinspection PyAttributeOutsideInit,PyPep8Naming @classmethod def setUpClass(cls): - super(TestStateManager, cls).setUpClass() + super(TestDatasourceInfoMapper, cls).setUpClass() cls.conf = cfg.ConfigOpts() cls.conf.register_opts(cls.ENTITY_GRAPH_OPTS, group='entity_graph') cls.conf.register_opts(cls.DATASOURCES_OPTS, group='datasources') @@ -65,7 +66,7 @@ class TestStateManager(base.BaseTest): def test_load_datasource_state_without_errors(self): # action - state_manager = StateManager(self.conf) + state_manager = DatasourceInfoMapper(self.conf) # test assertions @@ -87,44 +88,92 @@ class TestStateManager(base.BaseTest): self._load_datasources(conf) # action - state_manager = StateManager(conf) + state_manager = DatasourceInfoMapper(conf) # test assertions missing_states = 1 - erroneous_values = 2 + erroneous_values = 1 num_valid_datasources = len(state_manager.datasources_state_confs) + \ missing_states + erroneous_values - self.assertEqual(len(conf.datasources.types), - num_valid_datasources) + self.assertEqual(num_valid_datasources, len(conf.datasources.types)) - def test_normalize_state(self): + def test_operational_state_exists(self): # setup - state_manager = StateManager(self.conf) + state_manager = DatasourceInfoMapper(self.conf) # action - normalized_state = \ - state_manager.normalize_state(EntityCategory.RESOURCE, - NOVA_INSTANCE_DATASOURCE, - 'BUILDING') + operational_state = \ + state_manager.operational_state(NOVA_INSTANCE_DATASOURCE, + 'BUILDING') # test assertions - self.assertEqual(NormalizedResourceState.TRANSIENT, normalized_state) + self.assertEqual(OperationalResourceState.TRANSIENT, operational_state) + + def test_operational_state_not_exists(self): + # setup + state_manager = DatasourceInfoMapper(self.conf) + + # action + operational_state = \ + state_manager.operational_state(NOVA_INSTANCE_DATASOURCE, + 'NON EXISTING STATE') + + # test assertions + self.assertEqual(OperationalResourceState.NA, operational_state) + + def test_operational_state_datasource_not_exists(self): + # setup + state_manager = DatasourceInfoMapper(self.conf) + + # action + operational_state = \ + state_manager.operational_state('NON EXISTING DATASOURCE', + 'BUILDING') + + # test assertions + self.assertEqual(DatasourceInfoMapper.UNDEFINED_DATASOURCE, + operational_state) def test_state_priority(self): # setup - state_manager = StateManager(self.conf) + state_manager = DatasourceInfoMapper(self.conf) # action state_priority = \ state_manager.state_priority(NOVA_INSTANCE_DATASOURCE, - NormalizedResourceState.RUNNING) + 'ACTIVE') # test assertions self.assertEqual(10, state_priority) - def test_aggregated_state_not_normalized(self): + def test_state_priority_not_exists(self): # setup - state_manager = StateManager(self.conf) + state_manager = DatasourceInfoMapper(self.conf) + + # action + state_priority = \ + state_manager.state_priority(NOVA_INSTANCE_DATASOURCE, + 'NON EXISTING STATE') + + # test assertions + self.assertEqual(0, state_priority) + + def test_state_priority_datasource_not_exists(self): + # setup + state_manager = DatasourceInfoMapper(self.conf) + + # action + state_priority = \ + state_manager.state_priority('NON EXISTING DATASOURCE', + 'ACTIVE') + + # test assertions + self.assertEqual(DatasourceInfoMapper.UNDEFINED_DATASOURCE, + state_priority) + + def test_aggregated_state(self): + # setup + state_manager = DatasourceInfoMapper(self.conf) metadata1 = {VProps.VITRAGE_STATE: 'SUSPENDED'} new_vertex1 = create_vertex('12345', entity_state='ACTIVE', @@ -143,14 +192,16 @@ class TestStateManager(base.BaseTest): state_manager.aggregated_state(new_vertex2, None) # test assertions - self.assertEqual(NormalizedResourceState.SUSPENDED, - new_vertex1[VProps.AGGREGATED_STATE]) - self.assertEqual(NormalizedResourceState.SUSPENDED, - new_vertex2[VProps.AGGREGATED_STATE]) + self.assertEqual('SUSPENDED', new_vertex1[VProps.AGGREGATED_STATE]) + self.assertEqual(OperationalResourceState.SUBOPTIMAL, + new_vertex1[VProps.OPERATIONAL_STATE]) + self.assertEqual('SUSPENDED', new_vertex2[VProps.AGGREGATED_STATE]) + self.assertEqual(OperationalResourceState.SUBOPTIMAL, + new_vertex2[VProps.OPERATIONAL_STATE]) def test_aggregated_state_functionalities(self): # setup - state_manager = StateManager(self.conf) + state_manager = DatasourceInfoMapper(self.conf) new_vertex1 = create_vertex('12345', entity_state='ACTIVE', entity_category=EntityCategory.RESOURCE, @@ -160,12 +211,16 @@ class TestStateManager(base.BaseTest): entity_category=EntityCategory.RESOURCE, entity_type=NOVA_INSTANCE_DATASOURCE, metadata=metadata2) + metadata3 = {VProps.VITRAGE_STATE: 'SUBOPTIMAL'} new_vertex3 = create_vertex('34567', + entity_state='ACTIVE', entity_category=EntityCategory.RESOURCE, entity_type=NOVA_INSTANCE_DATASOURCE) - graph_vertex3 = create_vertex('45678', + graph_vertex3 = create_vertex('34567', + entity_state='SUSPENDED', entity_category=EntityCategory.RESOURCE, - entity_type=NOVA_INSTANCE_DATASOURCE) + entity_type=NOVA_INSTANCE_DATASOURCE, + metadata=metadata3) # action state_manager.aggregated_state(new_vertex1, @@ -176,9 +231,31 @@ class TestStateManager(base.BaseTest): graph_vertex3) # test assertions - self.assertEqual(NormalizedResourceState.RUNNING, - new_vertex1[VProps.AGGREGATED_STATE]) - self.assertEqual(NormalizedResourceState.SUBOPTIMAL, - new_vertex2[VProps.AGGREGATED_STATE]) - self.assertEqual(NormalizedResourceState.UNDEFINED, - new_vertex3[VProps.AGGREGATED_STATE]) + self.assertEqual('ACTIVE', new_vertex1[VProps.AGGREGATED_STATE]) + self.assertEqual(OperationalResourceState.OK, + new_vertex1[VProps.OPERATIONAL_STATE]) + self.assertEqual('SUBOPTIMAL', new_vertex2[VProps.AGGREGATED_STATE]) + self.assertEqual(OperationalResourceState.SUBOPTIMAL, + new_vertex2[VProps.OPERATIONAL_STATE]) + self.assertEqual('SUBOPTIMAL', new_vertex3[VProps.AGGREGATED_STATE]) + self.assertEqual(OperationalResourceState.SUBOPTIMAL, + new_vertex3[VProps.OPERATIONAL_STATE]) + + def test_aggregated_state_datasource_not_exists(self): + # setup + state_manager = DatasourceInfoMapper(self.conf) + metadata = {VProps.VITRAGE_STATE: 'SUSPENDED'} + new_vertex = create_vertex('12345', + entity_state='ACTIVE', + entity_category=EntityCategory.RESOURCE, + entity_type='NON EXISTING DATASOURCE', + metadata=metadata) + + # action + state_manager.aggregated_state(new_vertex, None) + + # test assertions + self.assertEqual(DatasourceInfoMapper.UNDEFINED_DATASOURCE, + new_vertex[VProps.AGGREGATED_STATE]) + self.assertEqual(DatasourceInfoMapper.UNDEFINED_DATASOURCE, + new_vertex[VProps.OPERATIONAL_STATE]) diff --git a/vitrage_tempest_tests/tests/utils.py b/vitrage_tempest_tests/tests/utils.py index 4e97a1d53..091699e87 100644 --- a/vitrage_tempest_tests/tests/utils.py +++ b/vitrage_tempest_tests/tests/utils.py @@ -67,18 +67,14 @@ def run_vitrage_command(command, conf): project_name_param, auth_url_param) LOG.info('Full command: %s', full_command) + p = subprocess.Popen(full_command, shell=True, executable="/bin/bash", stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() - if stderr != '': - LOG.error("The command output error is : " + stderr) - if stdout != '': - LOG.debug("The command output is : \n" + stdout) - return stdout - return None + return stdout def get_property_value(environment_name, conf_name, default_value, conf):