
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
192 lines
7.3 KiB
Python
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
|