Merge "Vitrage ID and vertex id will be standard openstack uuid from now on - fixed"
This commit is contained in:
commit
ffb1e4b0f7
@ -22,10 +22,9 @@ from vitrage.common.constants import EdgeProperties as EProps
|
||||
from vitrage.common.constants import EntityCategory
|
||||
from vitrage.common.constants import VertexProperties as VProps
|
||||
from vitrage.datasources.nova.instance import NOVA_INSTANCE_DATASOURCE
|
||||
from vitrage.datasources import OPENSTACK_CLUSTER
|
||||
from vitrage.datasources.transformer_base import build_key
|
||||
from vitrage.datasources.transformer_base import CLUSTER_ID
|
||||
|
||||
from vitrage.datasources.transformer_base\
|
||||
import create_cluster_placeholder_vertex
|
||||
from vitrage.entity_graph.processor import processor_utils
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
@ -191,13 +190,19 @@ class TopologyApis(EntityGraphApisBase):
|
||||
|
||||
entities = []
|
||||
|
||||
if not root:
|
||||
root = build_key([EntityCategory.RESOURCE,
|
||||
OPENSTACK_CLUSTER,
|
||||
CLUSTER_ID])
|
||||
if root:
|
||||
root_vertex = \
|
||||
self.entity_graph.get_vertex(root)
|
||||
else:
|
||||
key_values_hash = processor_utils.get_defining_properties(
|
||||
create_cluster_placeholder_vertex())
|
||||
tmp_vertices = self.entity_graph.get_vertices_by_key(
|
||||
key_values_hash)
|
||||
if not tmp_vertices:
|
||||
LOG.debug("No root vertex found")
|
||||
return set(entities)
|
||||
root_vertex = tmp_vertices[0]
|
||||
|
||||
root_vertex = \
|
||||
self.entity_graph.get_vertex(root)
|
||||
local_connected_component_subgraphs = \
|
||||
ga.connected_component_subgraphs(subgraph)
|
||||
|
||||
|
@ -69,7 +69,8 @@ def init(conf):
|
||||
evaluator_q = queue.Queue()
|
||||
e_graph = entity_graph.get_graph_driver(conf)(
|
||||
'Entity Graph',
|
||||
'%s:%s:%s' % (EntityCategory.RESOURCE, OPENSTACK_CLUSTER, CLUSTER_ID))
|
||||
'%s:%s:%s' % (EntityCategory.RESOURCE, OPENSTACK_CLUSTER, CLUSTER_ID),
|
||||
uuid=True)
|
||||
scenario_repo = ScenarioRepository(conf)
|
||||
|
||||
evaluator = ScenarioEvaluator(conf, e_graph, scenario_repo, evaluator_q)
|
||||
|
@ -38,6 +38,7 @@ class VertexProperties(object):
|
||||
RAWTEXT = 'rawtext'
|
||||
RESOURCE_ID = 'resource_id'
|
||||
RESOURCE = 'resource'
|
||||
IS_REAL_VITRAGE_ID = 'is_real_vitrage_id'
|
||||
|
||||
|
||||
class EdgeProperties(object):
|
||||
|
@ -56,6 +56,7 @@ class AodhTransformer(AlarmTransformerBase):
|
||||
AodhProps.ENABLED: entity_event[AodhProps.ENABLED],
|
||||
VProps.PROJECT_ID: entity_event.get(AodhProps.PROJECT_ID, None),
|
||||
AodhProps.REPEAT_ACTIONS: entity_event[AodhProps.REPEAT_ACTIONS],
|
||||
VProps.RESOURCE_ID: entity_event[AodhProps.RESOURCE_ID],
|
||||
'alarm_type': entity_event[AodhProps.TYPE]
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,8 @@ class CollectdTransformer(AlarmTransformerBase):
|
||||
metadata = {
|
||||
VProps.NAME: entity_event[CProps.MESSAGE],
|
||||
VProps.SEVERITY: entity_event[CProps.SEVERITY],
|
||||
VProps.RAWTEXT: self.generate_raw_text(entity_event)
|
||||
VProps.RAWTEXT: self.generate_raw_text(entity_event),
|
||||
VProps.RESOURCE_ID: entity_event[CProps.RESOURCE_NAME]
|
||||
}
|
||||
|
||||
return graph_utils.create_vertex(
|
||||
|
@ -40,9 +40,16 @@ class ConsistencyTransformer(ResourceTransformerBase):
|
||||
|
||||
@staticmethod
|
||||
def _create_vertex(entity_event):
|
||||
metadata = {
|
||||
VProps.IS_REAL_VITRAGE_ID:
|
||||
entity_event.get(VProps.IS_REAL_VITRAGE_ID, False)
|
||||
}
|
||||
|
||||
return graph_utils.create_vertex(
|
||||
entity_event[VProps.VITRAGE_ID],
|
||||
sample_timestamp=entity_event[DSProps.SAMPLE_DATE])
|
||||
sample_timestamp=entity_event[DSProps.SAMPLE_DATE],
|
||||
metadata=metadata
|
||||
)
|
||||
|
||||
def _create_entity_key(self, entity_event):
|
||||
return None
|
||||
|
@ -48,6 +48,7 @@ class NagiosTransformer(AlarmTransformerBase):
|
||||
|
||||
metadata = {
|
||||
VProps.NAME: entity_event[NagiosProperties.SERVICE],
|
||||
VProps.RESOURCE_ID: entity_event[NagiosProperties.RESOURCE_NAME],
|
||||
VProps.SEVERITY: entity_event[NagiosProperties.STATUS],
|
||||
VProps.INFO: entity_event[NagiosProperties.STATUS_INFO]
|
||||
}
|
||||
|
@ -64,7 +64,8 @@ class ZabbixTransformer(AlarmTransformerBase):
|
||||
VProps.NAME: entity_event[ZProps.DESCRIPTION],
|
||||
VProps.SEVERITY: TriggerSeverity.str(
|
||||
entity_event[ZProps.PRIORITY]),
|
||||
VProps.RAWTEXT: entity_event[ZProps.RAWTEXT]
|
||||
VProps.RAWTEXT: entity_event[ZProps.RAWTEXT],
|
||||
VProps.RESOURCE_ID: entity_event[ZProps.RESOURCE_NAME]
|
||||
}
|
||||
|
||||
return graph_utils.create_vertex(
|
||||
|
@ -157,7 +157,11 @@ class ConsistencyEnforcer(object):
|
||||
DSProps.DATASOURCE_ACTION: DatasourceAction.UPDATE,
|
||||
DSProps.SAMPLE_DATE: str(utcnow()),
|
||||
DSProps.EVENT_TYPE: action,
|
||||
VProps.VITRAGE_ID: vertex[VProps.VITRAGE_ID]
|
||||
VProps.VITRAGE_ID: vertex[VProps.VITRAGE_ID],
|
||||
VProps.ID: vertex.get(VProps.ID, None),
|
||||
VProps.TYPE: vertex[VProps.TYPE],
|
||||
VProps.CATEGORY: vertex[VProps.CATEGORY],
|
||||
VProps.IS_REAL_VITRAGE_ID: True
|
||||
}
|
||||
self.evaluator_queue.put(event)
|
||||
|
||||
|
@ -15,8 +15,12 @@
|
||||
|
||||
from oslo_log import log
|
||||
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from vitrage.common.constants import GraphAction
|
||||
from vitrage.common.constants import VertexProperties as VProps
|
||||
from vitrage.common.exception import VitrageError
|
||||
from vitrage.datasources import OPENSTACK_CLUSTER
|
||||
from vitrage.datasources.transformer_base import TransformerBase
|
||||
from vitrage.entity_graph.mappings.datasource_info_mapper import \
|
||||
DatasourceInfoMapper
|
||||
@ -32,7 +36,8 @@ LOG = log.getLogger(__name__)
|
||||
|
||||
class Processor(processor.ProcessorBase):
|
||||
|
||||
def __init__(self, conf, initialization_status, e_graph=None):
|
||||
def __init__(self, conf, initialization_status, e_graph=None,
|
||||
uuid=False):
|
||||
super(Processor, self).__init__()
|
||||
self.conf = conf
|
||||
self.transformer_manager = TransformerManager(self.conf)
|
||||
@ -40,7 +45,7 @@ class Processor(processor.ProcessorBase):
|
||||
self._initialize_events_actions()
|
||||
self.initialization_status = initialization_status
|
||||
self.entity_graph = e_graph if e_graph is not None\
|
||||
else NXGraph("Entity Graph")
|
||||
else NXGraph("Entity Graph", uuid=uuid)
|
||||
self._notifier = GraphNotifier(conf)
|
||||
|
||||
def process_event(self, event):
|
||||
@ -74,6 +79,7 @@ class Processor(processor.ProcessorBase):
|
||||
"""
|
||||
|
||||
LOG.debug('Add entity to entity graph:\n%s', new_vertex)
|
||||
self._find_and_fix_graph_vertex(new_vertex, neighbors)
|
||||
self.entity_graph.add_vertex(new_vertex)
|
||||
self._connect_neighbors(neighbors, [], GraphAction.CREATE_ENTITY)
|
||||
|
||||
@ -92,6 +98,8 @@ class Processor(processor.ProcessorBase):
|
||||
|
||||
LOG.debug('Update entity in entity graph:\n%s', updated_vertex)
|
||||
|
||||
if not updated_vertex.get(VProps.IS_REAL_VITRAGE_ID, False):
|
||||
self._find_and_fix_graph_vertex(updated_vertex, neighbors)
|
||||
graph_vertex = self.entity_graph.get_vertex(updated_vertex.vertex_id)
|
||||
|
||||
if (not graph_vertex) or \
|
||||
@ -117,7 +125,8 @@ class Processor(processor.ProcessorBase):
|
||||
"""
|
||||
|
||||
LOG.debug('Delete entity from entity graph:\n%s', deleted_vertex)
|
||||
|
||||
if not deleted_vertex.get(VProps.IS_REAL_VITRAGE_ID, False):
|
||||
self._find_and_fix_graph_vertex(deleted_vertex, neighbors)
|
||||
graph_vertex = self.entity_graph.get_vertex(deleted_vertex.vertex_id)
|
||||
|
||||
if graph_vertex and (not PUtils.is_deleted(graph_vertex)) and \
|
||||
@ -141,21 +150,38 @@ class Processor(processor.ProcessorBase):
|
||||
def update_relationship(self, entity_vertex, neighbors):
|
||||
LOG.debug('Update relationship in entity graph:\n%s', neighbors)
|
||||
|
||||
if not entity_vertex:
|
||||
for neighbor in neighbors:
|
||||
self.entity_graph.update_edge(neighbor.edge)
|
||||
return
|
||||
|
||||
self._find_and_fix_graph_vertex(entity_vertex, [])
|
||||
self.entity_graph.update_vertex(entity_vertex)
|
||||
for neighbor in neighbors:
|
||||
# TODO(Alexey): maybe to check if the vertices exists
|
||||
if entity_vertex is not None:
|
||||
self.entity_graph.update_vertex(entity_vertex)
|
||||
self._find_and_fix_relationship(entity_vertex, neighbor)
|
||||
self.entity_graph.update_edge(neighbor.edge)
|
||||
|
||||
def delete_relationship(self, updated_vertex, neighbors):
|
||||
LOG.debug('Delete relationship from entity graph:\n%s', neighbors)
|
||||
|
||||
if not updated_vertex:
|
||||
for neighbor in neighbors:
|
||||
graph_edge = self.entity_graph.get_edge(
|
||||
neighbor.edge.source_id,
|
||||
neighbor.edge.target_id,
|
||||
neighbor.edge.label)
|
||||
if graph_edge:
|
||||
self.entity_graph.remove_edge(graph_edge)
|
||||
|
||||
return
|
||||
|
||||
self._find_and_fix_graph_vertex(updated_vertex, [])
|
||||
self.entity_graph.update_vertex(updated_vertex)
|
||||
for neighbor in neighbors:
|
||||
self._find_and_fix_relationship(updated_vertex, neighbor)
|
||||
graph_edge = self.entity_graph.get_edge(neighbor.edge.source_id,
|
||||
neighbor.edge.target_id,
|
||||
neighbor.edge.label)
|
||||
if updated_vertex is not None:
|
||||
self.entity_graph.update_vertex(updated_vertex)
|
||||
if graph_edge:
|
||||
PUtils.mark_deleted(self.entity_graph, graph_edge)
|
||||
|
||||
@ -168,7 +194,7 @@ class Processor(processor.ProcessorBase):
|
||||
:type vertex: Vertex
|
||||
|
||||
:param neighbors: The neighbors of the deleted vertex
|
||||
:type neighbors: List
|
||||
:type neighbors: List - It's just a mock in this method
|
||||
"""
|
||||
|
||||
LOG.debug('Remove deleted entity from entity graph:\n%s', vertex)
|
||||
@ -308,7 +334,12 @@ class Processor(processor.ProcessorBase):
|
||||
if action in [GraphAction.UPDATE_ENTITY,
|
||||
GraphAction.DELETE_ENTITY,
|
||||
GraphAction.CREATE_ENTITY]:
|
||||
graph_vertex = self.entity_graph.get_vertex(vertex.vertex_id)
|
||||
if vertex.get(VProps.IS_REAL_VITRAGE_ID, False):
|
||||
graph_vertex = self.entity_graph.get_vertex(
|
||||
vertex.vertex_id)
|
||||
else:
|
||||
graph_vertex = self._get_single_graph_vertex_by_props(
|
||||
vertex)
|
||||
elif action in [GraphAction.END_MESSAGE,
|
||||
GraphAction.REMOVE_DELETED_ENTITY,
|
||||
GraphAction.UPDATE_RELATIONSHIP,
|
||||
@ -329,3 +360,97 @@ class Processor(processor.ProcessorBase):
|
||||
return
|
||||
result = self.entity_graph.get_vertices(attr)
|
||||
event[TransformerBase.QUERY_RESULT] = result
|
||||
|
||||
def _find_and_fix_relationship(self, vertex, neighbor):
|
||||
prev_neighbor_id = neighbor.vertex[VProps.VITRAGE_ID]
|
||||
self._find_and_fix_graph_vertex(neighbor.vertex, [])
|
||||
if neighbor.edge.source_id == prev_neighbor_id:
|
||||
neighbor.edge.source_id = neighbor.vertex.vertex_id
|
||||
neighbor.edge.target_id = vertex.vertex_id
|
||||
else:
|
||||
neighbor.edge.target_id = neighbor.vertex.vertex_id
|
||||
neighbor.edge.source_id = vertex.vertex_id
|
||||
|
||||
def _find_and_fix_graph_vertex(self,
|
||||
vertex,
|
||||
neighbors=None,
|
||||
include_deleted=False):
|
||||
"""Search for vertex in graph, and update vertex id and vitrage ID
|
||||
|
||||
Search for vertex in graph, and update vertex id and vitrage ID
|
||||
Both in the Vertex itself, and in it's neighbors and edges
|
||||
|
||||
:param new_vertex: The vertex to update
|
||||
:type new_vertex: Vertex
|
||||
|
||||
:param neighbors: The neighbors of the vertex
|
||||
:type neighbors: list
|
||||
|
||||
:param include_deleted: If True, Include deleted entities in the search
|
||||
:type include_deleted: bool
|
||||
"""
|
||||
|
||||
previous_vitrage_id = vertex[VProps.VITRAGE_ID]
|
||||
|
||||
graph_vertex = self._get_single_graph_vertex_by_props(
|
||||
vertex, include_deleted)
|
||||
|
||||
if not graph_vertex or (PUtils.is_deleted(graph_vertex)
|
||||
and not include_deleted):
|
||||
|
||||
vitrage_id = uuidutils.generate_uuid()
|
||||
if vertex[VProps.TYPE] == OPENSTACK_CLUSTER:
|
||||
self.entity_graph.root_id = vitrage_id
|
||||
else:
|
||||
vitrage_id = graph_vertex[VProps.VITRAGE_ID]
|
||||
|
||||
vertex[VProps.VITRAGE_ID] = vitrage_id
|
||||
vertex.vertex_id = vitrage_id
|
||||
|
||||
if not neighbors:
|
||||
return
|
||||
|
||||
for neighbor_vertex, edge in neighbors:
|
||||
if not neighbor_vertex.get(VProps.IS_REAL_VITRAGE_ID, False):
|
||||
self._find_and_fix_graph_vertex(neighbor_vertex)
|
||||
if edge.target_id == previous_vitrage_id:
|
||||
edge.target_id = vitrage_id
|
||||
edge.source_id = neighbor_vertex.vertex_id
|
||||
else:
|
||||
edge.source_id = vitrage_id
|
||||
edge.target_id = neighbor_vertex.vertex_id
|
||||
|
||||
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
|
||||
|
@ -16,7 +16,12 @@ from dateutil import parser
|
||||
|
||||
from oslo_log import log
|
||||
|
||||
from pprint import pformat
|
||||
|
||||
import six
|
||||
|
||||
from vitrage.common.constants import EdgeProperties as EProps
|
||||
from vitrage.common.constants import EntityCategory
|
||||
from vitrage.common.constants import VertexProperties as VProps
|
||||
from vitrage.graph import Edge
|
||||
from vitrage.graph import Vertex
|
||||
@ -83,6 +88,21 @@ def get_vertex_types(vertex):
|
||||
return category, type_
|
||||
|
||||
|
||||
def get_defining_properties(vertex):
|
||||
defining_props = {VProps.TYPE: six.text_type(vertex[VProps.TYPE])}
|
||||
|
||||
if VProps.ID in vertex.properties:
|
||||
defining_props[VProps.ID] = vertex[VProps.ID]
|
||||
|
||||
# In case the entity is an Alarm
|
||||
if vertex[VProps.CATEGORY] == EntityCategory.ALARM:
|
||||
if VProps.RESOURCE_ID in vertex.properties:
|
||||
defining_props[VProps.RESOURCE_ID] = vertex[VProps.RESOURCE_ID]
|
||||
defining_props[VProps.NAME] = vertex[VProps.NAME]
|
||||
|
||||
return hash(pformat(defining_props))
|
||||
|
||||
|
||||
def can_update_vertex(graph_vertex, new_vertex):
|
||||
return (not graph_vertex) or (not new_vertex[VProps.IS_PLACEHOLDER])
|
||||
|
||||
|
@ -67,6 +67,9 @@ class EvaluatorEventTransformer(transformer_base.TransformerBase):
|
||||
VProps.IS_PLACEHOLDER: False,
|
||||
VProps.RESOURCE_ID: event.get(TFields.TARGET)
|
||||
}
|
||||
if VProps.IS_REAL_VITRAGE_ID in event:
|
||||
properties[VProps.IS_REAL_VITRAGE_ID] = \
|
||||
event.get(VProps.IS_REAL_VITRAGE_ID)
|
||||
if VProps.VITRAGE_STATE in event:
|
||||
properties[VProps.VITRAGE_STATE] = \
|
||||
event.get(VProps.VITRAGE_STATE)
|
||||
@ -129,7 +132,8 @@ class EvaluatorEventTransformer(transformer_base.TransformerBase):
|
||||
neighbor_props = {
|
||||
VProps.IS_PLACEHOLDER: True,
|
||||
VProps.UPDATE_TIMESTAMP: timestamp,
|
||||
VProps.SAMPLE_TIMESTAMP: event[VProps.SAMPLE_TIMESTAMP]
|
||||
VProps.SAMPLE_TIMESTAMP: event[VProps.SAMPLE_TIMESTAMP],
|
||||
VProps.IS_REAL_VITRAGE_ID: True
|
||||
}
|
||||
neighbor = Vertex(event[TFields.TARGET], neighbor_props)
|
||||
return [Neighbor(neighbor, relation_edge)]
|
||||
|
@ -53,7 +53,8 @@ class SetState(base.Recipe):
|
||||
|
||||
update_vertex_params = {
|
||||
VProps.VITRAGE_ID: target_id,
|
||||
VProps.VITRAGE_STATE: vitrage_state
|
||||
VProps.VITRAGE_STATE: vitrage_state,
|
||||
VProps.IS_REAL_VITRAGE_ID: True
|
||||
}
|
||||
update_vertex_step = ActionStepWrapper(UPDATE_VERTEX,
|
||||
update_vertex_params)
|
||||
|
@ -13,10 +13,11 @@
|
||||
# under the License.
|
||||
from collections import defaultdict
|
||||
from collections import namedtuple
|
||||
from hashlib import md5
|
||||
|
||||
from oslo_log import log
|
||||
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from vitrage.evaluator.base import Template
|
||||
from vitrage.evaluator.template_data import RELATIONSHIP
|
||||
from vitrage.evaluator.template_data import TemplateData
|
||||
@ -85,7 +86,7 @@ class ScenarioRepository(object):
|
||||
if not result.is_valid_config:
|
||||
LOG.info('Unable to load template: %s' % result.comment)
|
||||
|
||||
template_uuid = md5(str(template_def).encode()).hexdigest()
|
||||
template_uuid = uuidutils.generate_uuid()
|
||||
self.templates[str(template_uuid)] = Template(template_uuid,
|
||||
template_def,
|
||||
current_time,
|
||||
|
@ -36,7 +36,8 @@ class Direction(object):
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class Graph(object):
|
||||
def __init__(self, name, graph_type, vertices=None, edges=None):
|
||||
def __init__(self, name, graph_type, vertices=None, edges=None,
|
||||
uuid=False):
|
||||
"""Create a Graph instance
|
||||
|
||||
:type name: str
|
||||
@ -48,6 +49,7 @@ class Graph(object):
|
||||
self.name = name
|
||||
self.graph_type = graph_type
|
||||
self.root_id = None
|
||||
self.uuid = uuid
|
||||
self.notifier = Notifier()
|
||||
|
||||
def subscribe(self, function):
|
||||
@ -338,6 +340,20 @@ class Graph(object):
|
||||
"""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_vertices_by_key(self,
|
||||
key_values_hash):
|
||||
"""Get vertices list according to their hash key
|
||||
|
||||
The hash key is derived from their properties :
|
||||
See processor_utils - get_defining_properties
|
||||
|
||||
|
||||
:param key_values_hash: hash key
|
||||
:type key_values_hash str
|
||||
"""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def neighbors(self, v_id, vertex_attr_filter=None,
|
||||
edge_attr_filter=None, direction=Direction.BOTH):
|
||||
|
@ -11,6 +11,7 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from collections import defaultdict
|
||||
|
||||
import copy
|
||||
import json
|
||||
@ -21,6 +22,7 @@ from networkx.readwrite import json_graph
|
||||
from oslo_log import log as logging
|
||||
|
||||
from vitrage.common.constants import VertexProperties as VProps
|
||||
from vitrage.entity_graph.processor import processor_utils as PUtils
|
||||
from vitrage.graph.algo_driver.networkx_algorithm import NXAlgorithm
|
||||
from vitrage.graph.driver.elements import Edge
|
||||
from vitrage.graph.driver.elements import Vertex
|
||||
@ -50,9 +52,12 @@ class NXGraph(Graph):
|
||||
name='networkx_graph',
|
||||
root_id=None,
|
||||
vertices=None,
|
||||
edges=None):
|
||||
super(NXGraph, self).__init__(name, NXGraph.GRAPH_TYPE)
|
||||
edges=None,
|
||||
uuid=False):
|
||||
super(NXGraph, self).__init__(name, NXGraph.GRAPH_TYPE, uuid=uuid)
|
||||
self._g = nx.MultiDiGraph()
|
||||
if uuid:
|
||||
self.key_to_vertex_ids = defaultdict(list)
|
||||
self.root_id = root_id
|
||||
self.add_vertices(vertices)
|
||||
self.add_edges(edges)
|
||||
@ -81,6 +86,13 @@ class NXGraph(Graph):
|
||||
def _add_vertex(self, v):
|
||||
properties_copy = copy.copy(v.properties)
|
||||
self._g.add_node(n=v.vertex_id, attr_dict=properties_copy)
|
||||
if self.uuid:
|
||||
self._update_keys_map(v)
|
||||
|
||||
def _update_keys_map(self, v):
|
||||
key_hash = PUtils.get_defining_properties(v)
|
||||
if v.vertex_id not in self.key_to_vertex_ids[key_hash]:
|
||||
self.key_to_vertex_ids[key_hash].append(v.vertex_id)
|
||||
|
||||
@Notifier.update_notify
|
||||
def add_edge(self, e):
|
||||
@ -197,6 +209,16 @@ class NXGraph(Graph):
|
||||
|
||||
:type v: Vertex
|
||||
"""
|
||||
if self.uuid:
|
||||
vertex = self.get_vertex(v.vertex_id)
|
||||
if vertex:
|
||||
key_hash = PUtils.get_defining_properties(vertex)
|
||||
if key_hash in self.key_to_vertex_ids and\
|
||||
v.vertex_id in self.key_to_vertex_ids[key_hash]:
|
||||
self.key_to_vertex_ids[key_hash].remove(v.vertex_id)
|
||||
if len(self.key_to_vertex_ids[key_hash]) == 0:
|
||||
del self.key_to_vertex_ids[key_hash]
|
||||
|
||||
self._g.remove_node(n=v.vertex_id)
|
||||
|
||||
def remove_edge(self, e):
|
||||
@ -207,7 +229,7 @@ class NXGraph(Graph):
|
||||
self._g.remove_edge(u=e.source_id, v=e.target_id, key=e.label)
|
||||
|
||||
def get_vertices(self,
|
||||
vertex_attr_filter=None,
|
||||
vertex_attr_filter=None, # Dictionary of key value
|
||||
query_dict=None):
|
||||
def check_vertex(vertex_data):
|
||||
return check_filter(vertex_data[1], vertex_attr_filter)
|
||||
@ -226,6 +248,15 @@ class NXGraph(Graph):
|
||||
else:
|
||||
return []
|
||||
|
||||
def get_vertices_by_key(self, key_values_hash):
|
||||
|
||||
if key_values_hash in self.key_to_vertex_ids:
|
||||
vertices = []
|
||||
for vertex_id in self.key_to_vertex_ids[key_values_hash]:
|
||||
vertices.append(self.get_vertex(vertex_id))
|
||||
return vertices
|
||||
return []
|
||||
|
||||
def neighbors(self, v_id, vertex_attr_filter=None, edge_attr_filter=None,
|
||||
direction=Direction.BOTH):
|
||||
|
||||
|
@ -23,7 +23,8 @@ from vitrage.common.constants import VertexProperties as VProps
|
||||
from vitrage.datasources import NOVA_HOST_DATASOURCE
|
||||
from vitrage.datasources import NOVA_INSTANCE_DATASOURCE
|
||||
from vitrage.datasources import NOVA_ZONE_DATASOURCE
|
||||
from vitrage.datasources import OPENSTACK_CLUSTER
|
||||
from vitrage.datasources.transformer_base \
|
||||
import create_cluster_placeholder_vertex
|
||||
from vitrage.graph.driver.networkx_graph import NXGraph
|
||||
import vitrage.graph.utils as graph_utils
|
||||
from vitrage.tests.unit.entity_graph.base import TestEntityGraphUnitBase
|
||||
@ -143,7 +144,7 @@ class TestApis(TestEntityGraphUnitBase):
|
||||
graph_type='graph',
|
||||
depth=10,
|
||||
query=None,
|
||||
root='RESOURCE:openstack.cluster:OpenStack Cluster',
|
||||
root=None,
|
||||
all_tenants=False)
|
||||
graph_topology = json.loads(graph_topology)
|
||||
|
||||
@ -165,7 +166,7 @@ class TestApis(TestEntityGraphUnitBase):
|
||||
graph_type='graph',
|
||||
depth=10,
|
||||
query=None,
|
||||
root='RESOURCE:openstack.cluster:OpenStack Cluster',
|
||||
root=None,
|
||||
all_tenants=False)
|
||||
graph_topology = json.loads(graph_topology)
|
||||
|
||||
@ -187,7 +188,7 @@ class TestApis(TestEntityGraphUnitBase):
|
||||
graph_type='graph',
|
||||
depth=10,
|
||||
query=None,
|
||||
root='RESOURCE:openstack.cluster:OpenStack Cluster',
|
||||
root=None,
|
||||
all_tenants=True)
|
||||
graph_topology = json.loads(graph_topology)
|
||||
|
||||
@ -389,12 +390,10 @@ class TestApis(TestEntityGraphUnitBase):
|
||||
self.assertEqual(resource[VProps.PROJECT_ID], project_id)
|
||||
|
||||
def _create_graph(self):
|
||||
graph = NXGraph('Multi tenancy graph')
|
||||
graph = NXGraph('Multi tenancy graph', uuid=True)
|
||||
|
||||
# create vertices
|
||||
cluster_vertex = self._create_resource(
|
||||
'RESOURCE:openstack.cluster:OpenStack Cluster',
|
||||
OPENSTACK_CLUSTER)
|
||||
cluster_vertex = create_cluster_placeholder_vertex()
|
||||
zone_vertex = self._create_resource('zone_1',
|
||||
NOVA_ZONE_DATASOURCE)
|
||||
host_vertex = self._create_resource('host_1',
|
||||
@ -411,18 +410,38 @@ class TestApis(TestEntityGraphUnitBase):
|
||||
instance_4_vertex = self._create_resource('instance_4',
|
||||
NOVA_INSTANCE_DATASOURCE,
|
||||
project_id='project_2')
|
||||
alarm_on_host_vertex = self._create_alarm('alarm_on_host',
|
||||
'alarm_on_host')
|
||||
alarm_on_instance_1_vertex = self._create_alarm('alarm_on_instance_1',
|
||||
'deduced_alarm',
|
||||
project_id='project_1')
|
||||
alarm_on_instance_2_vertex = self._create_alarm('alarm_on_instance_2',
|
||||
'deduced_alarm')
|
||||
alarm_on_instance_3_vertex = self._create_alarm('alarm_on_instance_3',
|
||||
'deduced_alarm',
|
||||
project_id='project_2')
|
||||
alarm_on_instance_4_vertex = self._create_alarm('alarm_on_instance_4',
|
||||
'deduced_alarm')
|
||||
alarm_on_host_vertex = self._create_alarm(
|
||||
'alarm_on_host',
|
||||
'alarm_on_host',
|
||||
metadata={'type': 'nova.host',
|
||||
'name': 'host_1',
|
||||
'resource_id': 'host_1'})
|
||||
alarm_on_instance_1_vertex = self._create_alarm(
|
||||
'alarm_on_instance_1',
|
||||
'deduced_alarm',
|
||||
project_id='project_1',
|
||||
metadata={'type': 'nova.instance',
|
||||
'name': 'instance_1',
|
||||
'resource_id': 'sdg7849ythksjdg'})
|
||||
alarm_on_instance_2_vertex = self._create_alarm(
|
||||
'alarm_on_instance_2',
|
||||
'deduced_alarm',
|
||||
metadata={'type': 'nova.instance',
|
||||
'name': 'instance_2',
|
||||
'resource_id': 'nbfhsdugf'})
|
||||
alarm_on_instance_3_vertex = self._create_alarm(
|
||||
'alarm_on_instance_3',
|
||||
'deduced_alarm',
|
||||
project_id='project_2',
|
||||
metadata={'type': 'nova.instance',
|
||||
'name': 'instance_3',
|
||||
'resource_id': 'nbffhsdasdugf'})
|
||||
alarm_on_instance_4_vertex = self._create_alarm(
|
||||
'alarm_on_instance_4',
|
||||
'deduced_alarm',
|
||||
metadata={'type': 'nova.instance',
|
||||
'name': 'instance_4',
|
||||
'resource_id': 'ngsuy76hgd87f'})
|
||||
|
||||
# create links
|
||||
edges = list()
|
||||
|
@ -22,11 +22,13 @@ from vitrage.tests.unit.entity_graph.base import TestEntityGraphUnitBase
|
||||
|
||||
class TestFunctionalBase(TestEntityGraphUnitBase):
|
||||
|
||||
def _create_processor_with_graph(self, conf, processor=None):
|
||||
def _create_processor_with_graph(self, conf, processor=None,
|
||||
uuid=False):
|
||||
events = self._create_mock_events()
|
||||
|
||||
if not processor:
|
||||
processor = proc.Processor(conf, InitializationStatus())
|
||||
processor = proc.Processor(conf, InitializationStatus(),
|
||||
uuid=uuid)
|
||||
|
||||
for event in events:
|
||||
processor.process_event(event)
|
||||
|
@ -53,7 +53,7 @@ class TestAodhAlarms(TestDataSourcesBase):
|
||||
|
||||
def test_aodh_alarms_validity(self):
|
||||
# Setup
|
||||
processor = self._create_processor_with_graph(self.conf)
|
||||
processor = self._create_processor_with_graph(self.conf, uuid=True)
|
||||
self.assertEqual(self._num_total_expected_vertices(),
|
||||
len(processor.entity_graph))
|
||||
|
||||
|
@ -52,7 +52,7 @@ class TestCinderVolume(TestDataSourcesBase):
|
||||
|
||||
def test_cinder_volume_validity(self):
|
||||
# Setup
|
||||
processor = self._create_processor_with_graph(self.conf)
|
||||
processor = self._create_processor_with_graph(self.conf, uuid=True)
|
||||
self.assertEqual(self._num_total_expected_vertices(),
|
||||
len(processor.entity_graph))
|
||||
|
||||
|
@ -52,7 +52,7 @@ class TestHeatStack(TestDataSourcesBase):
|
||||
|
||||
def test_heat_stack_validity(self):
|
||||
# Setup
|
||||
processor = self._create_processor_with_graph(self.conf)
|
||||
processor = self._create_processor_with_graph(self.conf, uuid=True)
|
||||
self.assertEqual(self._num_total_expected_vertices(),
|
||||
len(processor.entity_graph))
|
||||
|
||||
|
@ -51,7 +51,7 @@ class TestNagios(TestDataSourcesBase):
|
||||
|
||||
def test_nagios_validity(self):
|
||||
# Setup
|
||||
processor = self._create_processor_with_graph(self.conf)
|
||||
processor = self._create_processor_with_graph(self.conf, uuid=True)
|
||||
self.assertEqual(self._num_total_expected_vertices(),
|
||||
len(processor.entity_graph))
|
||||
|
||||
|
@ -30,7 +30,7 @@ class TestNovaDatasources(TestDataSourcesBase):
|
||||
cls.load_datasources(cls.conf)
|
||||
|
||||
def test_nova_datasources(self):
|
||||
processor = self._create_processor_with_graph(self.conf)
|
||||
processor = self._create_processor_with_graph(self.conf, uuid=True)
|
||||
|
||||
self.assertEqual(self._num_total_expected_vertices(),
|
||||
processor.entity_graph.num_vertices())
|
||||
|
@ -55,7 +55,7 @@ class TestStaticPhysical(TestDataSourcesBase):
|
||||
|
||||
def test_static_physical_validity(self):
|
||||
# Setup
|
||||
processor = self._create_processor_with_graph(self.conf)
|
||||
processor = self._create_processor_with_graph(self.conf, uuid=True)
|
||||
transformers = processor.transformer_manager.transformers
|
||||
transformers[SWITCH] = transformers[STATIC_PHYSICAL_DATASOURCE]
|
||||
self.assertEqual(self._num_total_expected_vertices(),
|
||||
|
@ -74,7 +74,8 @@ class TestConsistencyFunctional(TestFunctionalBase):
|
||||
cls.conf.register_opts(cls.DATASOURCES_OPTS, group='datasources')
|
||||
cls.load_datasources(cls.conf)
|
||||
|
||||
cls.processor = Processor(cls.conf, cls.initialization_status)
|
||||
cls.processor = Processor(cls.conf, cls.initialization_status,
|
||||
uuid=True)
|
||||
cls.event_queue = queue.Queue()
|
||||
scenario_repo = ScenarioRepository(cls.conf)
|
||||
cls.evaluator = ScenarioEvaluator(cls.conf,
|
||||
@ -93,7 +94,8 @@ class TestConsistencyFunctional(TestFunctionalBase):
|
||||
# Setup
|
||||
num_of_host_alarms = self.NUM_HOSTS - 2
|
||||
num_instances_per_host = 4
|
||||
self._create_processor_with_graph(self.conf, processor=self.processor)
|
||||
self._create_processor_with_graph(self.conf, processor=self.processor,
|
||||
uuid=True)
|
||||
self._add_alarms()
|
||||
self._set_end_messages()
|
||||
self.assertEqual(self._num_total_expected_vertices() +
|
||||
@ -167,7 +169,8 @@ class TestConsistencyFunctional(TestFunctionalBase):
|
||||
self.assertEqual(6, len(deleted_instance_vertices))
|
||||
|
||||
def _periodic_process_setup_stage(self, consistency_interval):
|
||||
self._create_processor_with_graph(self.conf, processor=self.processor)
|
||||
self._create_processor_with_graph(self.conf, processor=self.processor,
|
||||
uuid=True)
|
||||
current_time = utcnow()
|
||||
|
||||
# set all vertices to be have timestamp that consistency won't get
|
||||
|
@ -34,7 +34,7 @@ class TestProcessorFunctional(TestFunctionalBase):
|
||||
cls.load_datasources(cls.conf)
|
||||
|
||||
def test_create_entity_graph(self):
|
||||
processor = self._create_processor_with_graph(self.conf)
|
||||
processor = self._create_processor_with_graph(self.conf, uuid=True)
|
||||
|
||||
self.assertEqual(self._num_total_expected_vertices(),
|
||||
processor.entity_graph.num_vertices())
|
||||
|
@ -17,7 +17,6 @@ from oslo_config import cfg
|
||||
from vitrage.common.constants import DatasourceAction as DSAction
|
||||
from vitrage.common.constants import GraphAction
|
||||
from vitrage.common.constants import VertexProperties as VProps
|
||||
from vitrage.datasources.nova.instance.transformer import InstanceTransformer
|
||||
from vitrage.entity_graph.initialization_status import InitializationStatus
|
||||
from vitrage.entity_graph.mappings.operational_resource_state import \
|
||||
OperationalResourceState
|
||||
@ -38,7 +37,8 @@ class TestDatasourceInfoMapperFunctional(TestFunctionalBase):
|
||||
|
||||
def test_state_on_update(self):
|
||||
# setup
|
||||
processor = proc.Processor(self.conf, InitializationStatus())
|
||||
processor = proc.Processor(self.conf, InitializationStatus(),
|
||||
uuid=True)
|
||||
event = self._create_event(spec_type='INSTANCE_SPEC',
|
||||
datasource_action=DSAction.INIT_SNAPSHOT)
|
||||
|
||||
@ -46,9 +46,9 @@ class TestDatasourceInfoMapperFunctional(TestFunctionalBase):
|
||||
processor.process_event(event)
|
||||
|
||||
# test assertions
|
||||
instance_transformer = InstanceTransformer({}, self.conf)
|
||||
vitrage_id = instance_transformer._create_entity_key(event)
|
||||
vertex = processor.entity_graph.get_vertex(vitrage_id)
|
||||
entity = processor.transformer_manager.transform(event)
|
||||
processor._find_and_fix_graph_vertex(entity.vertex, [])
|
||||
vertex = processor.entity_graph.get_vertex(entity.vertex.vertex_id)
|
||||
self.assertEqual('ACTIVE', vertex[VProps.AGGREGATED_STATE])
|
||||
self.assertEqual(OperationalResourceState.OK,
|
||||
vertex[VProps.OPERATIONAL_STATE])
|
||||
|
@ -49,7 +49,7 @@ class TestActionExecutor(TestFunctionalBase):
|
||||
def test_execute_update_vertex(self):
|
||||
|
||||
# Test Setup
|
||||
processor = self._create_processor_with_graph(self.conf)
|
||||
processor = self._create_processor_with_graph(self.conf, uuid=True)
|
||||
|
||||
vertex_attrs = {VProps.TYPE: NOVA_HOST_DATASOURCE}
|
||||
host_vertices = processor.entity_graph.get_vertices(
|
||||
@ -97,7 +97,7 @@ class TestActionExecutor(TestFunctionalBase):
|
||||
def test_execute_add_edge(self):
|
||||
|
||||
# Test Setup
|
||||
processor = self._create_processor_with_graph(self.conf)
|
||||
processor = self._create_processor_with_graph(self.conf, uuid=True)
|
||||
|
||||
vertex_attrs = {VProps.TYPE: NOVA_HOST_DATASOURCE}
|
||||
host_vertices = processor.entity_graph.get_vertices(
|
||||
@ -147,7 +147,7 @@ class TestActionExecutor(TestFunctionalBase):
|
||||
def test_execute_add_vertex(self):
|
||||
|
||||
# Test Setup
|
||||
processor = self._create_processor_with_graph(self.conf)
|
||||
processor = self._create_processor_with_graph(self.conf, uuid=True)
|
||||
|
||||
vertex_attrs = {VProps.TYPE: NOVA_HOST_DATASOURCE}
|
||||
host_vertices = processor.entity_graph.get_vertices(
|
||||
@ -159,7 +159,9 @@ class TestActionExecutor(TestFunctionalBase):
|
||||
props = {
|
||||
TFields.ALARM_NAME: 'VM_CPU_SUBOPTIMAL_PERFORMANCE',
|
||||
TFields.SEVERITY: 'CRITICAL',
|
||||
VProps.STATE: AlarmProps.ACTIVE_STATE
|
||||
VProps.STATE: AlarmProps.ACTIVE_STATE,
|
||||
VProps.RESOURCE_ID: host[VProps.ID],
|
||||
VProps.VITRAGE_ID: 'DUMMY_ID'
|
||||
}
|
||||
|
||||
# Raise alarm action adds new vertex with type vitrage to the graph
|
||||
@ -171,8 +173,6 @@ class TestActionExecutor(TestFunctionalBase):
|
||||
event_queue = queue.Queue()
|
||||
action_executor = ActionExecutor(event_queue)
|
||||
|
||||
expected_alarm_id = 'ALARM:vitrage:%s:%s' % (props[TFields.ALARM_NAME],
|
||||
host.vertex_id)
|
||||
# Test Action
|
||||
action_executor.execute(action_spec, ActionMode.DO)
|
||||
processor.process_event(event_queue.get())
|
||||
@ -184,12 +184,7 @@ class TestActionExecutor(TestFunctionalBase):
|
||||
self.assertEqual(len(before_alarms) + 1, len(after_alarms))
|
||||
self.assert_is_not_empty(after_alarms)
|
||||
|
||||
alarms = [alarm for alarm in after_alarms
|
||||
if alarm.vertex_id == expected_alarm_id]
|
||||
|
||||
# Expected exactly one alarm with expected id
|
||||
self.assertEqual(1, len(alarms))
|
||||
alarm = alarms[0]
|
||||
alarm = after_alarms[0]
|
||||
|
||||
self.assertEqual(alarm.properties[VProps.CATEGORY],
|
||||
EntityCategory.ALARM)
|
||||
@ -205,7 +200,7 @@ class TestActionExecutor(TestFunctionalBase):
|
||||
def test_execute_add_and_remove_vertex(self):
|
||||
|
||||
# Test Setup
|
||||
processor = self._create_processor_with_graph(self.conf)
|
||||
processor = self._create_processor_with_graph(self.conf, uuid=True)
|
||||
|
||||
vertex_attrs = {VProps.TYPE: NOVA_HOST_DATASOURCE}
|
||||
host_vertices = processor.entity_graph.get_vertices(
|
||||
@ -217,7 +212,8 @@ class TestActionExecutor(TestFunctionalBase):
|
||||
props = {
|
||||
TFields.ALARM_NAME: 'VM_CPU_SUBOPTIMAL_PERFORMANCE',
|
||||
TFields.SEVERITY: 'CRITICAL',
|
||||
VProps.STATE: AlarmProps.ACTIVE_STATE
|
||||
VProps.STATE: AlarmProps.ACTIVE_STATE,
|
||||
VProps.RESOURCE_ID: host[VProps.ID]
|
||||
}
|
||||
action_spec = ActionSpecs(ActionType.RAISE_ALARM, targets, props)
|
||||
|
||||
@ -271,4 +267,6 @@ class TestActionExecutor(TestFunctionalBase):
|
||||
'type': 'add_vertex',
|
||||
'vitrage_entity_type': 'vitrage',
|
||||
'severity': 'CRITICAL',
|
||||
'vitrage_id': 'mock_vitrage_id',
|
||||
'category': 'RESOURCE',
|
||||
'sample_timestamp': '2016-03-17 11:33:32.443002+00:00'}
|
||||
|
@ -40,6 +40,7 @@ from vitrage.utils.datetime import utcnow
|
||||
_TARGET_HOST = 'host-2'
|
||||
_TARGET_ZONE = 'zone-1'
|
||||
_NAGIOS_TEST_INFO = {'resource_name': _TARGET_HOST,
|
||||
'resource_id': _TARGET_HOST,
|
||||
DSProps.DATASOURCE_ACTION: DatasourceAction.SNAPSHOT}
|
||||
|
||||
|
||||
@ -70,6 +71,7 @@ class TestScenarioEvaluator(TestFunctionalBase):
|
||||
event_queue, processor, evaluator = self._init_system()
|
||||
|
||||
host_v = self._get_entity_from_graph(NOVA_HOST_DATASOURCE,
|
||||
_TARGET_HOST,
|
||||
_TARGET_HOST,
|
||||
processor.entity_graph)
|
||||
self.assertEqual('AVAILABLE', host_v[VProps.AGGREGATED_STATE],
|
||||
@ -98,6 +100,7 @@ class TestScenarioEvaluator(TestFunctionalBase):
|
||||
event_queue, processor, evaluator = self._init_system()
|
||||
|
||||
host_v = self._get_entity_from_graph(NOVA_HOST_DATASOURCE,
|
||||
_TARGET_HOST,
|
||||
_TARGET_HOST,
|
||||
processor.entity_graph)
|
||||
self.assertEqual('AVAILABLE', host_v[VProps.AGGREGATED_STATE],
|
||||
@ -144,6 +147,7 @@ class TestScenarioEvaluator(TestFunctionalBase):
|
||||
event_queue, processor, evaluator = self._init_system()
|
||||
|
||||
host_v = self._get_entity_from_graph(NOVA_HOST_DATASOURCE,
|
||||
_TARGET_HOST,
|
||||
_TARGET_HOST,
|
||||
processor.entity_graph)
|
||||
self.assertEqual('AVAILABLE', host_v[VProps.AGGREGATED_STATE],
|
||||
@ -183,6 +187,7 @@ class TestScenarioEvaluator(TestFunctionalBase):
|
||||
event_queue, processor, evaluator = self._init_system()
|
||||
|
||||
host_v = self._get_entity_from_graph(NOVA_HOST_DATASOURCE,
|
||||
_TARGET_HOST,
|
||||
_TARGET_HOST,
|
||||
processor.entity_graph)
|
||||
self.assertEqual('AVAILABLE', host_v[VProps.AGGREGATED_STATE],
|
||||
@ -478,21 +483,31 @@ class TestScenarioEvaluator(TestFunctionalBase):
|
||||
|
||||
# test asserts
|
||||
self.assertEqual(num_orig_vertices + num_added_vertices +
|
||||
num_deduced_vertices + num_nagios_alarm_vertices,
|
||||
num_deduced_vertices + num_nagios_alarm_vertices +
|
||||
# This is due to keeping alarm history :
|
||||
# new alarm doesn't update same deleted alarm.
|
||||
# Instead, it keeps the old one and creates a new one
|
||||
1,
|
||||
entity_graph.num_vertices())
|
||||
self.assertEqual(num_orig_edges + num_added_edges + num_deduced_edges +
|
||||
num_nagios_alarm_edges, entity_graph.num_edges())
|
||||
num_nagios_alarm_edges + 1, entity_graph.num_edges())
|
||||
|
||||
query = {VProps.CATEGORY: EntityCategory.ALARM, VProps.TYPE: 'vitrage'}
|
||||
port_neighbors = entity_graph.neighbors(port_vertex.vertex_id,
|
||||
vertex_attr_filter=query)
|
||||
self.assertEqual(1, len(port_neighbors))
|
||||
self.assertEqual(port_neighbors[0][VProps.CATEGORY],
|
||||
EntityCategory.ALARM)
|
||||
self.assertEqual(port_neighbors[0][VProps.TYPE], 'vitrage')
|
||||
self.assertEqual(port_neighbors[0][VProps.NAME],
|
||||
'simple_port_deduced_alarm')
|
||||
self.assertEqual(port_neighbors[0][VProps.IS_DELETED], False)
|
||||
query = {VProps.CATEGORY: EntityCategory.ALARM, VProps.TYPE: 'vitrage',
|
||||
VProps.IS_DELETED: True}
|
||||
is_deleted = True
|
||||
for counter in range(0, 1):
|
||||
port_neighbors = entity_graph.neighbors(port_vertex.vertex_id,
|
||||
vertex_attr_filter=query)
|
||||
self.assertEqual(1, len(port_neighbors))
|
||||
self.assertEqual(port_neighbors[0][VProps.CATEGORY],
|
||||
EntityCategory.ALARM)
|
||||
self.assertEqual(port_neighbors[0][VProps.TYPE], 'vitrage')
|
||||
self.assertEqual(port_neighbors[0][VProps.NAME],
|
||||
'simple_port_deduced_alarm')
|
||||
self.assertEqual(port_neighbors[0][VProps.IS_DELETED], is_deleted)
|
||||
query = {VProps.CATEGORY: EntityCategory.ALARM,
|
||||
VProps.TYPE: 'vitrage', VProps.IS_DELETED: False}
|
||||
is_deleted = False
|
||||
|
||||
query = {VProps.CATEGORY: EntityCategory.ALARM, VProps.TYPE: 'nagios'}
|
||||
port_neighbors = entity_graph.neighbors(port_vertex.vertex_id,
|
||||
@ -517,21 +532,35 @@ class TestScenarioEvaluator(TestFunctionalBase):
|
||||
|
||||
# test asserts
|
||||
self.assertEqual(num_orig_vertices + num_added_vertices +
|
||||
num_deduced_vertices + num_nagios_alarm_vertices,
|
||||
num_deduced_vertices + num_nagios_alarm_vertices +
|
||||
# This is due to keeping alarm history :
|
||||
# new alarm doesn't update same deleted alarm.
|
||||
# Instead, it keeps the old one and creates a new one
|
||||
1,
|
||||
entity_graph.num_vertices())
|
||||
self.assertEqual(num_orig_edges + num_added_edges + num_deduced_edges +
|
||||
num_nagios_alarm_edges, entity_graph.num_edges())
|
||||
num_nagios_alarm_edges + 1, entity_graph.num_edges())
|
||||
|
||||
query = {VProps.CATEGORY: EntityCategory.ALARM, VProps.TYPE: 'vitrage'}
|
||||
port_neighbors = entity_graph.neighbors(port_vertex.vertex_id,
|
||||
vertex_attr_filter=query)
|
||||
self.assertEqual(1, len(port_neighbors))
|
||||
self.assertEqual(port_neighbors[0][VProps.CATEGORY],
|
||||
EntityCategory.ALARM)
|
||||
self.assertEqual(port_neighbors[0][VProps.TYPE], 'vitrage')
|
||||
self.assertEqual(port_neighbors[0][VProps.NAME],
|
||||
'simple_port_deduced_alarm')
|
||||
self.assertEqual(port_neighbors[0][VProps.IS_DELETED], True)
|
||||
query = {VProps.CATEGORY: EntityCategory.ALARM, VProps.TYPE: 'vitrage',
|
||||
VProps.IS_DELETED: True}
|
||||
is_deleted = True
|
||||
for counter in range(0, 1):
|
||||
port_neighbors = entity_graph.neighbors(port_vertex.vertex_id,
|
||||
vertex_attr_filter=query)
|
||||
self.assertEqual(2, len(port_neighbors))
|
||||
for in_counter in range(0, 1):
|
||||
self.assertEqual(port_neighbors[in_counter][VProps.CATEGORY],
|
||||
EntityCategory.ALARM)
|
||||
self.assertEqual(port_neighbors[in_counter][VProps.TYPE],
|
||||
'vitrage')
|
||||
self.assertEqual(port_neighbors[in_counter][VProps.NAME],
|
||||
'simple_port_deduced_alarm')
|
||||
self.assertEqual(
|
||||
port_neighbors[in_counter][VProps.IS_DELETED], is_deleted)
|
||||
|
||||
query = {VProps.CATEGORY: EntityCategory.ALARM,
|
||||
VProps.TYPE: 'vitrage', VProps.IS_DELETED: False}
|
||||
is_deleted = False
|
||||
|
||||
query = {VProps.CATEGORY: EntityCategory.ALARM, VProps.TYPE: 'nagios'}
|
||||
port_neighbors = entity_graph.neighbors(port_vertex.vertex_id,
|
||||
@ -551,21 +580,37 @@ class TestScenarioEvaluator(TestFunctionalBase):
|
||||
|
||||
# test asserts
|
||||
self.assertEqual(num_orig_vertices + num_added_vertices +
|
||||
num_deduced_vertices + num_nagios_alarm_vertices,
|
||||
num_deduced_vertices + num_nagios_alarm_vertices +
|
||||
# This is due to keeping alarm history :
|
||||
# new alarm doesn't update same deleted alarm.
|
||||
# Instead, it keeps the old one and creates a new one
|
||||
# Since this is the second test, there are already two
|
||||
# alarms of this type
|
||||
2,
|
||||
entity_graph.num_vertices())
|
||||
self.assertEqual(num_orig_edges + num_added_edges + num_deduced_edges +
|
||||
num_nagios_alarm_edges, entity_graph.num_edges())
|
||||
num_nagios_alarm_edges + 2, entity_graph.num_edges())
|
||||
|
||||
query = {VProps.CATEGORY: EntityCategory.ALARM, VProps.TYPE: 'vitrage'}
|
||||
port_neighbors = entity_graph.neighbors(port_vertex.vertex_id,
|
||||
vertex_attr_filter=query)
|
||||
self.assertEqual(1, len(port_neighbors))
|
||||
self.assertEqual(port_neighbors[0][VProps.CATEGORY],
|
||||
EntityCategory.ALARM)
|
||||
self.assertEqual(port_neighbors[0][VProps.TYPE], 'vitrage')
|
||||
self.assertEqual(port_neighbors[0][VProps.NAME],
|
||||
'simple_port_deduced_alarm')
|
||||
self.assertEqual(port_neighbors[0][VProps.IS_DELETED], False)
|
||||
query = {VProps.CATEGORY: EntityCategory.ALARM,
|
||||
VProps.TYPE: 'vitrage', VProps.IS_DELETED: True}
|
||||
is_deleted = True
|
||||
for counter in range(0, 1):
|
||||
port_neighbors = entity_graph.neighbors(port_vertex.vertex_id,
|
||||
vertex_attr_filter=query)
|
||||
self.assertEqual(2, len(port_neighbors))
|
||||
for in_counter in range(0, 1):
|
||||
self.assertEqual(port_neighbors[in_counter][VProps.CATEGORY],
|
||||
EntityCategory.ALARM)
|
||||
self.assertEqual(port_neighbors[in_counter][VProps.TYPE],
|
||||
'vitrage')
|
||||
self.assertEqual(port_neighbors[in_counter][VProps.NAME],
|
||||
'simple_port_deduced_alarm')
|
||||
self.assertEqual(
|
||||
port_neighbors[in_counter][VProps.IS_DELETED], is_deleted)
|
||||
|
||||
query = {VProps.CATEGORY: EntityCategory.ALARM,
|
||||
VProps.TYPE: 'vitrage', VProps.IS_DELETED: False}
|
||||
is_deleted = False
|
||||
|
||||
query = {VProps.CATEGORY: EntityCategory.ALARM, VProps.TYPE: 'nagios'}
|
||||
port_neighbors = entity_graph.neighbors(port_vertex.vertex_id,
|
||||
@ -710,10 +755,14 @@ class TestScenarioEvaluator(TestFunctionalBase):
|
||||
processor.process_event(event_queue.get())
|
||||
|
||||
self.assertEqual(num_orig_vertices + num_added_vertices +
|
||||
num_deduced_vertices + num_network_alarm_vertices,
|
||||
num_deduced_vertices + num_network_alarm_vertices +
|
||||
# This is due to keeping alarm history :
|
||||
# new alarm doesn't update same deleted alarm.
|
||||
# Instead, it keeps the old one and creates a new one
|
||||
1,
|
||||
entity_graph.num_vertices())
|
||||
self.assertEqual(num_orig_edges + num_added_edges + num_deduced_edges +
|
||||
num_network_alarm_edges, entity_graph.num_edges())
|
||||
num_network_alarm_edges + 1, entity_graph.num_edges())
|
||||
|
||||
query = {VProps.CATEGORY: EntityCategory.ALARM}
|
||||
network_neighbors = entity_graph.neighbors(network_vertex.vertex_id,
|
||||
@ -725,15 +774,25 @@ class TestScenarioEvaluator(TestFunctionalBase):
|
||||
self.assertEqual(network_neighbors[0][VProps.NAME], 'NETWORK_PROBLEM')
|
||||
self.assertEqual(network_neighbors[0][VProps.IS_DELETED], True)
|
||||
|
||||
zone_neighbors = entity_graph.neighbors(zone_vertex.vertex_id,
|
||||
vertex_attr_filter=query)
|
||||
self.assertEqual(1, len(zone_neighbors))
|
||||
self.assertEqual(zone_neighbors[0][VProps.CATEGORY],
|
||||
EntityCategory.ALARM)
|
||||
self.assertEqual(zone_neighbors[0][VProps.TYPE], 'vitrage')
|
||||
self.assertEqual(zone_neighbors[0][VProps.NAME],
|
||||
'complex_zone_deduced_alarm')
|
||||
self.assertEqual(zone_neighbors[0][VProps.IS_DELETED], False)
|
||||
query = {VProps.CATEGORY: EntityCategory.ALARM,
|
||||
VProps.IS_DELETED: True}
|
||||
is_deleted = True
|
||||
# Alarm History is saved. We are testing the deleted alarm and
|
||||
# then we are testing the live alarm
|
||||
for counter in range(0, 1):
|
||||
zone_neighbors = entity_graph.neighbors(zone_vertex.vertex_id,
|
||||
vertex_attr_filter=query)
|
||||
self.assertEqual(1, len(zone_neighbors))
|
||||
self.assertEqual(zone_neighbors[0][VProps.CATEGORY],
|
||||
EntityCategory.ALARM)
|
||||
self.assertEqual(zone_neighbors[0][VProps.TYPE], 'vitrage')
|
||||
self.assertEqual(zone_neighbors[0][VProps.NAME],
|
||||
'complex_zone_deduced_alarm')
|
||||
self.assertEqual(zone_neighbors[0][VProps.IS_DELETED], is_deleted)
|
||||
|
||||
query = {VProps.CATEGORY: EntityCategory.ALARM,
|
||||
VProps.IS_DELETED: False}
|
||||
is_deleted = False
|
||||
|
||||
def get_host_after_event(self, event_queue, nagios_event,
|
||||
processor, target_host):
|
||||
@ -741,12 +800,13 @@ class TestScenarioEvaluator(TestFunctionalBase):
|
||||
while not event_queue.empty():
|
||||
processor.process_event(event_queue.get())
|
||||
host_v = self._get_entity_from_graph(NOVA_HOST_DATASOURCE,
|
||||
target_host,
|
||||
target_host,
|
||||
processor.entity_graph)
|
||||
return host_v
|
||||
|
||||
def _init_system(self):
|
||||
processor = self._create_processor_with_graph(self.conf)
|
||||
processor = self._create_processor_with_graph(self.conf, uuid=True)
|
||||
event_queue = queue.Queue()
|
||||
evaluator = ScenarioEvaluator(self.conf, processor.entity_graph,
|
||||
self.scenario_repository, event_queue,
|
||||
@ -754,8 +814,11 @@ class TestScenarioEvaluator(TestFunctionalBase):
|
||||
return event_queue, processor, evaluator
|
||||
|
||||
@staticmethod
|
||||
def _get_entity_from_graph(entity_type, entity_name, entity_graph):
|
||||
def _get_entity_from_graph(entity_type, entity_name,
|
||||
entity_id,
|
||||
entity_graph):
|
||||
vertex_attrs = {VProps.TYPE: entity_type,
|
||||
VProps.ID: entity_id,
|
||||
VProps.NAME: entity_name}
|
||||
vertices = entity_graph.get_vertices(vertex_attr_filter=vertex_attrs)
|
||||
# assert len(vertices) == 1, "incorrect number of vertices"
|
||||
|
@ -9,6 +9,9 @@
|
||||
"service": "compute",
|
||||
"vitrage_entity_type": "nova.host",
|
||||
"zone": "zone0",
|
||||
"id": "compute-0-0.local",
|
||||
"category": "RESOURCE",
|
||||
"vitrage_id": "compute-0-0.local",
|
||||
"vitrage_datasource_action": "init_snapshot",
|
||||
"vitrage_sample_date": "2015-12-01T12:46:41Z"
|
||||
}
|
||||
|
@ -72,6 +72,7 @@
|
||||
"key_name": null,
|
||||
"OS-EXT-SRV-ATTR:hypervisor_hostname": "nyakar-devstack",
|
||||
"name": "vm2",
|
||||
"category": "RESOURCE",
|
||||
"created": "2015-11-25T14:18:07Z",
|
||||
"tenant_id": "0683517e1e354d2ba25cba6937f44e79",
|
||||
"os-extended-volumes:volumes_attached": [],
|
||||
|
@ -12,6 +12,9 @@
|
||||
"vitrage_entity_type": "nova.zone",
|
||||
"vitrage_datasource_action": "snapshot",
|
||||
"zoneName": "zone0",
|
||||
"id": "zone0",
|
||||
"vitrage_id": "zone0",
|
||||
"category": "RESOURCE",
|
||||
"zoneState": {
|
||||
"available": "True"
|
||||
}
|
||||
|
@ -208,8 +208,6 @@ class NovaZoneTransformerTest(base.BaseTest):
|
||||
|
||||
self.assertEqual(cluster_neighbor.vertex[VProps.VITRAGE_ID],
|
||||
cluster_neighbor.vertex.vertex_id)
|
||||
self.assertEqual('RESOURCE:openstack.cluster:OpenStack Cluster',
|
||||
cluster_neighbor.vertex[VProps.VITRAGE_ID])
|
||||
self.assertEqual(False,
|
||||
cluster_neighbor.vertex[VProps.IS_DELETED])
|
||||
self.assertEqual(EntityCategory.RESOURCE,
|
||||
|
@ -114,7 +114,8 @@ class TestEntityGraphUnitBase(base.BaseTest):
|
||||
|
||||
# add instance entity with host
|
||||
if processor is None:
|
||||
processor = proc.Processor(self.conf, InitializationStatus())
|
||||
processor = proc.Processor(self.conf, InitializationStatus(),
|
||||
uuid=True)
|
||||
|
||||
vertex, neighbors, event_type = processor.transformer_manager\
|
||||
.transform(event)
|
||||
@ -146,7 +147,7 @@ class TestEntityGraphUnitBase(base.BaseTest):
|
||||
return events_list[0]
|
||||
|
||||
@staticmethod
|
||||
def _create_alarm(vitrage_id, alarm_type, project_id=None):
|
||||
def _create_alarm(vitrage_id, alarm_type, project_id=None, metadata=None):
|
||||
return graph_utils.create_vertex(
|
||||
vitrage_id,
|
||||
entity_id=vitrage_id,
|
||||
@ -156,7 +157,8 @@ class TestEntityGraphUnitBase(base.BaseTest):
|
||||
is_deleted=False,
|
||||
sample_timestamp=None,
|
||||
is_placeholder=False,
|
||||
project_id=project_id
|
||||
project_id=project_id,
|
||||
metadata=metadata
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
|
@ -51,7 +51,8 @@ class TestProcessor(TestEntityGraphUnitBase):
|
||||
|
||||
def test_process_event(self):
|
||||
# check create instance event
|
||||
processor = proc.Processor(self.conf, InitializationStatus())
|
||||
processor = proc.Processor(self.conf, InitializationStatus(),
|
||||
uuid=True)
|
||||
event = self._create_event(spec_type=self.INSTANCE_SPEC,
|
||||
datasource_action=DSAction.INIT_SNAPSHOT)
|
||||
processor.process_event(event)
|
||||
@ -145,10 +146,17 @@ class TestProcessor(TestEntityGraphUnitBase):
|
||||
new_edge = graph_utils.create_edge(vertex1.vertex_id,
|
||||
vertex2.vertex_id,
|
||||
'backup')
|
||||
new_neighbors = [Neighbor(None, new_edge)]
|
||||
mock_neighbor = graph_utils.create_vertex(
|
||||
"asdjashdkahsdashdalksjhd",
|
||||
entity_id="wtw64768476",
|
||||
entity_category="RESOURCE",
|
||||
entity_type="nova.instance",
|
||||
entity_state="AVAILABLE",
|
||||
)
|
||||
new_neighbors = [Neighbor(mock_neighbor, new_edge)]
|
||||
|
||||
# action
|
||||
processor.update_relationship(None, new_neighbors)
|
||||
processor.update_relationship(vertex1, new_neighbors)
|
||||
|
||||
# test assertions
|
||||
self.assertEqual(3, processor.entity_graph.num_edges())
|
||||
@ -169,10 +177,10 @@ class TestProcessor(TestEntityGraphUnitBase):
|
||||
'backup')
|
||||
processor.entity_graph.add_edge(new_edge)
|
||||
self.assertEqual(3, processor.entity_graph.num_edges())
|
||||
new_neighbors = [Neighbor(None, new_edge)]
|
||||
new_neighbors = [Neighbor(vertex1, new_edge)]
|
||||
|
||||
# action
|
||||
processor.delete_relationship(None, new_neighbors)
|
||||
processor.delete_relationship(vertex2, new_neighbors)
|
||||
|
||||
# test assertions
|
||||
edge_from_graph = processor.entity_graph.get_edge(vertex1.vertex_id,
|
||||
|
@ -21,6 +21,8 @@ from vitrage.evaluator.template_fields import TemplateFields as TFields
|
||||
from vitrage.graph import Vertex
|
||||
from vitrage.tests import base
|
||||
|
||||
_SET_STATES_PARAM_LEN = 3
|
||||
|
||||
|
||||
class SetStateRecipeTest(base.BaseTest):
|
||||
|
||||
@ -47,7 +49,7 @@ class SetStateRecipeTest(base.BaseTest):
|
||||
|
||||
self.assertEqual(UPDATE_VERTEX, action_steps[0].type)
|
||||
update_vertex_step_params = action_steps[0].params
|
||||
self.assertEqual(2, len(update_vertex_step_params))
|
||||
self.assertEqual(_SET_STATES_PARAM_LEN, len(update_vertex_step_params))
|
||||
|
||||
vitrage_state = update_vertex_step_params[VProps.VITRAGE_STATE]
|
||||
self.assertEqual(self.props[TFields.STATE], vitrage_state)
|
||||
@ -67,7 +69,7 @@ class SetStateRecipeTest(base.BaseTest):
|
||||
|
||||
self.assertEqual(UPDATE_VERTEX, action_steps[0].type)
|
||||
update_vertex_step_params = action_steps[0].params
|
||||
self.assertEqual(2, len(update_vertex_step_params))
|
||||
self.assertEqual(_SET_STATES_PARAM_LEN, len(update_vertex_step_params))
|
||||
|
||||
vitrage_state = update_vertex_step_params[VProps.VITRAGE_STATE]
|
||||
self.assertIsNone(vitrage_state)
|
||||
|
@ -26,6 +26,7 @@ from oslo_log import log as logging
|
||||
|
||||
from vitrage.common.constants import EdgeLabel as ELabel
|
||||
from vitrage.common.constants import EntityCategory
|
||||
from vitrage.common.constants import VertexProperties as VProps
|
||||
from vitrage.common.exception import VitrageError
|
||||
from vitrage.datasources.nova.host import NOVA_HOST_DATASOURCE
|
||||
from vitrage.datasources.nova.instance import NOVA_INSTANCE_DATASOURCE
|
||||
@ -75,7 +76,9 @@ v_alarm = graph_utils.create_vertex(
|
||||
vitrage_id=ALARM + '444444444444',
|
||||
entity_id='444444444444',
|
||||
entity_type=ALARM_ON_VM,
|
||||
entity_category=ALARM)
|
||||
entity_category=ALARM,
|
||||
metadata={VProps.RESOURCE_ID: '333333333333',
|
||||
VProps.NAME: 'anotheralarm'})
|
||||
v_switch = graph_utils.create_vertex(
|
||||
vitrage_id=SWITCH + '1212121212',
|
||||
entity_id='1212121212',
|
||||
@ -95,12 +98,14 @@ e_node_to_switch = graph_utils.create_edge(
|
||||
|
||||
|
||||
def add_connected_vertex(graph, entity_type, entity_subtype, entity_id,
|
||||
edge_type, other_vertex, reverse=False):
|
||||
edge_type, other_vertex, reverse=False,
|
||||
metadata=None):
|
||||
vertex = graph_utils.create_vertex(
|
||||
vitrage_id=entity_subtype + str(entity_id),
|
||||
entity_id=entity_id,
|
||||
entity_category=entity_type,
|
||||
entity_type=entity_subtype)
|
||||
entity_type=entity_subtype,
|
||||
metadata=metadata)
|
||||
edge = graph_utils.create_edge(
|
||||
source_id=other_vertex.vertex_id if reverse else vertex.vertex_id,
|
||||
target_id=vertex.vertex_id if reverse else other_vertex.vertex_id,
|
||||
@ -136,7 +141,8 @@ class GraphTestBase(base.BaseTest):
|
||||
start = time.time()
|
||||
g = NXGraph(name, EntityCategory.RESOURCE + ':' +
|
||||
OPENSTACK_CLUSTER + ':' +
|
||||
CLUSTER_ID)
|
||||
CLUSTER_ID,
|
||||
uuid=True)
|
||||
g.add_vertex(v_node)
|
||||
g.add_vertex(v_switch)
|
||||
g.add_edge(e_node_to_switch)
|
||||
@ -158,7 +164,9 @@ class GraphTestBase(base.BaseTest):
|
||||
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)
|
||||
host_to_add, False,
|
||||
{VProps.RESOURCE_ID: host_id,
|
||||
VProps.NAME: host_id})
|
||||
cls.host_alarm_id += 1
|
||||
|
||||
# Add Host Tests
|
||||
@ -183,7 +191,9 @@ class GraphTestBase(base.BaseTest):
|
||||
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)
|
||||
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()
|
||||
|
@ -103,7 +103,9 @@ class TestGraph(GraphTestBase):
|
||||
vitrage_id='123',
|
||||
entity_id='456',
|
||||
entity_category=NOVA_INSTANCE_DATASOURCE,
|
||||
metadata={'some_meta': 'DATA'}
|
||||
metadata={'some_meta': 'DATA',
|
||||
'type': 'nova.instance',
|
||||
'resource_id': 'sdg7849ythksjdg'}
|
||||
)
|
||||
g.add_vertex(another_vertex)
|
||||
v = g.get_vertex(another_vertex.vertex_id)
|
||||
@ -254,7 +256,8 @@ class TestGraph(GraphTestBase):
|
||||
v4 = v_alarm
|
||||
v5 = utils.create_vertex(
|
||||
vitrage_id='kuku',
|
||||
entity_category=NOVA_HOST_DATASOURCE)
|
||||
entity_type=NOVA_HOST_DATASOURCE,
|
||||
entity_category=EntityCategory.RESOURCE)
|
||||
|
||||
g = NXGraph('test_neighbors')
|
||||
g.add_vertex(v1)
|
||||
|
@ -21,7 +21,6 @@ Tests for `vitrage` graph driver algorithms
|
||||
|
||||
from vitrage.common.constants import EdgeLabel
|
||||
from vitrage.common.constants import EdgeProperties as EProps
|
||||
from vitrage.common.constants import VertexProperties as VProps
|
||||
from vitrage.datasources.heat.stack import HEAT_STACK_DATASOURCE
|
||||
from vitrage.datasources.neutron.network import NEUTRON_NETWORK_DATASOURCE
|
||||
from vitrage.graph.algo_driver.algorithm import Mapping
|
||||
|
@ -19,6 +19,8 @@ from datetime import datetime
|
||||
from oslo_log import log as logging
|
||||
from oslotest import base
|
||||
|
||||
import unittest
|
||||
|
||||
from vitrage.common.constants import EntityCategory
|
||||
from vitrage.common.constants import EventProperties as EventProps
|
||||
from vitrage.common.constants import VertexProperties as VProps
|
||||
@ -39,22 +41,40 @@ class TestEvents(base.BaseTestCase):
|
||||
cls.vitrage_client = \
|
||||
v_client.Client('1', session=keystone_client.get_session(cls.conf))
|
||||
|
||||
def test_send_doctor_event(self):
|
||||
def test_send_doctor_event_with_resource_id(self):
|
||||
"""Sending an event in Doctor format should result in an alarm"""
|
||||
details = {
|
||||
'hostname': 'host123',
|
||||
'source': 'sample_monitor',
|
||||
'cause': 'another alarm',
|
||||
'severity': 'critical',
|
||||
'status': 'down',
|
||||
'monitor_id': 'sample monitor',
|
||||
'resource_id': 'host123',
|
||||
'monitor_event_id': '456',
|
||||
}
|
||||
self._test_send_doctor_event(details)
|
||||
|
||||
@unittest.skip("testing skipping")
|
||||
def test_send_doctor_event_without_resource_id(self):
|
||||
"""Sending an event in Doctor format should result in an alarm"""
|
||||
details = {
|
||||
'hostname': 'host123',
|
||||
'source': 'sample_monitor',
|
||||
'cause': 'another alarm',
|
||||
'severity': 'critical',
|
||||
'status': 'down',
|
||||
'monitor_id': 'sample monitor',
|
||||
'monitor_event_id': '456',
|
||||
}
|
||||
self._test_send_doctor_event(details)
|
||||
|
||||
def _test_send_doctor_event(self, details):
|
||||
try:
|
||||
# post an event to the message bus
|
||||
event_time = datetime.now()
|
||||
event_time_iso = event_time.isoformat()
|
||||
event_type = 'compute.host.down'
|
||||
details = {
|
||||
'hostname': 'host123',
|
||||
'source': 'sample_monitor',
|
||||
'cause': 'another alarm',
|
||||
'severity': 'critical',
|
||||
'status': 'down',
|
||||
'monitor_id': 'sample monitor',
|
||||
'monitor_event_id': '456',
|
||||
}
|
||||
|
||||
self.vitrage_client.event.post(event_time_iso, event_type, details)
|
||||
|
||||
@ -67,12 +87,15 @@ class TestEvents(base.BaseTestCase):
|
||||
alarm = api_alarms[0]
|
||||
event_time_tz = six.u(event_time.strftime('%Y-%m-%dT%H:%M:%SZ'))
|
||||
self._check_alarm(alarm, event_time_tz, event_type, details)
|
||||
event_time = datetime.now()
|
||||
event_time_iso = event_time.isoformat()
|
||||
details['status'] = 'up'
|
||||
self.vitrage_client.event.post(event_time_iso, event_type, details)
|
||||
|
||||
except Exception as e:
|
||||
LOG.exception(e)
|
||||
raise
|
||||
finally:
|
||||
# do what?
|
||||
LOG.warning('done')
|
||||
|
||||
def _check_alarms(self):
|
||||
|
@ -29,8 +29,7 @@ class BaseTopologyTest(BaseApiTest):
|
||||
def _rollback_to_default(self):
|
||||
self._delete_entities()
|
||||
api_graph = self.vitrage_client.topology.get(
|
||||
limit=4,
|
||||
root='RESOURCE:openstack.cluster:OpenStack Cluster',
|
||||
root=None,
|
||||
all_tenants=True)
|
||||
graph = self._create_graph_from_graph_dictionary(api_graph)
|
||||
entities = self._entities_validation_data()
|
||||
|
@ -31,6 +31,7 @@ NOVA_QUERY = '{"and": [{"==": {"category": "RESOURCE"}},' \
|
||||
'{"==": {"type": "nova.instance"}},' \
|
||||
'{"==": {"type": "nova.host"}},' \
|
||||
'{"==": {"type": "nova.zone"}}]}]}'
|
||||
CLUSTER_VERTEX_ID = 'RESOURCE:openstack.cluster:OpenStack Cluster'
|
||||
|
||||
|
||||
class TestTopology(BaseTopologyTest):
|
||||
@ -277,7 +278,7 @@ class TestTopology(BaseTopologyTest):
|
||||
# Calculate expected results
|
||||
api_graph = self.vitrage_client.topology.get(
|
||||
limit=2,
|
||||
root='RESOURCE:openstack.cluster:OpenStack Cluster',
|
||||
root=CLUSTER_VERTEX_ID,
|
||||
all_tenants=True)
|
||||
graph = self._create_graph_from_graph_dictionary(api_graph)
|
||||
entities = self._entities_validation_data(
|
||||
@ -310,7 +311,7 @@ class TestTopology(BaseTopologyTest):
|
||||
# Calculate expected results
|
||||
api_graph = self.vitrage_client.topology.get(
|
||||
limit=3,
|
||||
root='RESOURCE:openstack.cluster:OpenStack Cluster',
|
||||
root=CLUSTER_VERTEX_ID,
|
||||
all_tenants=True)
|
||||
graph = self._create_graph_from_graph_dictionary(api_graph)
|
||||
entities = self._entities_validation_data(
|
||||
@ -348,14 +349,13 @@ class TestTopology(BaseTopologyTest):
|
||||
# Calculate expected results
|
||||
self.vitrage_client.topology.get(
|
||||
limit=2,
|
||||
root='RESOURCE:openstack.cluster:OpenStack Cluster',
|
||||
root=None,
|
||||
all_tenants=True)
|
||||
except ClientException as e:
|
||||
self.assertEqual(403, e.code)
|
||||
self.assertEqual(
|
||||
str(e),
|
||||
str(e.message),
|
||||
"Graph-type 'graph' requires a 'root' with 'depth'")
|
||||
raise
|
||||
finally:
|
||||
self._rollback_to_default()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user