def load(self, template_def, def_templates=None): name = template_def[TFields.METADATA][TFields.NAME] 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(name, self.entities, self.relationships)\ .build_scenarios(template_def[TFields.SCENARIOS]) return TemplateData(name, self.entities, self.relationships, scenarios)
def validate_scenario_condition(condition, definitions_index): try: TemplateData.convert_to_dnf_format(condition) except Exception: LOG.error('%s status code: %s' % (status_msgs[85], 85)) return get_fault_result(RESULT_DESCRIPTION, 85) values_to_replace = ' and ', ' or ', ' not ', '(', ')' condition = reduce(lambda cond, v: cond.replace(v, ' '), values_to_replace, condition) for condition_var in condition.split(' '): if len(condition_var.strip()) == 0: continue result = _validate_template_id(definitions_index, condition_var) if not result.is_valid: return result return get_correct_result(RESULT_DESCRIPTION)
def validate_scenario_condition(condition, definitions_index): try: TemplateData.convert_to_dnf_format(condition) except Exception: LOG.error('%s status code: %s' % (status_msgs[85], 85)) return get_fault_result(RESULT_DESCRIPTION, 85) values_to_replace = ' and ', ' or ', ' not ', '(', ')' condition = reduce(lambda cond, v: cond.replace(v, ' '), values_to_replace, condition) for condition_var in condition.split(' '): if len(condition_var.strip()) == 0: continue result = _validate_template_id(definitions_index, condition_var) if not result.is_valid_config: return result return get_correct_result(RESULT_DESCRIPTION)
def _check_get_condition_common_targets(self, template_name, valid_targets): template_path = CONDITION_TEMPLATES_DIR % (utils.get_resources_dir(), template_name) template_definition = file_utils.load_yaml_file(template_path, True) template_data = TemplateData(template_definition) definitions_index = template_data.entities.copy() definitions_index.update(template_data.relationships) common_targets = get_condition_common_targets( template_data.scenarios[0].condition, definitions_index, self.ConditionSymbolResolver()) self.assertIsNotNone(common_targets) self.assertTrue(common_targets == set(valid_targets))
def add_template(self, template_def): current_time = datetime_utils.utcnow() result = syntax_validation(template_def) if not result.is_valid: LOG.info('Unable to load template: %s', result.comment) else: result = content_validation(template_def) if not result.is_valid: LOG.info('Unable to load template: %s', result.comment) template_uuid = uuid.uuid4() self.templates[str(template_uuid)] = Template(template_uuid, template_def, current_time, result) if result.is_valid: template_data = TemplateData(template_def) self._add_template_scenarios(template_data)
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] # template_type might be None, it is defined only in version 2 template_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, template_type, template_schema.version(), self.entities, self.relationships, scenarios)
def test_basic_template(self): # Test setup template_path = '%s/templates/general/%s' % (utils.get_resources_dir(), self.BASIC_TEMPLATE) template_definition = file_utils.load_yaml_file(template_path, True) template_data = TemplateData(template_definition) entities = template_data.entities relationships = template_data.relationships scenarios = template_data.scenarios definitions = template_definition[TFields.DEFINITIONS] # Assertions entities_definition = definitions[TFields.ENTITIES] self._validate_entities(entities, entities_definition) relate_def = definitions[TFields.RELATIONSHIPS] self._validate_relationships(relationships, relate_def, entities) self._validate_scenarios(scenarios, entities)
def add_template(self, template_def): current_time = datetime_utils.utcnow() result = syntax_validation(template_def) if not result.is_valid_config: LOG.info('Unable to load template: %s' % result.comment) else: result = content_validation(template_def) if not result.is_valid_config: LOG.info('Unable to load template: %s' % result.comment) template_uuid = uuidutils.generate_uuid() self.templates[str(template_uuid)] = Template(template_uuid, template_def, current_time, result) if result.is_valid_config: template_data = TemplateData(template_def) for scenario in template_data.scenarios: for equivalent_scenario in self._expand_equivalence(scenario): self._add_scenario(equivalent_scenario)
def _build_equivalences(equivalence_defs): """equivalence stored as arrays of frozen entity props sets equivalences:: [equivalence, ...] equivalence:: {entity_props, ...} entity_props:: {(k,v), ...} """ equivalences = [] for equivalence_def in equivalence_defs: equivalent_entities = equivalence_def[Fields.EQUIVALENCE] equivalence = set() for entity_def in equivalent_entities: entity_props = {(k, v) for k, v in entity_def[Fields.ENTITY].items()} entity_key = frozenset( TemplateData._convert_props_with_set(entity_props)) if entity_key in equivalence: raise VitrageError('duplicated entities found in ' 'equivalence') equivalence.add(entity_key) equivalences.append(frozenset(equivalence)) return equivalences
def test_basic_template(self): # Test setup template_path = '%s/templates/general/%s' % (utils.get_resources_dir(), self.BASIC_TEMPLATE) template_definition = file_utils.load_yaml_file(template_path, True) template_data = TemplateData(template_definition) entities = template_data.entities relationships = template_data.relationships scenarios = template_data.scenarios definitions = template_definition[TFields.DEFINITIONS] # Assertions entities_definition = definitions[TFields.ENTITIES] self._validate_entities(entities, entities_definition) relate_def = definitions[TFields.RELATIONSHIPS] self._validate_relationships(relationships, relate_def, entities) self._validate_scenarios(scenarios, entities) expected_entities = { 'alarm': Vertex(vertex_id='alarm', properties={ 'category': 'ALARM', 'type': 'nagios', 'name': 'host_problem' }), 'resource': Vertex(vertex_id='resource', properties={ 'category': 'RESOURCE', 'type': 'nova.host' }) } expected_relationships = { 'alarm_on_host': EdgeDescription(edge=Edge(source_id='alarm', target_id='resource', label='on', properties={'relationship_type': 'on'}), source=expected_entities['alarm'], target=expected_entities['resource']) } expected_scenario = Scenario( id='basic_template-scenario0', condition=[[ ConditionVar(symbol_name='alarm_on_host', positive=True) ]], actions=[ ActionSpecs(type='set_state', targets={'target': 'resource'}, properties={'state': 'SUBOPTIMAL'}) ], # TODO(yujunz): verify the built subgraph is consistent with # scenario definition. For now the observed value is # assigned to make test passing subgraphs=template_data.scenarios[0].subgraphs, entities=expected_entities, relationships=expected_relationships) self._validate_strict_equal(template_data, expected_entities, expected_relationships, expected_scenario)
def load(self, template_schema, template_def, def_templates=None): template = copy.deepcopy(template_def) entities = _build_entities(template) relationships = _build_condition_relationships(template, entities) return TemplateData(scenarios=_build_scenarios( template, entities, relationships, template_schema))
def test_basic_template_with_include(self): # Test setup template_path = self.DEF_TEMPLATE_TESTS_DIR +\ '/templates/%s' % self.BASIC_TEMPLATE_WITH_INCLUDE template_definition = file_utils.load_yaml_file(template_path, True) def_templates_path = self.DEF_TEMPLATE_TESTS_DIR + \ '/definition_templates' def_demplates_list = file_utils.load_yaml_files( def_templates_path) def_templates_dict = utils.get_def_templates_dict_from_list( def_demplates_list) template_data = TemplateData(template_definition, def_templates_dict) entities = template_data.entities relationships = template_data.relationships scenarios = template_data.scenarios definitions = template_definition[TFields.DEFINITIONS] def_template = file_utils.load_yaml_file( def_templates_path + '/basic_def_template.yaml') def_template_entities = \ def_template[TFields.DEFINITIONS][TFields.ENTITIES] def_template_relationships = \ def_template[TFields.DEFINITIONS][TFields.RELATIONSHIPS] definitions[TFields.ENTITIES] += def_template_entities definitions[TFields.RELATIONSHIPS] = def_template_relationships # Assertions for definition in definitions[TFields.ENTITIES]: for key, value in definition['entity'].items(): new_key = TemplateData.PROPS_CONVERSION[key] if key in \ TemplateData.PROPS_CONVERSION else key del definition['entity'][key] definition['entity'][new_key] = value self._validate_entities(entities, definitions[TFields.ENTITIES]) relate_def = def_template_relationships self._validate_relationships(relationships, relate_def, entities) self._validate_scenarios(scenarios, entities) expected_entities = { 'alarm11': Vertex( vertex_id='alarm11', properties={VProps.VITRAGE_CATEGORY: EntityCategory.ALARM, VProps.VITRAGE_TYPE: NAGIOS_DATASOURCE, VProps.NAME: 'host_problem' }), 'resource11': Vertex( vertex_id='resource11', properties={VProps.VITRAGE_CATEGORY: EntityCategory.RESOURCE, VProps.VITRAGE_TYPE: NOVA_HOST_DATASOURCE }), 'alarm': Vertex( vertex_id='alarm', properties={VProps.VITRAGE_CATEGORY: EntityCategory.ALARM, VProps.VITRAGE_TYPE: NAGIOS_DATASOURCE, VProps.NAME: 'host_problem' }), 'resource': Vertex( vertex_id='resource', properties={VProps.VITRAGE_CATEGORY: EntityCategory.RESOURCE, VProps.VITRAGE_TYPE: NOVA_HOST_DATASOURCE }) } expected_relationships = { 'alarm_on_host': EdgeDescription( edge=Edge(source_id='alarm', target_id='resource', label=EdgeLabel.ON, properties={EdgeProperties.RELATIONSHIP_TYPE: EdgeLabel.ON}), source=expected_entities['alarm'], target=expected_entities['resource'] ), } scenario_entities = { 'alarm': Vertex( vertex_id='alarm', properties={VProps.VITRAGE_CATEGORY: EntityCategory.ALARM, VProps.VITRAGE_TYPE: NAGIOS_DATASOURCE, VProps.NAME: 'host_problem' }), 'resource': Vertex( vertex_id='resource', properties={VProps.VITRAGE_CATEGORY: EntityCategory.RESOURCE, VProps.VITRAGE_TYPE: NOVA_HOST_DATASOURCE }) } expected_scenario = Scenario( id='basic_template_with_include-scenario0', condition=[ [ConditionVar(symbol_name='alarm_on_host', positive=True)]], actions=[ ActionSpecs( type=ActionType.SET_STATE, targets={'target': 'resource'}, properties={'state': OperationalResourceState.SUBOPTIMAL})], subgraphs=template_data.scenarios[0].subgraphs, entities=scenario_entities, relationships=expected_relationships ) self._validate_strict_equal(template_data, expected_entities, expected_relationships, expected_scenario)
def test_basic_template(self): # Test setup template_path = '%s/templates/general/%s' % (utils.get_resources_dir(), self.BASIC_TEMPLATE) template_definition = file_utils.load_yaml_file(template_path, True) template_data = TemplateData(template_definition) entities = template_data.entities relationships = template_data.relationships scenarios = template_data.scenarios definitions = template_definition[TFields.DEFINITIONS] # Assertions for definition in definitions[TFields.ENTITIES]: for key, value in definition['entity'].items(): new_key = TemplateData.PROPS_CONVERSION[key] if key in \ TemplateData.PROPS_CONVERSION else key del definition['entity'][key] definition['entity'][new_key] = value self._validate_entities(entities, definitions[TFields.ENTITIES]) relate_def = definitions[TFields.RELATIONSHIPS] self._validate_relationships(relationships, relate_def, entities) self._validate_scenarios(scenarios, entities) expected_entities = { 'alarm': Vertex( vertex_id='alarm', properties={VProps.VITRAGE_CATEGORY: EntityCategory.ALARM, VProps.VITRAGE_TYPE: NAGIOS_DATASOURCE, VProps.NAME: 'host_problem' }), 'resource': Vertex( vertex_id='resource', properties={VProps.VITRAGE_CATEGORY: EntityCategory.RESOURCE, VProps.VITRAGE_TYPE: NOVA_HOST_DATASOURCE }) } expected_relationships = { 'alarm_on_host': EdgeDescription( edge=Edge(source_id='alarm', target_id='resource', label=EdgeLabel.ON, properties={EdgeProperties.RELATIONSHIP_TYPE: EdgeLabel.ON}), source=expected_entities['alarm'], target=expected_entities['resource'] ) } expected_scenario = Scenario( id='basic_template-scenario0', condition=[ [ConditionVar(symbol_name='alarm_on_host', positive=True)]], actions=[ ActionSpecs( type=ActionType.SET_STATE, targets={'target': 'resource'}, properties={'state': OperationalResourceState.SUBOPTIMAL})], # TODO(yujunz): verify the built subgraph is consistent with # scenario definition. For now the observed value is # assigned to make test passing subgraphs=template_data.scenarios[0].subgraphs, entities=expected_entities, relationships=expected_relationships ) self._validate_strict_equal(template_data, expected_entities, expected_relationships, expected_scenario)