From 7c5edad86d3236c6494c1a62ea5d0e97d585122a Mon Sep 17 00:00:00 2001 From: Ifat Afek Date: Thu, 30 Nov 2017 16:30:20 +0000 Subject: [PATCH] Refactor template_content_validator Split the code in template_content_validator to two files: - definitions_validator - scenario_validator The purpose is to make it easier to support per-version validation later on Change-Id: Ib7716bbc592f22ab8d0b892736cae0c78affabe9 --- vitrage/evaluator/scenario_repository.py | 6 +- .../content/definitions_validator.py | 214 ++++++++++ .../content/scenario_validator.py | 203 +++++++++ .../content/template_content_validator.py | 394 +----------------- .../tests/unit/evaluator/test_condition.py | 2 +- 5 files changed, 441 insertions(+), 378 deletions(-) create mode 100644 vitrage/evaluator/template_validation/content/definitions_validator.py create mode 100644 vitrage/evaluator/template_validation/content/scenario_validator.py diff --git a/vitrage/evaluator/scenario_repository.py b/vitrage/evaluator/scenario_repository.py index 943a6699f..c5b76a47a 100644 --- a/vitrage/evaluator/scenario_repository.py +++ b/vitrage/evaluator/scenario_repository.py @@ -24,10 +24,10 @@ from vitrage.evaluator.base import Template from vitrage.evaluator.equivalence_repository import EquivalenceRepository from vitrage.evaluator.template_data import TemplateData from vitrage.evaluator.template_fields import TemplateFields +from vitrage.evaluator.template_validation.content.definitions_validator \ + import DefinitionsValidator as DefValidator from vitrage.evaluator.template_validation.content.template_content_validator \ import content_validation -from vitrage.evaluator.template_validation.content.template_content_validator \ - import def_template_content_validation from vitrage.evaluator.template_validation.template_syntax_validator import \ def_template_syntax_validation from vitrage.evaluator.template_validation.template_syntax_validator import \ @@ -139,7 +139,7 @@ class ScenarioRepository(object): LOG.info('Unable to load definition template, syntax err: %s' % result.comment) else: - result = def_template_content_validation(def_template) + result = DefValidator.def_template_content_validation(def_template) if not result.is_valid_config: LOG.info('Unable to load definition template, content err: %s' % result.comment) diff --git a/vitrage/evaluator/template_validation/content/definitions_validator.py b/vitrage/evaluator/template_validation/content/definitions_validator.py new file mode 100644 index 000000000..663d35f89 --- /dev/null +++ b/vitrage/evaluator/template_validation/content/definitions_validator.py @@ -0,0 +1,214 @@ +# 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 +import re + +from vitrage.evaluator.template_fields import TemplateFields +from vitrage.evaluator.template_validation.content.base import \ + get_content_correct_result +from vitrage.evaluator.template_validation.content.base import \ + get_content_fault_result +from vitrage.evaluator.template_validation.content.base import \ + validate_template_id +from vitrage.evaluator.template_validation.status_messages import status_msgs +from vitrage.utils import evaluator as evaluator_utils + +LOG = log.getLogger(__name__) + + +class DefinitionsValidator(object): + + @classmethod + def def_template_content_validation(cls, def_template): + def_template_definitions = def_template[TemplateFields.DEFINITIONS] + + entities_index = {} + entities = def_template_definitions[TemplateFields.ENTITIES] + result = cls.validate_entities_definition(entities, entities_index) + + relationships_index = {} + + if result.is_valid_config \ + and TemplateFields.RELATIONSHIPS in def_template_definitions: + relationships = \ + def_template_definitions[TemplateFields.RELATIONSHIPS] + result = \ + cls.validate_relationships_definitions(relationships, + relationships_index, + entities_index) + + return result + + @classmethod + def validate_entities_definition(cls, entities, entities_index): + for entity in entities: + entity_dict = entity[TemplateFields.ENTITY] + result = \ + cls._validate_entity_definition(entity_dict, entities_index) + + if not result.is_valid_config: + return result + + entities_index[entity_dict[TemplateFields.TEMPLATE_ID]] = \ + entity_dict + + return get_content_correct_result() + + @classmethod + def validate_definitions_with_includes( + cls, template_includes, def_templates, entities_index): + + for include in template_includes: + + name = include[TemplateFields.NAME] + def_template = \ + evaluator_utils.find_def_template(name, def_templates) + + if not def_template: + + LOG.error('%s status code: %s' % (status_msgs[142], 142)) + return get_content_fault_result(142) + + def_template_definitions = def_template[TemplateFields.DEFINITIONS] + def_template_entities = \ + def_template_definitions[TemplateFields.ENTITIES] + result = cls._validate_include_entities_definition( + def_template_entities, entities_index) + + if not result.is_valid_config: + return result + + return get_content_correct_result() + + @classmethod + def validate_relationships_definitions(cls, + relationships, + relationships_index, + entities_index): + for relationship in relationships: + + relationship_dict = relationship[TemplateFields.RELATIONSHIP] + result = cls._validate_relationship(relationship_dict, + relationships_index, + entities_index) + if not result.is_valid_config: + return result + + template_id = relationship_dict[TemplateFields.TEMPLATE_ID] + relationships_index[template_id] = relationship_dict + return get_content_correct_result() + + @classmethod + def validate_relationships_definitions_with_includes(cls, + template_includes, + def_templates, + entities_index, + relationships_index): + + for include in template_includes: + + name = include[TemplateFields.NAME] + def_template = \ + evaluator_utils.find_def_template(name, def_templates) + + if def_template: + defs = def_template[TemplateFields.DEFINITIONS] + relationships = defs[TemplateFields.RELATIONSHIPS] + + for relationship in relationships: + relationship_dict = \ + relationship[TemplateFields.RELATIONSHIP] + template_id = relationship_dict[TemplateFields.TEMPLATE_ID] + if template_id not in relationships_index: + result = cls._validate_def_template_relationship( + relationship_dict, + entities_index) + + if not result.is_valid_config: + return result + + relationships_index[template_id] = relationship_dict + + return get_content_correct_result() + + @classmethod + def _validate_entity_definition(cls, entity_dict, entities_index): + template_id = entity_dict[TemplateFields.TEMPLATE_ID] + if template_id in entities_index: + LOG.error('%s status code: %s' % (status_msgs[2], 2)) + return get_content_fault_result(2) + + for key, value in entity_dict.items(): + + if key.lower().endswith(TemplateFields.REGEX): + try: + re.compile(value) + except Exception: + LOG.error('%s %s status code: %s' % (status_msgs[47], + str(key), 47)) + return get_content_fault_result(47) + + return get_content_correct_result() + + @classmethod + def _validate_include_entities_definition( + cls, + def_template_entities, + entities_index): + + for entity in def_template_entities: + entity_dict = entity[TemplateFields.ENTITY] + result = \ + cls._validate_entity_definition(entity_dict, entities_index) + + if not result.is_valid_config: + return result + + if entity_dict[TemplateFields.TEMPLATE_ID] not in entities_index: + template_id = entity_dict[TemplateFields.TEMPLATE_ID] + entities_index[template_id] = entity_dict + + return get_content_correct_result() + + @classmethod + def _validate_def_template_relationship(cls, relationship, entities_index): + target = relationship[TemplateFields.TARGET] + result = validate_template_id(entities_index, target) + + if result.is_valid_config: + source = relationship[TemplateFields.SOURCE] + result = validate_template_id(entities_index, source) + + return result + + @classmethod + def _validate_relationship(cls, + relationship, + relationships_index, + entities_index): + + template_id = relationship[TemplateFields.TEMPLATE_ID] + if template_id in relationships_index or template_id in entities_index: + LOG.error('%s status code: %s' % (status_msgs[2], 2)) + return get_content_fault_result(2) + + target = relationship[TemplateFields.TARGET] + result = validate_template_id(entities_index, target) + + if result.is_valid_config: + source = relationship[TemplateFields.SOURCE] + result = validate_template_id(entities_index, source) + + return result diff --git a/vitrage/evaluator/template_validation/content/scenario_validator.py b/vitrage/evaluator/template_validation/content/scenario_validator.py new file mode 100644 index 000000000..c5ec5bd1f --- /dev/null +++ b/vitrage/evaluator/template_validation/content/scenario_validator.py @@ -0,0 +1,203 @@ +# 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 sympy.logic.boolalg import Not +from sympy import Symbol + +from oslo_log import log +from six.moves import reduce + +from vitrage.common.constants import EdgeProperties as EProps +from vitrage.evaluator.actions.base import ActionType +from vitrage.evaluator.condition import convert_to_dnf_format +from vitrage.evaluator.condition import get_condition_common_targets +from vitrage.evaluator.condition import is_condition_include_positive_clause +from vitrage.evaluator.condition import parse_condition +from vitrage.evaluator.condition import SymbolResolver +from vitrage.evaluator.template_fields import TemplateFields +from vitrage.evaluator.template_validation.content. \ + add_causal_relationship_validator import AddCausalRelationshipValidator +from vitrage.evaluator.template_validation.content.base import \ + get_content_correct_result +from vitrage.evaluator.template_validation.content.base import \ + get_content_fault_result +from vitrage.evaluator.template_validation.content.base import \ + validate_template_id +from vitrage.evaluator.template_validation.content.execute_mistral_validator \ + import ExecuteMistralValidator +from vitrage.evaluator.template_validation.content.mark_down_validator \ + import MarkDownValidator +from vitrage.evaluator.template_validation.content.raise_alarm_validator \ + import RaiseAlarmValidator +from vitrage.evaluator.template_validation.content.set_state_validator \ + import SetStateValidator +from vitrage.evaluator.template_validation.status_messages import status_msgs + +LOG = log.getLogger(__name__) + + +class ScenarioValidator(object): + + class TemplateSymbolResolver(SymbolResolver): + def is_relationship(self, symbol): + return TemplateFields.RELATIONSHIP_TYPE in symbol + + def get_relationship_source_id(self, relationship): + return relationship[TemplateFields.SOURCE] + + def get_relationship_target_id(self, relationship): + return relationship[TemplateFields.TARGET] + + def get_entity_id(self, entity): + return entity[TemplateFields.TEMPLATE_ID] + + def __init__(self, definitions_index): + self.definitions_index = definitions_index + + def validate(self, scenarios): + for scenario in scenarios: + scenario_values = scenario[TemplateFields.SCENARIO] + + condition = scenario_values[TemplateFields.CONDITION] + result = self._validate_scenario_condition(condition) + + if not result.is_valid_config: + return result + + actions = scenario_values[TemplateFields.ACTIONS] + result = self._validate_scenario_actions(actions) + + if not result.is_valid_config: + return result + + return get_content_correct_result() + + def _validate_scenario_condition(self, condition): + try: + dnf_result = convert_to_dnf_format(condition) + except Exception: + LOG.error('%s status code: %s' % (status_msgs[85], 85)) + return get_content_fault_result(85) + + # not condition validation + not_condition_result = self._validate_not_condition(dnf_result) + if not not_condition_result.is_valid_config: + return not_condition_result + + # template id validation + values_to_replace = ' and ', ' or ', ' not ', 'not ', '(', ')' + condition_vars = reduce(lambda cond, v: cond.replace(v, ' '), + values_to_replace, + condition) + + for condition_var in condition_vars.split(' '): + + if len(condition_var.strip()) == 0: + continue + + result = \ + validate_template_id(self.definitions_index, condition_var) + if not result.is_valid_config: + return result + + # condition structure validation + condition_structure_result = \ + self._validate_condition_structure(parse_condition(condition)) + if not condition_structure_result.is_valid_config: + return condition_structure_result + + return get_content_correct_result() + + def _validate_condition_structure(self, condition_dnf): + result = \ + self._validate_condition_includes_positive_clause(condition_dnf) + if not result.is_valid_config: + return result + + common_targets = \ + get_condition_common_targets(condition_dnf, + self.definitions_index, + self.TemplateSymbolResolver()) + + return get_content_correct_result() if common_targets \ + else get_content_fault_result(135) + + @staticmethod + def _validate_condition_includes_positive_clause(condition): + return get_content_correct_result() if \ + is_condition_include_positive_clause(condition) \ + else get_content_fault_result(134) + + def _validate_not_condition(self, dnf_result): + """Not operator validation + + Not operator can appear only on edges. + + :param dnf_result: + :param definitions_index: + :return: + """ + + if isinstance(dnf_result, Not): + for arg in dnf_result.args: + if isinstance(arg, Symbol): + definition = self.definitions_index.get(str(arg), None) + if not (definition and + definition.get(EProps.RELATIONSHIP_TYPE)): + msg = status_msgs[86] + ' template id: %s' % arg + LOG.error('%s status code: %s' % (msg, 86)) + return get_content_fault_result(86, msg) + else: + res = self._validate_not_condition(arg) + if not res.is_valid_config: + return res + return get_content_correct_result() + + for arg in dnf_result.args: + if not isinstance(arg, Symbol): + res = self._validate_not_condition(arg) + if not res.is_valid_config: + return res + + return get_content_correct_result() + + def _validate_scenario_actions(self, actions): + + for action in actions: + result = \ + self._validate_scenario_action(action[TemplateFields.ACTION]) + if not result.is_valid_config: + return result + + return get_content_correct_result() + + def _validate_scenario_action(self, action): + + action_type = action[TemplateFields.ACTION_TYPE] + + action_validators = { + ActionType.RAISE_ALARM: RaiseAlarmValidator(), + ActionType.SET_STATE: SetStateValidator(), + ActionType.ADD_CAUSAL_RELATIONSHIP: + AddCausalRelationshipValidator(), + ActionType.MARK_DOWN: MarkDownValidator(), + ActionType.EXECUTE_MISTRAL: ExecuteMistralValidator(), + } + + if action_type not in action_validators: + LOG.error('%s status code: %s' % (status_msgs[120], 120)) + return get_content_fault_result(120) + + return action_validators[action_type].validate(action, + self.definitions_index) diff --git a/vitrage/evaluator/template_validation/content/template_content_validator.py b/vitrage/evaluator/template_validation/content/template_content_validator.py index 5600e507f..fe8425b71 100644 --- a/vitrage/evaluator/template_validation/content/template_content_validator.py +++ b/vitrage/evaluator/template_validation/content/template_content_validator.py @@ -12,39 +12,15 @@ # License for the specific language governing permissions and limitations # under the License. -from sympy.logic.boolalg import Not -from sympy import Symbol - from oslo_log import log -import re -from six.moves import reduce -from vitrage.common.constants import EdgeProperties as EProps -from vitrage.evaluator.actions.base import ActionType -from vitrage.evaluator.condition import convert_to_dnf_format -from vitrage.evaluator.condition import get_condition_common_targets -from vitrage.evaluator.condition import is_condition_include_positive_clause -from vitrage.evaluator.condition import parse_condition -from vitrage.evaluator.condition import SymbolResolver from vitrage.evaluator.template_fields import TemplateFields -from vitrage.evaluator.template_validation.content. \ - add_causal_relationship_validator import AddCausalRelationshipValidator from vitrage.evaluator.template_validation.content.base import \ get_content_correct_result -from vitrage.evaluator.template_validation.content.base import \ - get_content_fault_result -from vitrage.evaluator.template_validation.content.base import \ - validate_template_id -from vitrage.evaluator.template_validation.content.execute_mistral_validator \ - import ExecuteMistralValidator -from vitrage.evaluator.template_validation.content.mark_down_validator \ - import MarkDownValidator -from vitrage.evaluator.template_validation.content.raise_alarm_validator \ - import RaiseAlarmValidator -from vitrage.evaluator.template_validation.content.set_state_validator \ - import SetStateValidator -from vitrage.evaluator.template_validation.status_messages import status_msgs -from vitrage.utils import evaluator as evaluator_utils +from vitrage.evaluator.template_validation.content.definitions_validator \ + import DefinitionsValidator as DefValidator +from vitrage.evaluator.template_validation.content.scenario_validator import \ + ScenarioValidator LOG = log.getLogger(__name__) @@ -63,370 +39,40 @@ def content_validation(template, def_templates=None): if TemplateFields.ENTITIES in template_definitions: entities = template_definitions[TemplateFields.ENTITIES] - result = _validate_entities_definition(entities, entities_index) + result = DefValidator.validate_entities_definition(entities, + entities_index) # If there are duplicate definitions in several includes under the same # name, will regard the first one if result.is_valid_config and TemplateFields.INCLUDES in template: - template_includes = template[TemplateFields.INCLUDES] - result = _validate_definitions_with_includes(template_includes, - def_templates, - entities_index) + result = \ + DefValidator.validate_definitions_with_includes(template_includes, + def_templates, + entities_index) - relationships_index = {} + relationship_index = {} if result.is_valid_config and \ - TemplateFields.RELATIONSHIPS in template_definitions: - + TemplateFields.RELATIONSHIPS in template_definitions: relationships = template_definitions[TemplateFields.RELATIONSHIPS] - result = _validate_relationships_definitions(relationships, - relationships_index, - entities_index) + result = \ + DefValidator.validate_relationships_definitions(relationships, + relationship_index, + entities_index) if result.is_valid_config and TemplateFields.INCLUDES in template: template_includes = template[TemplateFields.INCLUDES] - result = _validate_relationships_definitions_with_includes( + result = DefValidator.validate_relationships_definitions_with_includes( template_includes, def_templates, entities_index, - relationships_index) + relationship_index) if result.is_valid_config: scenarios = template[TemplateFields.SCENARIOS] definitions_index = entities_index.copy() - definitions_index.update(relationships_index) - result = _validate_scenarios(scenarios, definitions_index) + definitions_index.update(relationship_index) + result = ScenarioValidator(definitions_index).validate(scenarios) return result - - -def def_template_content_validation(def_template): - def_template_definitions = def_template[TemplateFields.DEFINITIONS] - - entities_index = {} - entities = def_template_definitions[TemplateFields.ENTITIES] - result = _validate_entities_definition(entities, entities_index) - - relationships_index = {} - - if result.is_valid_config \ - and TemplateFields.RELATIONSHIPS in def_template_definitions: - relationships = def_template_definitions[TemplateFields.RELATIONSHIPS] - result = _validate_relationships_definitions(relationships, - relationships_index, - entities_index) - - return result - - -def _validate_entities_definition(entities, entities_index): - - for entity in entities: - - entity_dict = entity[TemplateFields.ENTITY] - result = _validate_entity_definition(entity_dict, entities_index) - - if not result.is_valid_config: - return result - - entities_index[entity_dict[TemplateFields.TEMPLATE_ID]] = entity_dict - - return get_content_correct_result() - - -def _validate_entity_definition(entity_dict, entities_index): - - template_id = entity_dict[TemplateFields.TEMPLATE_ID] - if template_id in entities_index: - LOG.error('%s status code: %s' % (status_msgs[2], 2)) - return get_content_fault_result(2) - - for key, value in entity_dict.items(): - - if key.lower().endswith(TemplateFields.REGEX): - try: - re.compile(value) - except Exception: - LOG.error('%s %s status code: %s' % (status_msgs[47], - str(key), 47)) - return get_content_fault_result(47) - - return get_content_correct_result() - - -def _validate_definitions_with_includes( - template_includes, def_templates, entities_index): - - for include in template_includes: - - name = include[TemplateFields.NAME] - def_template = evaluator_utils.find_def_template(name, def_templates) - - if not def_template: - - LOG.error('%s status code: %s' % (status_msgs[142], 142)) - return get_content_fault_result(142) - - def_template_definitions = def_template[TemplateFields.DEFINITIONS] - def_template_entities = \ - def_template_definitions[TemplateFields.ENTITIES] - result = _validate_include_entities_definition( - def_template_entities, entities_index) - - if not result.is_valid_config: - return result - - return get_content_correct_result() - - -def _validate_include_entities_definition( - def_template_entities, - entities_index): - - for entity in def_template_entities: - entity_dict = entity[TemplateFields.ENTITY] - result = _validate_entity_definition(entity_dict, entities_index) - - if not result.is_valid_config: - return result - - if entity_dict[TemplateFields.TEMPLATE_ID] not in entities_index: - id = entity_dict[TemplateFields.TEMPLATE_ID] - entities_index[id] = entity_dict - - return get_content_correct_result() - - -def _validate_relationships_definitions(relationships, - relationships_index, - entities_index): - - for relationship in relationships: - - relationship_dict = relationship[TemplateFields.RELATIONSHIP] - result = _validate_relationship(relationship_dict, - relationships_index, - entities_index) - if not result.is_valid_config: - return result - - template_id = relationship_dict[TemplateFields.TEMPLATE_ID] - relationships_index[template_id] = relationship_dict - return get_content_correct_result() - - -def _validate_relationships_definitions_with_includes(template_includes, - def_templates, - entities_index, - relationships_index): - - for include in template_includes: - - name = include[TemplateFields.NAME] - def_template = evaluator_utils.find_def_template(name, def_templates) - - if def_template: - defs = def_template[TemplateFields.DEFINITIONS] - relationships = defs[TemplateFields.RELATIONSHIPS] - - for relationship in relationships: - relationship_dict = relationship[TemplateFields.RELATIONSHIP] - template_id = relationship_dict[TemplateFields.TEMPLATE_ID] - if template_id not in relationships_index: - result = _validate_def_template_relationship( - relationship_dict, - entities_index) - - if not result.is_valid_config: - return result - - relationships_index[template_id] = relationship_dict - - return get_content_correct_result() - - -def _validate_def_template_relationship(relationship, - entities_index): - - target = relationship[TemplateFields.TARGET] - result = validate_template_id(entities_index, target) - - if result.is_valid_config: - source = relationship[TemplateFields.SOURCE] - result = validate_template_id(entities_index, source) - - return result - - -def _validate_relationship(relationship, relationships_index, entities_index): - - template_id = relationship[TemplateFields.TEMPLATE_ID] - if template_id in relationships_index or template_id in entities_index: - LOG.error('%s status code: %s' % (status_msgs[2], 2)) - return get_content_fault_result(2) - - target = relationship[TemplateFields.TARGET] - result = validate_template_id(entities_index, target) - - if result.is_valid_config: - source = relationship[TemplateFields.SOURCE] - result = validate_template_id(entities_index, source) - - return result - - -def _validate_scenarios(scenarios, definitions_index): - - for scenario in scenarios: - - scenario_values = scenario[TemplateFields.SCENARIO] - - condition = scenario_values[TemplateFields.CONDITION] - result = _validate_scenario_condition(condition, definitions_index) - - if not result.is_valid_config: - return result - - actions = scenario_values[TemplateFields.ACTIONS] - result = _validate_scenario_actions(actions, definitions_index) - - if not result.is_valid_config: - return result - - return get_content_correct_result() - - -def _validate_scenario_condition(condition, definitions_index): - try: - dnf_result = convert_to_dnf_format(condition) - except Exception: - LOG.error('%s status code: %s' % (status_msgs[85], 85)) - return get_content_fault_result(85) - - # not condition validation - not_condition_result = \ - _validate_not_condition(dnf_result, definitions_index) - if not not_condition_result.is_valid_config: - return not_condition_result - - # template id validation - values_to_replace = ' and ', ' or ', ' not ', 'not ', '(', ')' - condition_vars = reduce(lambda cond, v: cond.replace(v, ' '), - values_to_replace, - condition) - - for condition_var in condition_vars.split(' '): - - if len(condition_var.strip()) == 0: - continue - - result = validate_template_id(definitions_index, condition_var) - if not result.is_valid_config: - return result - - # condition structure validation - condition_structure_result = \ - validate_condition_structure(parse_condition(condition), - definitions_index) - if not condition_structure_result.is_valid_config: - return condition_structure_result - - return get_content_correct_result() - - -def validate_condition_structure(condition_dnf, definitions_index): - result = validate_condition_includes_positive_clause(condition_dnf) - if not result.is_valid_config: - return result - - common_targets = get_condition_common_targets(condition_dnf, - definitions_index, - TemplateSymbolResolver()) - - return get_content_correct_result() if common_targets \ - else get_content_fault_result(135) - - -def validate_condition_includes_positive_clause(condition): - return get_content_correct_result() if \ - is_condition_include_positive_clause(condition) \ - else get_content_fault_result(134) - - -class TemplateSymbolResolver(SymbolResolver): - def is_relationship(self, symbol): - return TemplateFields.RELATIONSHIP_TYPE in symbol - - def get_relationship_source_id(self, relationship): - return relationship[TemplateFields.SOURCE] - - def get_relationship_target_id(self, relationship): - return relationship[TemplateFields.TARGET] - - def get_entity_id(self, entity): - return entity[TemplateFields.TEMPLATE_ID] - - -def _validate_not_condition(dnf_result, definitions_index): - """Not operator validation - - Not operator can appear only on edges. - - :param dnf_result: - :param definitions_index: - :return: - """ - - if isinstance(dnf_result, Not): - for arg in dnf_result.args: - if isinstance(arg, Symbol): - definition = definitions_index.get(str(arg), None) - if not (definition and - definition.get(EProps.RELATIONSHIP_TYPE)): - msg = status_msgs[86] + ' template id: %s' % arg - LOG.error('%s status code: %s' % (msg, 86)) - return get_content_fault_result(86, msg) - else: - res = _validate_not_condition(arg, definitions_index) - if not res.is_valid_config: - return res - return get_content_correct_result() - - for arg in dnf_result.args: - if not isinstance(arg, Symbol): - res = _validate_not_condition(arg, definitions_index) - if not res.is_valid_config: - return res - - return get_content_correct_result() - - -def _validate_scenario_actions(actions, definitions_index): - - for action in actions: - result = _validate_scenario_action(action[TemplateFields.ACTION], - definitions_index) - if not result.is_valid_config: - return result - - return get_content_correct_result() - - -def _validate_scenario_action(action, definitions_index): - - action_type = action[TemplateFields.ACTION_TYPE] - - action_validators = { - ActionType.RAISE_ALARM: RaiseAlarmValidator(), - ActionType.SET_STATE: SetStateValidator(), - ActionType.ADD_CAUSAL_RELATIONSHIP: AddCausalRelationshipValidator(), - ActionType.MARK_DOWN: MarkDownValidator(), - ActionType.EXECUTE_MISTRAL: ExecuteMistralValidator(), - } - - if action_type not in action_validators: - LOG.error('%s status code: %s' % (status_msgs[120], 120)) - return get_content_fault_result(120) - - return action_validators[action_type].validate(action, definitions_index) diff --git a/vitrage/tests/unit/evaluator/test_condition.py b/vitrage/tests/unit/evaluator/test_condition.py index 096782c0c..032bac243 100644 --- a/vitrage/tests/unit/evaluator/test_condition.py +++ b/vitrage/tests/unit/evaluator/test_condition.py @@ -15,7 +15,7 @@ from vitrage.evaluator.condition import EdgeDescription from vitrage.evaluator.condition import SymbolResolver from vitrage.evaluator.template_data import TemplateData -from vitrage.evaluator.template_validation.content.template_content_validator \ +from vitrage.evaluator.template_validation.content.scenario_validator \ import get_condition_common_targets from vitrage.tests import base from vitrage.tests.mocks import utils