def relation_str(matchobj): source = matchobj.group(1) label = matchobj.group(2) target = matchobj.group(3) relation_id = '%s__%s__%s' % (source, label, target) extracted_relationships[relation_id] = EdgeDescription( Edge(source, target, label, dict()), entities[source], entities[target]) return relation_id
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)
def _build_equivalent_relationship(relationship, template_id, entity_props): source = relationship.source target = relationship.target if relationship.edge.source_id == template_id: source = Vertex(vertex_id=source.vertex_id, properties={k: v for k, v in entity_props}) elif relationship.edge.target_id == template_id: target = Vertex(vertex_id=target.vertex_id, properties={k: v for k, v in entity_props}) return EdgeDescription(source=source, target=target, edge=relationship.edge)
def _get_edge_description(self, element): source = self._entity_graph.get_vertex(element.source_id) target = self._entity_graph.get_vertex(element.target_id) edge_desc = EdgeDescription(element, source, target) return edge_desc
def _copy_edge_desc(edge_desc): return EdgeDescription(edge=edge_desc.edge.copy(), source=edge_desc.source.copy(), target=edge_desc.target.copy())
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 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 = \ TemplateLoader().load(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 = TemplateLoader.PROPS_CONVERSION[key] if key in \ TemplateLoader.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', version=1, condition=[[ ConditionVar(symbol_name='alarm_on_host', positive=True) ]], actions=[ ActionSpecs( id='basic_template_with_include-scenario0-action0', 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 = TemplateLoader().load(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 = TemplateLoader.PROPS_CONVERSION[key] if key in \ TemplateLoader.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', version=1, condition=[[ ConditionVar(symbol_name='alarm_on_host', positive=True) ]], actions=[ ActionSpecs( id='basic_template-scenario0-action0', 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)
class TemplateLoaderV3Test(BaseTest, TestConfiguration): expected_entities = { 'host_ssh_alarm': Vertex('host_ssh_alarm', { 'rawtext': 'host ssh is down', 'vitrage_type': 'zabbix' }), 'host': Vertex('host', {'vitrage_type': 'nova.host'}), 'foo': Vertex('foo', {'name.regex': 'kuku'}), 'host_network_alarm': Vertex( 'host_network_alarm', { 'rawtext': 'host network interface is down', 'vitrage_type': 'zabbix', }), 'instance': Vertex('instance', {'vitrage_type': 'nova.instance'}), } expected_relationships = { 'host_ssh_alarm__on__host': EdgeDescription( Edge('host_ssh_alarm', 'host', 'on', {}), Vertex('host_ssh_alarm', { 'rawtext': 'host ssh is down', 'vitrage_type': 'zabbix' }), Vertex('host', {'vitrage_type': 'nova.host'})), 'host__contains__instance': EdgeDescription(Edge('host', 'instance', 'contains', {}), Vertex('host', {'vitrage_type': 'nova.host'}), Vertex('instance', {'vitrage_type': 'nova.instance'})), 'host_network_alarm__on__host': EdgeDescription( Edge('host_network_alarm', 'host', 'on', {}), Vertex( 'host_network_alarm', { 'rawtext': 'host network interface is down', 'vitrage_type': 'zabbix' }), Vertex('host', {'vitrage_type': 'nova.host'})), } @classmethod def setUpClass(cls): super(TemplateLoaderV3Test, cls).setUpClass() cls.conf = cfg.ConfigOpts() cls.add_db(cls.conf) def _load_scenarios(self, file=None, content=None): if file and not content: content = self._get_yaml(file) return get_template_data(content).scenarios def _assert_scenario_equal(self, expected, observed): # Basic self.assertEqual(expected.id, observed.id) self.assertEqual(expected.version, observed.version) self.assertEqual(expected.condition, observed.condition) # is None # Actions self.assertEqual(len(expected.actions), len(observed.actions), 'actions count') for j in range(len(expected.actions)): expected_action = expected.actions[j] observed_action = observed.actions[j] self.assertEqual(expected_action.id, observed_action.id) self.assertEqual(expected_action.type, observed_action.type) self.assertEqual(expected_action.properties, observed_action.properties) if expected_action.type == 'execute_mistral': continue self.assertEqual(expected_action.targets, observed_action.targets) # Subgraphs self.assertEqual(len(expected.subgraphs), len(observed.subgraphs), 'subgraphs count') for j in range(len(expected.subgraphs)): expected_subgraph = expected.subgraphs[j] observed_subgraph = observed.subgraphs[j] self.assert_graph_equal(expected_subgraph, observed_subgraph) # Entities self.assert_dict_equal(expected.entities, observed.entities, 'entities comparison') self.assert_dict_equal(expected.relationships, observed.relationships, 'relationships comparison') @staticmethod def _get_yaml(filename): path = '%s/templates/v3_templates/%s' % (get_resources_dir(), filename) return file_utils.load_yaml_file(path) def test_scenarios(self): observed_scenarios = self._load_scenarios('valid_actions.yaml') self.assertEqual(6, len(observed_scenarios), 'scenarios count') def test_scenario_0(self): observed_scenarios = self._load_scenarios('valid_actions.yaml') expected_scenario = Scenario( 'valid actions-scenario0', '3', None, [ ActionSpecs('valid actions-scenario0-action0', 'set_state', {'target': 'host'}, {'state': 'ERROR'}), ActionSpecs('valid actions-scenario0-action1', 'raise_alarm', {'target': 'host'}, { 'severity': 'WARNING', 'alarm_name': 'ddd' }), ActionSpecs('valid actions-scenario0-action2', 'mark_down', {'target': 'host'}, {}), ActionSpecs('valid actions-scenario0-action3', 'execute_mistral', {'target': 'host'}, { 'input': { 'farewell': 'get_attr(host, name) bla bla' }, 'workflow': 'wf_1234' }), ], [ NXGraph(vertices=[ Vertex( 'host_ssh_alarm', { 'rawtext': 'host ssh is down', 'vitrage_is_placeholder': False, 'vitrage_type': 'zabbix', 'vitrage_is_deleted': False, }), Vertex( 'host', { 'vitrage_is_placeholder': False, 'vitrage_type': 'nova.host', 'vitrage_is_deleted': False, }) ], edges=[ Edge( 'host_ssh_alarm', 'host', 'on', { 'vitrage_is_deleted': False, 'negative_condition': False }) ]) ], TemplateLoaderV3Test.expected_entities, TemplateLoaderV3Test.expected_relationships) self._assert_scenario_equal(expected_scenario, observed_scenarios[0]) def test_scenario_1(self): observed_scenarios = self._load_scenarios('valid_actions.yaml') expected_scenario = Scenario( 'valid actions-scenario1', '3', None, [ ActionSpecs('valid actions-scenario1-action0', 'add_causal_relationship', { 'target': 'host_ssh_alarm', 'source': 'host_network_alarm', }, {}), ], [ NXGraph(vertices=[ Vertex( 'host_ssh_alarm', { 'rawtext': 'host ssh is down', 'vitrage_is_placeholder': False, 'vitrage_type': 'zabbix', 'vitrage_is_deleted': False, }), Vertex( 'host_network_alarm', { 'rawtext': 'host network interface is down', 'vitrage_is_placeholder': False, 'vitrage_type': 'zabbix', 'vitrage_is_deleted': False, }), Vertex( 'host', { 'vitrage_is_placeholder': False, 'vitrage_type': 'nova.host', 'vitrage_is_deleted': False, }) ], edges=[ Edge( 'host_ssh_alarm', 'host', 'on', { 'vitrage_is_deleted': False, 'negative_condition': False }), Edge( 'host_network_alarm', 'host', 'on', { 'vitrage_is_deleted': False, 'negative_condition': False }) ]) ], TemplateLoaderV3Test.expected_entities, TemplateLoaderV3Test.expected_relationships) self._assert_scenario_equal(expected_scenario, observed_scenarios[1]) def test_scenario_2(self): observed_scenarios = self._load_scenarios('valid_actions.yaml') expected_scenario = Scenario( 'valid actions-scenario2', '3', None, [ ActionSpecs( 'valid actions-scenario2-action0', 'raise_alarm', {'target': 'instance'}, { 'severity': 'WARNING', 'alarm_name': 'instance is down', 'causing_alarm': 'get_attr(host_ssh_alarm, vitrage_id)', }), ActionSpecs('valid actions-scenario2-action1', 'set_state', {'target': 'instance'}, {'state': 'SUBOPTIMAL'}), ], [ NXGraph(vertices=[ Vertex( 'host_ssh_alarm', { 'rawtext': 'host ssh is down', 'vitrage_is_placeholder': False, 'vitrage_type': 'zabbix', 'vitrage_is_deleted': False, }), Vertex( 'instance', { 'vitrage_is_placeholder': False, 'vitrage_type': 'nova.instance', 'vitrage_is_deleted': False, }), Vertex( 'host', { 'vitrage_is_placeholder': False, 'vitrage_type': 'nova.host', 'vitrage_is_deleted': False, }), ], edges=[ Edge( 'host_ssh_alarm', 'host', 'on', { 'vitrage_is_deleted': False, 'negative_condition': False }), Edge( 'host', 'instance', 'contains', { 'vitrage_is_deleted': False, 'negative_condition': False }) ]) ], TemplateLoaderV3Test.expected_entities, TemplateLoaderV3Test.expected_relationships) self._assert_scenario_equal(expected_scenario, observed_scenarios[2]) def test_scenario_3(self): observed_scenarios = self._load_scenarios('valid_actions.yaml') expected_scenario = Scenario( 'valid actions-scenario3', '3', None, [ ActionSpecs('valid actions-scenario3-action0', 'mark_down', {'target': 'host'}, {}), ], [ NXGraph(vertices=[ Vertex( 'instance', { 'vitrage_is_placeholder': False, 'vitrage_type': 'nova.instance', 'vitrage_is_deleted': False, }), Vertex( 'host', { 'vitrage_is_placeholder': False, 'vitrage_type': 'nova.host', 'vitrage_is_deleted': False, }), ], edges=[ Edge( 'host', 'instance', 'contains', { 'vitrage_is_deleted': False, 'negative_condition': False }) ]), NXGraph(vertices=[ Vertex( 'host_ssh_alarm', { 'rawtext': 'host ssh is down', 'vitrage_is_placeholder': False, 'vitrage_type': 'zabbix', 'vitrage_is_deleted': False, }), Vertex( 'host', { 'vitrage_is_placeholder': False, 'vitrage_type': 'nova.host', 'vitrage_is_deleted': False, }), ], edges=[ Edge( 'host_ssh_alarm', 'host', 'on', { 'vitrage_is_deleted': True, 'negative_condition': True, }), ]), ], TemplateLoaderV3Test.expected_entities, TemplateLoaderV3Test.expected_relationships) self._assert_scenario_equal(expected_scenario, observed_scenarios[3]) def test_scenario_4(self): observed_scenarios = self._load_scenarios('valid_actions.yaml') expected_scenario = Scenario( 'valid actions-scenario4', '3', None, [ ActionSpecs('valid actions-scenario4-action0', 'mark_down', {'target': 'host'}, {}), ], [ NXGraph(vertices=[ Vertex( 'host', { 'vitrage_is_placeholder': False, 'vitrage_type': 'nova.host', 'vitrage_is_deleted': False, }), ]), ], TemplateLoaderV3Test.expected_entities, TemplateLoaderV3Test.expected_relationships) self._assert_scenario_equal(expected_scenario, observed_scenarios[4]) def test_scenario_5(self): observed_scenarios = self._load_scenarios('valid_actions.yaml') expected_scenario = Scenario( 'valid actions-scenario5', '3', None, [ ActionSpecs('valid actions-scenario5-action0', 'mark_down', {'target': 'host'}, {}), ], [ NXGraph( vertices=[ Vertex( 'host_ssh_alarm', { 'rawtext': 'host ssh is down', 'vitrage_is_placeholder': False, 'vitrage_type': 'zabbix', 'vitrage_is_deleted': False, }), Vertex( 'instance', { 'vitrage_is_placeholder': False, 'vitrage_type': 'nova.instance', 'vitrage_is_deleted': False, }), Vertex( 'host', { 'vitrage_is_placeholder': False, 'vitrage_type': 'nova.host', 'vitrage_is_deleted': False, }), ], edges=[ Edge('host_ssh_alarm', 'host', 'on', { 'vitrage_is_deleted': True, 'negative_condition': True }), Edge('host', 'instance', 'contains', { 'vitrage_is_deleted': True, 'negative_condition': True }) ]), ], TemplateLoaderV3Test.expected_entities, TemplateLoaderV3Test.expected_relationships) self._assert_scenario_equal(expected_scenario, observed_scenarios[5])