Ifat Afek 3f7b5a70e1 Add type property to the template metadata
In order to better support validation and loading of different template
types, a mandatory 'type' property was added to the metadata section
(in version 2)

Change-Id: Iebd3eae2db14266a1cfc9cdd11ad9ee24ab9ff4c
2018-01-23 09:26:43 +00:00

192 lines
7.3 KiB
Python

# 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_log import log
from vitrage.common.constants import VertexProperties as VProps
from vitrage.evaluator.template_data import EdgeDescription
from vitrage.evaluator.template_data import TemplateData
from vitrage.evaluator.template_fields import TemplateFields as TFields
from vitrage.evaluator.template_loading.props_converter import PropsConverter
from vitrage.evaluator.template_loading.scenario_loader import ScenarioLoader
from vitrage.evaluator.template_schema_factory import TemplateSchemaFactory
from vitrage.graph import Edge
from vitrage.graph import Vertex
from vitrage.utils import evaluator as evaluator_utils
LOG = log.getLogger(__name__)
class TemplateLoader(object):
PROPS_CONVERSION = {
'category': VProps.VITRAGE_CATEGORY,
'type': VProps.VITRAGE_TYPE,
'resource_id': VProps.VITRAGE_RESOURCE_ID,
'sample_timestamp': VProps.VITRAGE_SAMPLE_TIMESTAMP,
'is_deleted': VProps.VITRAGE_IS_DELETED,
'is_placeholder': VProps.VITRAGE_IS_PLACEHOLDER,
'aggregated_state': VProps.VITRAGE_AGGREGATED_STATE,
'operational_state': VProps.VITRAGE_OPERATIONAL_STATE,
'aggregated_severity': VProps.VITRAGE_AGGREGATED_SEVERITY,
'operational_severity': VProps.VITRAGE_OPERATIONAL_SEVERITY
}
def __init__(self):
self.entities = {}
self.relationships = {}
def load(self, template_def, def_templates=None):
template_schema = self._get_template_schema(template_def)
if not template_schema:
LOG.error('Failed to load template - unsupported version')
return
name = template_def[TFields.METADATA][TFields.NAME]
# type might be None, it is defined only in version 2
type = template_def[TFields.METADATA].get(TFields.TYPE)
if def_templates is None:
def_templates = {}
defs = {}
if TFields.DEFINITIONS in template_def:
defs = template_def[TFields.DEFINITIONS]
if TFields.ENTITIES in defs:
self.entities = self._build_entities(defs[TFields.ENTITIES])
# Add definitions from template then from definition templates.
if TFields.INCLUDES in template_def:
includes = template_def[TFields.INCLUDES]
self._build_entities_from_def_templates(
includes, def_templates, self.entities)
if TFields.RELATIONSHIPS in defs:
self.relationships = self._build_relationships(
defs[TFields.RELATIONSHIPS])
if TFields.INCLUDES in template_def:
includes = template_def[TFields.INCLUDES]
self._build_relationships_with_def_templates(includes,
def_templates,
self.relationships)
scenarios = ScenarioLoader(template_schema, name, self.entities,
self.relationships).\
build_scenarios(template_def[TFields.SCENARIOS])
return TemplateData(name, type, template_schema.version(),
self.entities, self.relationships, scenarios)
def _build_entities(self, entities_defs):
entities = {}
for entity_def in entities_defs:
entity_dict = entity_def[TFields.ENTITY]
template_id = entity_dict[TFields.TEMPLATE_ID]
properties = PropsConverter.convert_props_with_dictionary(
self._extract_properties(entity_dict))
entities[template_id] = Vertex(template_id, properties)
return entities
def _build_entities_from_def_templates(
self, includes, def_templates, entities):
for def_template_dict in includes:
name = def_template_dict[TFields.NAME]
def_template = evaluator_utils.find_def_template(
name, def_templates)
defs = def_template[TFields.DEFINITIONS]
entities_defs = defs[TFields.ENTITIES]
for entity_def in entities_defs:
entity_dict = entity_def[TFields.ENTITY]
template_id = entity_dict[TFields.TEMPLATE_ID]
if template_id not in entities:
properties = \
PropsConverter.convert_props_with_dictionary(
self._extract_properties(entity_dict))
entities[template_id] = Vertex(template_id, properties)
def _build_relationships(self, relationships_defs):
relationships = {}
for relationship_def in relationships_defs:
relationship_dict = relationship_def[TFields.RELATIONSHIP]
relationship = self._extract_relationship_info(relationship_dict)
template_id = relationship_dict[TFields.TEMPLATE_ID]
relationships[template_id] = relationship
return relationships
def _build_relationships_with_def_templates(
self, includes, def_templates, relationships):
for def_template_dict in includes:
name = def_template_dict[TFields.NAME]
def_template = evaluator_utils.find_def_template(
name, def_templates)
if TFields.RELATIONSHIPS in def_template[TFields.DEFINITIONS]:
defs = def_template[TFields.DEFINITIONS]
relationship_defs = defs[TFields.RELATIONSHIPS]
for relationship_def in relationship_defs:
relationship_dict = relationship_def[TFields.RELATIONSHIP]
template_id = relationship_dict[TFields.TEMPLATE_ID]
if template_id not in relationships:
relationship = self._extract_relationship_info(
relationship_dict)
relationships[template_id] = relationship
def _extract_relationship_info(self, relationship_dict):
source_id = relationship_dict[TFields.SOURCE]
target_id = relationship_dict[TFields.TARGET]
edge = Edge(source_id,
target_id,
relationship_dict[TFields.RELATIONSHIP_TYPE],
self._extract_properties(relationship_dict))
source = self.entities[source_id]
target = self.entities[target_id]
return EdgeDescription(edge, source, target)
@staticmethod
def _extract_properties(var_dict):
ignore_ids = [TFields.TEMPLATE_ID, TFields.SOURCE, TFields.TARGET]
return \
{key: var_dict[key] for key in var_dict if key not in ignore_ids}
@staticmethod
def _get_template_schema(template):
metadata = template.get(TFields.METADATA)
if metadata:
version = metadata.get(TFields.VERSION)
return TemplateSchemaFactory().template_schema(version)
else:
return None