add templates with illegal yaml to template list

till now, if a template had illegal yaml format, it wouldnt appear
in template list, also it should be there with status failed

Change-Id: Ib5a40aacb6028d7a68e327bc0f7a0225171e783a
This commit is contained in:
Anna 2017-10-09 11:07:23 +00:00
parent 29fd68a0b5
commit b5f3a6b2dd
6 changed files with 81 additions and 16 deletions

View File

@ -21,12 +21,15 @@ from oslo_utils import uuidutils
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.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 \
EXCEPTION
from vitrage.evaluator.template_validation.template_syntax_validator import \
syntax_validation
from vitrage.utils import datetime as datetime_utils
@ -98,6 +101,7 @@ class ScenarioRepository(object):
def add_template(self, template_def):
result = syntax_validation(template_def)
if not result.is_valid_config:
LOG.info('Unable to load template, syntax err: %s'
% result.comment)
@ -181,11 +185,28 @@ class ScenarioRepository(object):
def _load_templates_files(self, conf):
templates_dir = conf.evaluator.templates_dir
template_defs = file_utils.load_yaml_files(templates_dir)
files = \
file_utils.list_files(templates_dir, '.yaml', with_pathname=True)
template_defs = []
for f in files:
template_defs.append(self._load_template_file(f))
for template_def in template_defs:
self.add_template(template_def)
@staticmethod
def _load_template_file(file_name):
try:
config = file_utils.load_yaml_file(file_name,
with_exception=True)
if config:
return config
except Exception as e:
return {TemplateFields.METADATA: {TemplateFields.NAME: file_name},
EXCEPTION: str(e)}
@staticmethod
def _create_scenario_key(properties):
return frozenset(properties)

View File

@ -23,6 +23,7 @@ status_msgs = {
2: 'Duplicate template_id definition.',
3: 'template_id does not appear in the definition block.',
4: 'Syntax error: ',
5: 'Invalid yaml format: ',
# definitions section 20-39
20: 'definitions section must contain entities field.',

View File

@ -33,27 +33,35 @@ from vitrage.evaluator.template_validation.status_messages import status_msgs
LOG = log.getLogger(__name__)
RESULT_DESCRIPTION = 'Template syntax validation'
EXCEPTION = 'exception'
def syntax_validation(template_conf):
result = _validate_template_sections(template_conf)
if template_conf.get(EXCEPTION):
result = get_fault_result(RESULT_DESCRIPTION,
5,
msg=status_msgs[5] +
template_conf.get(EXCEPTION))
else:
result = _validate_template_sections(template_conf)
if result.is_valid_config:
metadata = template_conf[TemplateFields.METADATA]
result = _validate_metadata_section(metadata)
if result.is_valid_config:
metadata = template_conf[TemplateFields.METADATA]
result = _validate_metadata_section(metadata)
if result.is_valid_config and TemplateFields.INCLUDES in template_conf:
includes = template_conf[TemplateFields.INCLUDES]
result = _validate_includes_section(includes)
if result.is_valid_config and TemplateFields.INCLUDES in template_conf:
includes = template_conf[TemplateFields.INCLUDES]
result = _validate_includes_section(includes)
if result.is_valid_config and TemplateFields.DEFINITIONS in template_conf:
definitions = template_conf[TemplateFields.DEFINITIONS]
has_includes = TemplateFields.INCLUDES in template_conf
result = _validate_definitions_section(definitions, has_includes)
if result.is_valid_config and \
TemplateFields.DEFINITIONS in template_conf:
definitions = template_conf[TemplateFields.DEFINITIONS]
has_includes = TemplateFields.INCLUDES in template_conf
result = _validate_definitions_section(definitions, has_includes)
if result.is_valid_config:
scenarios = template_conf[TemplateFields.SCENARIOS]
result = _validate_scenarios_section(scenarios)
if result.is_valid_config:
scenarios = template_conf[TemplateFields.SCENARIOS]
result = _validate_scenarios_section(scenarios)
return result

View File

@ -0,0 +1,24 @@
metadata:
name: bad_template
description: template with illegal format
definitions:
entities:
- entity:
category: ALARM
# error in yaml format
- template_id: zabbix_alarm
- entity:
category: RESOURCE
type: nova.host
template_id: host
relationships:
scenarios:
- scenario:
condition: host
actions:
- action:
action_type: set_state
action_target:
target: host
properties:
state: uuuu

View File

@ -14,6 +14,7 @@
import copy
import logging
from vitrage.evaluator.scenario_repository import ScenarioRepository
from vitrage.evaluator.template_fields import TemplateFields
from vitrage.evaluator.template_validation.status_messages import status_msgs
from vitrage.evaluator.template_validation import template_syntax_validator
@ -22,6 +23,9 @@ from vitrage.tests.mocks import utils
from vitrage.utils import file as file_utils
BAD_YAML_PATH = 'bad_yaml.yaml'
# noinspection PyAttributeOutsideInit
class TemplateSyntaxValidatorTest(base.BaseTest):
@ -33,6 +37,9 @@ class TemplateSyntaxValidatorTest(base.BaseTest):
'/templates/def_template_tests'
template_dir_path = '%s/templates/general' % utils.get_resources_dir()
cls.template_yamls = file_utils.load_yaml_files(template_dir_path)
cls.bad_template = \
ScenarioRepository._load_template_file(template_dir_path
+ '/' + BAD_YAML_PATH)
cls.first_template = cls.template_yamls[0]
cls._hide_useless_logging_messages()
@ -45,6 +52,9 @@ class TemplateSyntaxValidatorTest(base.BaseTest):
for template in self.template_yamls:
self._test_execution_with_correct_result(template)
def test_bad_yaml_validation(self):
self._test_execution_with_fault_result(self.bad_template, 5)
def test_validate_template_without_metadata_section(self):
template = self.clone_template

View File

@ -72,7 +72,8 @@ class ScenarioRepositoryTest(base.BaseTest):
self.assertIsNotNone(self.scenario_repository)
scenario_templates = self.scenario_repository.templates
self.assertEqual(valid_template_counter, len(scenario_templates))
# there is one bad template
self.assertEqual(valid_template_counter, len(scenario_templates) - 1)
entity_equivalences = self.scenario_repository.entity_equivalences
for entity_props, equivalence in entity_equivalences.items():