def _add_equivalence(self, equivalence): for entity in equivalence: if entity in self.entity_equivalences: # TODO(yujunz): log error and continue processing the rest raise VitrageError('one entity should not be included in ' 'multiple equivalence definitions') self.entity_equivalences[entity] = equivalence
def _get_single_graph_vertex_by_props(self, vertex, include_deleted=False): """Returns a single vertex by it's defining properties Queries the graph DB for vertices according to the vertice's "key" properties In case multiple vertices return from the query, an exception is issued :param updated_vertex: The vertex with the defining properties :type vertex: Vertex :param include_deleted: Include deleted entities in the query :type include_deleted: bool """ received_graph_vertices = self.entity_graph.get_vertices_by_key( PUtils.get_defining_properties(vertex)) graph_vertices = [] if include_deleted: for tmp_vertex in received_graph_vertices: graph_vertices.append(tmp_vertex) else: for tmp_vertex in received_graph_vertices: if not tmp_vertex.get(VProps.IS_DELETED, False): graph_vertices.append(tmp_vertex) if len(graph_vertices) > 1: raise VitrageError( 'found too many vertices with same properties: %s ', vertex) graph_vertex = None if not graph_vertices else graph_vertices[0] return graph_vertex
def _rollback_to_default(self, templates): try: for t in templates: db_row = vitrage_utils.get_first_template(name=t) vitrage_utils.delete_template(db_row['uuid']) except Exception as e: raise VitrageError('Rollback to default failed %s', e)
def submit_template_event(self, event): """Template worker to load the new/deleted template Load the template to scenario-evaluator and run it on the entire graph """ template_action = event.get(TEMPLATE_ACTION) if template_action == ADD: templates = self._db.templates.query(status=TStatus.LOADING) new_status = TStatus.ACTIVE action_mode = ActionMode.DO elif template_action == DELETE: templates = self._db.templates.query(status=TStatus.DELETING) new_status = TStatus.DELETED action_mode = ActionMode.UNDO else: raise VitrageError('Invalid template_action %s' % template_action) self._submit_and_wait(self._template_queues, ( TEMPLATE_ACTION, [t.name for t in templates if t.template_type == TType.STANDARD], action_mode, )) for t in templates: self._db.templates.update(t.uuid, 'status', new_status)
def extract_var(symbol_name): if symbol_name in entities: return entities[symbol_name], ENTITY elif symbol_name in relationships: return relationships[symbol_name], RELATIONSHIP else: raise VitrageError( 'invalid symbol name: {}'.format(symbol_name))
def _default_root_id(self): tmp_vertices = self.entity_graph.get_vertices( vertex_attr_filter={VProps.VITRAGE_TYPE: OPENSTACK_CLUSTER}) if not tmp_vertices: LOG.debug("No root vertex found") return None if len(tmp_vertices) > 1: raise VitrageError("Multiple root vertices found") return tmp_vertices[0].vertex_id
def _show_template(uuid): try: templates = pecan.request.storage.templates.query(uuid=uuid) if not templates: raise VitrageError("Template %s not found", uuid) return templates[0].file_content except Exception: LOG.exception('Failed to show template with uuid: %s ', uuid) abort(404, 'Failed to show template.')
def _show_template(_id): uuid = TemplateController._to_uuid(_id) try: templates = pecan.request.storage.templates.query(uuid=uuid) if not templates or templates[0].status == TStatus.DELETED: raise VitrageError("Template %s not found", uuid) return templates[0].file_content except Exception: LOG.exception('Failed to show template with uuid: %s ', uuid) abort(404, 'Failed to show template.')
def _show_template(uuid): try: templates = pecan.request.storage.templates.query(uuid=uuid) if not templates: raise VitrageError("Template %s not found", uuid) return templates[0].file_content except Exception as e: to_unicode = encodeutils.exception_to_unicode(e) LOG.exception('failed to show template with uuid: %s ', to_unicode) abort(404, to_unicode)
def _validate_template(db, template, template_type): if template_type == TType.DEFINITION: result = template_validation.validate_definition_template(template) elif template_type == TType.STANDARD: result = template_validation.validate_template(template, _load_def_templates(db)) elif template_type == TType.EQUIVALENCE: result = base.Result("", True, "", "No Validation") else: raise VitrageError("Unknown template type %s", template_type) return result
def add_api_workers(self): """Add Api workers Api workers receive all graph updates, hence are updated. Each template worker holds a disabled scenario-evaluator that does not process changes. These also hold a rpc server and process the incoming Api calls """ if self._api_queues: raise VitrageError('add_api_workers called more than once') workers = self._conf.api.workers queues = [multiprocessing.Queue() for i in range(workers)] self.add(ApiWorker, args=(self._conf, queues), workers=workers) self._api_queues = queues self._all_queues.extend(queues)
def add_evaluator_workers(self): """Add evaluator workers Evaluator workers receive all graph updates, hence are updated. Each evaluator worker holds an enabled scenario-evaluator and process every change. Each worker's scenario-evaluator runs different template scenarios. Interface to these workers is: submit_graph_update(..) submit_start_evaluations(..) submit_evaluators_reload_templates(..) """ if self._evaluator_queues: raise VitrageError('add_evaluator_workers called more than once') workers = CONF.evaluator.workers queues = [multiprocessing.JoinableQueue() for i in range(workers)] self.add(EvaluatorWorker, args=(queues, workers), workers=workers) self._evaluator_queues = queues self._all_queues.extend(queues)
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(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 add_template_workers(self): """Add template workers Template workers receive all graph updates, hence are updated. Each template worker holds a disabled scenario-evaluator that does not process changes. The scenario-evaluator is enabled when a template add/delete arrives, so this worker will run the added template on the entire graph. Interface to these workers is: submit_graph_update(..) submit_template_event(..) """ if self._template_queues: raise VitrageError('add_template_workers called more than once') workers = 1 # currently more than one worker is not supported queues = [multiprocessing.JoinableQueue() for i in range(workers)] self.add(TemplateLoaderWorker, args=(self._conf, queues, self._entity_graph), workers=workers) self._template_queues = queues self._all_queues.extend(queues)
def create_predicate(query_dict): """Create predicate from a logical and/or/==/>/etc expression Example Input: -------------- query_dict = { 'and': [ {'==': {'TYPE': 'ALARM'}}, {'or': [ {'>': {'TIME': 150}}, {'==': {'IS_DELETED': True}} ]} ] } Example Output: -------------- lambda item: ((item['TYPE']== 'ALARM') and ((item['TIME']> 150) or (item['IS_DELETED']== True))) Example Usage: -------------- match = create_predicate(query_dict) if match(vertex): print vertex :param query_dict: :return: a predicate "match(item)" """ try: expression = _create_query_expression(query=query_dict) LOG.debug('create_predicate::%s', expression) expression = 'lambda item: ' + expression return eval(expression) except Exception as e: LOG.error('invalid query format %s. Exception: %s', query_dict, e) raise VitrageError('invalid query format %s. Exception: %s', query_dict, e)
def _create_query_expression(query, parent_operator=None): expressions = [] # First element or element under logical operation if not parent_operator and isinstance(query, dict): (key, value) = query.copy().popitem() return _create_query_expression(value, key) # Continue recursion on logical (and/or) operation elif parent_operator in logical_operations and isinstance(query, list): for val in query: expressions.append(_create_query_expression(val)) return _join_logical_operator(parent_operator, expressions) # Recursion evaluate leaf (stop condition) elif parent_operator in operators: for key, val in query.items(): expressions.append('item.get(' + _evaluable_str(key) + ')' + parent_operator + ' ' + _evaluable_str(val)) return _join_logical_operator('and', expressions) else: raise VitrageError('invalid partial query format', parent_operator, query)
def _create_entity_graph(cls, name, num_of_alarms_per_host, num_of_alarms_per_vm, num_of_hosts_per_node, num_of_vms_per_host, num_of_tests_per_host): start = time.time() g = NXGraph(name) g.add_vertex(v_node) g.add_vertex(v_switch) g.add_edge(e_node_to_switch) # Add Hosts for host_id in range(num_of_hosts_per_node): host_to_add = add_connected_vertex(g, RESOURCE, NOVA_HOST_DATASOURCE, host_id, ELabel.CONTAINS, v_node, True) g.add_edge(graph_utils.create_edge(host_to_add.vertex_id, v_switch.vertex_id, 'USES')) # Add Host Alarms for j in range(num_of_alarms_per_host): add_connected_vertex(g, ALARM, ALARM_ON_HOST, cls.host_alarm_id, ELabel.ON, host_to_add, False, {VProps.RESOURCE_ID: host_id, VProps.NAME: host_id}) cls.host_alarm_id += 1 # Add Host Tests for j in range(num_of_tests_per_host): add_connected_vertex(g, TEST, TEST_ON_HOST, cls.host_test_id, ELabel.ON, host_to_add) cls.host_test_id += 1 # Add Host Vms for j in range(num_of_vms_per_host): vm_to_add = add_connected_vertex(g, RESOURCE, NOVA_INSTANCE_DATASOURCE, cls.vm_id, ELabel.CONTAINS, host_to_add, True) cls.vm_id += 1 cls.vms.append(vm_to_add) # Add Instance Alarms for k in range(num_of_alarms_per_vm): add_connected_vertex(g, ALARM, ALARM_ON_VM, cls.vm_alarm_id, ELabel.ON, vm_to_add, False, {VProps.RESOURCE_ID: cls.vm_id - 1, VProps.NAME: cls.vm_id - 1}) cls.vm_alarm_id += 1 end = time.time() LOG.debug('Graph creation took ' + str(end - start) + ' seconds, size is: ' + str(len(g))) expected_graph_size = \ 2 + num_of_hosts_per_node + num_of_hosts_per_node * \ num_of_alarms_per_host + num_of_hosts_per_node * \ num_of_vms_per_host + num_of_hosts_per_node * \ num_of_vms_per_host * num_of_alarms_per_vm + \ num_of_tests_per_host * num_of_hosts_per_node if not expected_graph_size == len(g): raise VitrageError('Init failed, graph size unexpected {0} != {1}' .format(expected_graph_size, len(g))) return g