Merge "Added a version to Vitrage templates"
This commit is contained in:
commit
e8c4066881
@ -17,6 +17,7 @@ The template is written in YAML language, with the following structure:
|
||||
::
|
||||
|
||||
metadata:
|
||||
version: <template version>
|
||||
name: <unique template identifier>
|
||||
description: <what this template does>
|
||||
definitions:
|
||||
@ -38,17 +39,21 @@ The template is written in YAML language, with the following structure:
|
||||
|
||||
The template is divided into four main sections:
|
||||
|
||||
- *metadata:* Contains the template name, and brief description of what the template does (optional)
|
||||
- *metadata:* Contains general information about the template.
|
||||
|
||||
- *version -* the version of the template format. The default is 1.
|
||||
- *name -* the name of the template
|
||||
- *description -* a brief description of what the template does (optional)
|
||||
- *definitions:* This section is **mandatory** unless an include section is specified in the template (see below).
|
||||
This section contains the atomic definitions referenced later on, for entities and relationships.
|
||||
|
||||
- *entities –* describes the resources and alarms which are relevant to the template scenario (conceptually, corresponds to a vertex in the entity graph)
|
||||
- *relationships –* the relationships between the entities (conceptually, corresponds to an edge in the entity graph)
|
||||
- *entities –* describes the resources and alarms which are relevant to the template scenario (conceptually, corresponds to a vertex in the entity graph)
|
||||
- *relationships –* the relationships between the entities (conceptually, corresponds to an edge in the entity graph)
|
||||
- *includes:* This section is optional. If included, it must contain a list of names of definition templates as they appear in the metadata section of said templates.
|
||||
If only definitions from included definition templates are used to create scenarios within the template, then the *definitions* section is **optional**.
|
||||
- *scenarios:* A list of if-then scenarios to consider. Each scenario is comprised of:
|
||||
- *condition –* the condition to be met. This condition will be phrased referencing the entities and relationships previously defined.
|
||||
- *action(s) –* a list of actions to execute when the condition is met.
|
||||
- *condition –* the condition to be met. This condition will be phrased referencing the entities and relationships previously defined.
|
||||
- *action(s) –* a list of actions to execute when the condition is met.
|
||||
|
||||
|
||||
Definition Template Structure
|
||||
|
@ -0,0 +1,5 @@
|
||||
---
|
||||
features:
|
||||
- A ``version`` field was added to the metadata section of Vitrage templates,
|
||||
to allow future changes that are not backward-compatible. The default
|
||||
version is 1.
|
@ -123,6 +123,7 @@ class TemplateTopologyFields(object):
|
||||
METADATA = 'metadata'
|
||||
DESCRIPTION = 'description'
|
||||
NAME = 'name'
|
||||
VERSION = 'version'
|
||||
|
||||
DEFINITIONS = 'definitions'
|
||||
|
||||
|
@ -15,6 +15,10 @@
|
||||
from vitrage.common.constants import TemplateTopologyFields
|
||||
|
||||
|
||||
DEFAULT_VERSION = '1'
|
||||
SUPPORTED_VERSIONS = ['1']
|
||||
|
||||
|
||||
class TemplateFields(TemplateTopologyFields):
|
||||
|
||||
SCENARIOS = 'scenarios'
|
||||
|
@ -14,13 +14,18 @@
|
||||
|
||||
from oslo_log import log
|
||||
|
||||
from vitrage.evaluator.template_fields import DEFAULT_VERSION
|
||||
from vitrage.evaluator.template_fields import SUPPORTED_VERSIONS
|
||||
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.definitions_validator \
|
||||
import DefinitionsValidator as DefValidator
|
||||
from vitrage.evaluator.template_validation.content.scenario_validator import \
|
||||
ScenarioValidator
|
||||
from vitrage.evaluator.template_validation.status_messages import status_msgs
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
@ -30,11 +35,12 @@ def content_validation(template, def_templates=None):
|
||||
if def_templates is None:
|
||||
def_templates = {}
|
||||
|
||||
result = get_content_correct_result()
|
||||
result = _validate_version(template)
|
||||
|
||||
entities_index = {}
|
||||
template_definitions = {}
|
||||
|
||||
if TemplateFields.DEFINITIONS in template:
|
||||
if result.is_valid_config and TemplateFields.DEFINITIONS in template:
|
||||
template_definitions = template[TemplateFields.DEFINITIONS]
|
||||
|
||||
if TemplateFields.ENTITIES in template_definitions:
|
||||
@ -76,3 +82,18 @@ def content_validation(template, def_templates=None):
|
||||
result = ScenarioValidator(definitions_index).validate(scenarios)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _validate_version(template):
|
||||
metadata = template.get(TemplateFields.METADATA)
|
||||
|
||||
if metadata is None:
|
||||
LOG.error('%s status code: %s' % (status_msgs[62], 62))
|
||||
return get_content_fault_result(62)
|
||||
|
||||
version = metadata.get(TemplateFields.VERSION, DEFAULT_VERSION)
|
||||
if version in SUPPORTED_VERSIONS:
|
||||
return get_content_correct_result()
|
||||
else:
|
||||
LOG.error('%s status code: %s' % (status_msgs[63], 63))
|
||||
return get_content_fault_result(63)
|
||||
|
@ -14,6 +14,7 @@
|
||||
from vitrage.common.constants import EdgeLabel
|
||||
from vitrage.common.constants import EntityCategory
|
||||
from vitrage.evaluator.actions.base import action_types
|
||||
from vitrage.evaluator.template_fields import SUPPORTED_VERSIONS
|
||||
|
||||
status_msgs = {
|
||||
|
||||
@ -41,6 +42,8 @@ status_msgs = {
|
||||
# metadata section status messages 60-79
|
||||
60: 'metadata section must contain id field.',
|
||||
62: 'metadata is a mandatory section.',
|
||||
63: 'Unsupported version. Version must be one of: {versions}'
|
||||
.format(versions=SUPPORTED_VERSIONS),
|
||||
|
||||
# scenarios section status messages 80-99
|
||||
80: 'scenarios is a mandatory section.',
|
||||
|
@ -115,6 +115,7 @@ def _validate_metadata_section(metadata):
|
||||
any_str = Any(str, six.text_type)
|
||||
|
||||
schema = Schema({
|
||||
TemplateFields.VERSION: any_str,
|
||||
Required(TemplateFields.NAME, msg=60): any_str,
|
||||
TemplateFields.DESCRIPTION: any_str
|
||||
})
|
||||
|
@ -0,0 +1,30 @@
|
||||
metadata:
|
||||
version: 999
|
||||
name: invalid_version
|
||||
description: template with an invalid version
|
||||
definitions:
|
||||
entities:
|
||||
- entity:
|
||||
category: ALARM
|
||||
name: compute.host.down
|
||||
template_id: host_down_alarm
|
||||
- entity:
|
||||
category: RESOURCE
|
||||
type: nova.host
|
||||
template_id: host
|
||||
relationships:
|
||||
- relationship:
|
||||
source: host_down_alarm
|
||||
relationship_type: on
|
||||
target: host
|
||||
template_id : host_down_alarm_on_host
|
||||
scenarios:
|
||||
- scenario:
|
||||
condition: host_down_alarm_on_host
|
||||
actions:
|
||||
- action:
|
||||
action_type: set_state
|
||||
properties:
|
||||
state: ERROR
|
||||
action_target:
|
||||
target: host
|
29
vitrage/tests/resources/templates/version/no_version.yaml
Normal file
29
vitrage/tests/resources/templates/version/no_version.yaml
Normal file
@ -0,0 +1,29 @@
|
||||
metadata:
|
||||
name: no_version
|
||||
description: template without version
|
||||
definitions:
|
||||
entities:
|
||||
- entity:
|
||||
category: ALARM
|
||||
name: compute.host.down
|
||||
template_id: host_down_alarm
|
||||
- entity:
|
||||
category: RESOURCE
|
||||
type: nova.host
|
||||
template_id: host
|
||||
relationships:
|
||||
- relationship:
|
||||
source: host_down_alarm
|
||||
relationship_type: on
|
||||
target: host
|
||||
template_id : host_down_alarm_on_host
|
||||
scenarios:
|
||||
- scenario:
|
||||
condition: host_down_alarm_on_host
|
||||
actions:
|
||||
- action:
|
||||
action_type: set_state
|
||||
properties:
|
||||
state: ERROR
|
||||
action_target:
|
||||
target: host
|
30
vitrage/tests/resources/templates/version/version1.yaml
Normal file
30
vitrage/tests/resources/templates/version/version1.yaml
Normal file
@ -0,0 +1,30 @@
|
||||
metadata:
|
||||
version: 1
|
||||
name: version_1
|
||||
description: template with version 1
|
||||
definitions:
|
||||
entities:
|
||||
- entity:
|
||||
category: ALARM
|
||||
name: compute.host.down
|
||||
template_id: host_down_alarm
|
||||
- entity:
|
||||
category: RESOURCE
|
||||
type: nova.host
|
||||
template_id: host
|
||||
relationships:
|
||||
- relationship:
|
||||
source: host_down_alarm
|
||||
relationship_type: on
|
||||
target: host
|
||||
template_id : host_down_alarm_on_host
|
||||
scenarios:
|
||||
- scenario:
|
||||
condition: host_down_alarm_on_host
|
||||
actions:
|
||||
- action:
|
||||
action_type: set_state
|
||||
properties:
|
||||
state: ERROR
|
||||
action_target:
|
||||
target: host
|
@ -25,6 +25,7 @@ from vitrage.utils import file as file_utils
|
||||
|
||||
CONDITION_TEMPLATES_DIR = '%s/templates/evaluator/conditions/%s'
|
||||
REGEX_TEMPLATE_DIR = '%s/templates/regex/%s'
|
||||
VERSION_TEMPLATE_DIR = '%s/templates/version/%s'
|
||||
|
||||
|
||||
class TemplateContentValidatorTest(ValidatorTest):
|
||||
@ -277,6 +278,27 @@ class TemplateContentValidatorTest(ValidatorTest):
|
||||
self._execute_and_assert_with_correct_result(
|
||||
basic_regex_template)
|
||||
|
||||
def test_validate_template_with_no_version(self):
|
||||
invalid_version_path = \
|
||||
VERSION_TEMPLATE_DIR % (utils.get_resources_dir(),
|
||||
"no_version.yaml")
|
||||
template = file_utils.load_yaml_file(invalid_version_path)
|
||||
self._execute_and_assert_with_correct_result(template)
|
||||
|
||||
def test_validate_template_with_version_1(self):
|
||||
invalid_version_path = \
|
||||
VERSION_TEMPLATE_DIR % (utils.get_resources_dir(),
|
||||
"version1.yaml")
|
||||
template = file_utils.load_yaml_file(invalid_version_path)
|
||||
self._execute_and_assert_with_correct_result(template)
|
||||
|
||||
def test_validate_template_with_invalid_version(self):
|
||||
invalid_version_path = \
|
||||
VERSION_TEMPLATE_DIR % (utils.get_resources_dir(),
|
||||
"invalid_version.yaml")
|
||||
template = file_utils.load_yaml_file(invalid_version_path)
|
||||
self._execute_and_assert_with_fault_result(template, 63)
|
||||
|
||||
def _execute_condition_template_with_correct_result(self, template_name):
|
||||
template_path = CONDITION_TEMPLATES_DIR % (utils.get_resources_dir(),
|
||||
template_name)
|
||||
|
@ -36,6 +36,8 @@ class TemplateSyntaxValidatorTest(base.BaseTest):
|
||||
cls.def_template_dir_path = utils.get_resources_dir() + \
|
||||
'/templates/def_template_tests'
|
||||
template_dir_path = '%s/templates/general' % utils.get_resources_dir()
|
||||
cls.version_dir_path = '%s/templates/version/' \
|
||||
% 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
|
||||
@ -219,6 +221,23 @@ class TemplateSyntaxValidatorTest(base.BaseTest):
|
||||
template = file_utils.load_yaml_file(template_path)
|
||||
self._test_execution_with_correct_result(template)
|
||||
|
||||
def test_template_with_no_version(self):
|
||||
template_path = self.version_dir_path + 'no_version.yaml'
|
||||
template = file_utils.load_yaml_file(template_path)
|
||||
self._test_execution_with_correct_result(template)
|
||||
|
||||
def test_template_with_valid_version(self):
|
||||
template_path = self.version_dir_path + 'version1.yaml'
|
||||
template = file_utils.load_yaml_file(template_path)
|
||||
self._test_execution_with_correct_result(template)
|
||||
|
||||
def test_template_with_invalid_version(self):
|
||||
# Invalid version number is checked by the content validator, not by
|
||||
# the syntax validator
|
||||
template_path = self.version_dir_path + 'invalid_version.yaml'
|
||||
template = file_utils.load_yaml_file(template_path)
|
||||
self._test_execution_with_correct_result(template)
|
||||
|
||||
def _test_validate_action_without_required_fields(self):
|
||||
|
||||
self._test_validate_action_without_required_field(
|
||||
|
Loading…
Reference in New Issue
Block a user