Merge "Bug fix: delete outdated entities for OpenStack datasources"

This commit is contained in:
Zuul 2018-11-29 16:55:29 +00:00 committed by Gerrit Code Review
commit e86a5726f9
8 changed files with 111 additions and 81 deletions

View File

@ -65,3 +65,7 @@ class CinderVolumeDriver(DriverBase):
'volume.detach.end',
'volume.delete.start',
'volume.delete.end']
@staticmethod
def should_delete_outdated_entities():
return True

View File

@ -140,3 +140,7 @@ class HeatStackDriver(DriverBase):
HEAT_STACK_DATASOURCE,
datasource_action,
*self.properties_to_filter_out())
@staticmethod
def should_delete_outdated_entities():
return True

View File

@ -45,3 +45,7 @@ class NetworkDriver(NeutronBase):
NEUTRON_NETWORK_DATASOURCE,
datasource_action,
*self.properties_to_filter_out())
@staticmethod
def should_delete_outdated_entities():
return True

View File

@ -50,3 +50,7 @@ class PortDriver(NeutronBase):
NEUTRON_PORT_DATASOURCE,
datasource_action,
*self.properties_to_filter_out())
@staticmethod
def should_delete_outdated_entities():
return True

View File

@ -29,3 +29,7 @@ class HostDriver(NovaDriverBase):
@staticmethod
def properties_to_filter_out():
return ['manager']
@staticmethod
def should_delete_outdated_entities():
return True

View File

@ -71,3 +71,7 @@ class InstanceDriver(NovaDriverBase):
'compute.instance.volume.detach',
'compute.instance.pause.end',
'compute.instance.unpause.end']
@staticmethod
def should_delete_outdated_entities():
return True

View File

@ -19,7 +19,6 @@ from oslo_config import cfg
from six.moves import queue
from testtools import matchers
from vitrage.common.constants import EdgeLabel
from vitrage.common.constants import EntityCategory
from vitrage.common.constants import VertexProperties as VProps
from vitrage.datasources.nagios import NAGIOS_DATASOURCE
@ -32,7 +31,6 @@ from vitrage.entity_graph.processor.processor import Processor
from vitrage.evaluator.scenario_evaluator import ScenarioEvaluator
from vitrage.evaluator.scenario_repository import ScenarioRepository
from vitrage.graph.driver.networkx_graph import NXGraph
import vitrage.graph.utils as graph_utils
from vitrage.tests.functional.base import TestFunctionalBase
from vitrage.tests.functional.test_configuration import TestConfiguration
from vitrage.tests.mocks import utils
@ -106,6 +104,8 @@ class TestConsistencyFunctional(TestFunctionalBase, TestConfiguration):
# Setup
consistency_interval = self.conf.datasources.snapshots_interval
self._periodic_process_setup_stage(consistency_interval)
self._add_alarms_by_type(consistency_interval=consistency_interval,
alarm_type='prometheus')
# Action
time.sleep(2 * consistency_interval + 1)
@ -130,22 +130,27 @@ class TestConsistencyFunctional(TestFunctionalBase, TestConfiguration):
# number of vertices - 3 (deleted instances)
# number of nics - 1
# number of volumes - 1
# number of prometheus alarms - 1
self.assertThat(self.processor.entity_graph.get_vertices(),
matchers.HasLength(
# 3 instances deleted
self._num_total_expected_vertices() - 3 +
3 - 1 + # one nic deleted
3 - 1) # one cinder.volume deleted
3 - 1 + # one cinder.volume deleted
3 - 1) # one prometheus deleted
)
self.assertThat(deleted_instance_vertices, matchers.HasLength(3))
# one nic was deleted, one marked as deleted, one untouched
self._assert_vertices_status('nic', 2, 1)
# same for cinder.volume
self._assert_vertices_status(EntityCategory.RESOURCE, 'nic', 2, 1)
self._assert_vertices_status(
EntityCategory.RESOURCE, 'cinder.volume', 2, 1)
# one cinder.volume deleted, other two are untouched
# cinder.volume vertices should not be marked as deleted, since the
# one prometheus deleted, other two are untouched
# prometheus vertices should not be marked as deleted, since the
# datasource did not ask to delete outdated vertices.
self._assert_vertices_status('cinder.volume', 2, 0)
self._assert_vertices_status(EntityCategory.ALARM, 'prometheus', 2, 0)
def test_should_delete_vertex(self):
# should be deleted because the static datasource asks to delete its
@ -154,47 +159,54 @@ class TestConsistencyFunctional(TestFunctionalBase, TestConfiguration):
self.assertTrue(
self.consistency_enforcer._should_delete_vertex(static_vertex))
# should not be deleted because the cinder datasource does not ask to
# delete its outdated vertices
# should be deleted because the cinder datasource asks to delete its
# outdated vertices
volume_vertex = {VProps.VITRAGE_DATASOURCE_NAME: 'cinder.volume'}
self.assertFalse(
self.assertTrue(
self.consistency_enforcer._should_delete_vertex(volume_vertex))
# should not be deleted because the prometheus datasource does not ask
# to delete its outdated vertices
prometheus_vertex = {VProps.VITRAGE_DATASOURCE_NAME: 'prometheus'}
self.assertFalse(
self.consistency_enforcer._should_delete_vertex(prometheus_vertex))
# should be deleted because it is a placeholder
placeholder_vertex = {VProps.VITRAGE_IS_PLACEHOLDER: True,
VProps.VITRAGE_TYPE: 'cinder.volume'}
VProps.VITRAGE_TYPE: 'prometheus'}
self.assertTrue(self.consistency_enforcer.
_should_delete_vertex(placeholder_vertex))
# should be deleted because it is an openstack.cluster
# should not be deleted because it is an openstack.cluster
cluster_vertex = {VProps.VITRAGE_IS_PLACEHOLDER: True,
VProps.VITRAGE_TYPE: 'openstack.cluster'}
self.assertFalse(self.consistency_enforcer._should_delete_vertex(
cluster_vertex))
vertices = \
[static_vertex, volume_vertex, placeholder_vertex, cluster_vertex]
vertices = [static_vertex, volume_vertex, prometheus_vertex,
placeholder_vertex, cluster_vertex]
vertices_to_mark_deleted = self.consistency_enforcer.\
_filter_vertices_to_be_marked_as_deleted(vertices)
self.assertThat(vertices_to_mark_deleted, matchers.HasLength(2))
self.assertThat(vertices_to_mark_deleted, matchers.HasLength(3))
self.assertTrue(static_vertex in vertices_to_mark_deleted)
self.assertTrue(placeholder_vertex in vertices_to_mark_deleted)
self.assertFalse(volume_vertex in vertices_to_mark_deleted)
self.assertTrue(volume_vertex in vertices_to_mark_deleted)
self.assertFalse(prometheus_vertex in vertices_to_mark_deleted)
self.assertFalse(cluster_vertex in vertices_to_mark_deleted)
def _assert_vertices_status(self, vitrage_type,
def _assert_vertices_status(self, category, vitrage_type,
num_vertices, num_marked_deleted):
vertices = \
self.processor.entity_graph.get_vertices({
VProps.VITRAGE_CATEGORY: EntityCategory.RESOURCE,
VProps.VITRAGE_CATEGORY: category,
VProps.VITRAGE_TYPE: vitrage_type,
})
self.assertThat(vertices, matchers.HasLength(num_vertices))
marked_deleted_vertices = \
self.processor.entity_graph.get_vertices({
VProps.VITRAGE_CATEGORY: EntityCategory.RESOURCE,
VProps.VITRAGE_CATEGORY: category,
VProps.VITRAGE_TYPE: vitrage_type,
VProps.VITRAGE_IS_DELETED: True
})
@ -233,8 +245,12 @@ class TestConsistencyFunctional(TestFunctionalBase, TestConfiguration):
current_time + timedelta(seconds=2 * consistency_interval + 1))
self.processor.entity_graph.update_vertex(instance_vertices[i])
self._add_static_resources(consistency_interval)
self._add_cinder_volume_resources(consistency_interval)
self._add_resources_by_type(consistency_interval=consistency_interval,
datasource_name='static',
resource_type='nic')
self._add_resources_by_type(consistency_interval=consistency_interval,
datasource_name='cinder.volume',
resource_type='cinder.volume')
def _set_end_messages(self):
self.initialization_status.end_messages[NOVA_ZONE_DATASOURCE] = True
@ -243,41 +259,6 @@ class TestConsistencyFunctional(TestFunctionalBase, TestConfiguration):
True
self.initialization_status.end_messages[NAGIOS_DATASOURCE] = True
def _add_alarms(self):
# find hosts and instances
host_vertices = self.processor.entity_graph.get_vertices({
VProps.VITRAGE_CATEGORY: EntityCategory.RESOURCE,
VProps.VITRAGE_TYPE: NOVA_HOST_DATASOURCE
})
# add host alarms + deduced alarms
self.evaluator.enabled = True
alarms_on_hosts_list = []
for index, host_vertex in enumerate(host_vertices):
alarm_name = '%s:%s' % ('nagios_alarm_on_host_',
host_vertex[VProps.NAME])
alarms_on_hosts_list.append(
self._create_alarm(alarm_name, NAGIOS_DATASOURCE))
self.processor.entity_graph.add_vertex(alarms_on_hosts_list[index])
edge = graph_utils.create_edge(
alarms_on_hosts_list[index].vertex_id,
host_vertex.vertex_id,
EdgeLabel.ON)
self.processor.entity_graph.add_edge(edge)
# reliable action to check that the events in the queue
while self.event_queue.empty():
time.sleep(0.1)
while not self.event_queue.empty():
self.processor.process_event(self.event_queue.get())
# remove external alarms
self.evaluator.enabled = False
self.processor.entity_graph.remove_vertex(alarms_on_hosts_list[2])
self.processor.entity_graph.remove_vertex(alarms_on_hosts_list[3])
self.evaluator.enabled = True
def _update_timestamp(self, lst, timestamp):
for vertex in lst:
vertex[VProps.VITRAGE_SAMPLE_TIMESTAMP] = str(timestamp)
@ -302,19 +283,41 @@ class TestConsistencyFunctional(TestFunctionalBase, TestConfiguration):
if num_retries == 30:
return
def _add_static_resources(self, consistency_interval):
self._add_resources_with_different_timestamps(
consistency_interval=consistency_interval,
datasource_name='static', resource_type='nic')
def _add_resources_by_type(self, consistency_interval, resource_type,
datasource_name):
def _create_resource_by_type(v_id, v_type, ds_name, timestamp,
is_deleted=False):
return self._create_resource(
vitrage_id=v_id, resource_type=v_type, datasource_name=ds_name,
sample_timestamp=timestamp, is_deleted=is_deleted)
def _add_cinder_volume_resources(self, consistency_interval):
self._add_resources_with_different_timestamps(
self._add_entities_with_different_timestamps(
consistency_interval=consistency_interval,
datasource_name='cinder.volume', resource_type='cinder.volume')
create_func=_create_resource_by_type,
category=EntityCategory.RESOURCE,
datasource_name=datasource_name, resource_type=resource_type)
def _add_resources_with_different_timestamps(self, consistency_interval,
datasource_name,
resource_type):
def _add_alarms_by_type(
self, consistency_interval, alarm_type):
def _create_alarm_by_type(v_id, v_type, ds_name, timestamp,
is_deleted=False):
return self._create_alarm(
vitrage_id=v_id, alarm_type=v_type, datasource_name=ds_name,
project_id=None, vitrage_resource_project_id=None,
metadata=None, vitrage_sample_timestamp=timestamp,
is_deleted=is_deleted)
self._add_entities_with_different_timestamps(
consistency_interval=consistency_interval,
create_func=_create_alarm_by_type,
category=EntityCategory.ALARM,
datasource_name=alarm_type, resource_type=alarm_type)
def _add_entities_with_different_timestamps(self, consistency_interval,
create_func,
category,
datasource_name,
resource_type):
# add resources to the graph:
# - updated_resource
# - outdated_resource with an old timestamp
@ -325,16 +328,15 @@ class TestConsistencyFunctional(TestFunctionalBase, TestConfiguration):
past_timestamp = \
str(utcnow() - timedelta(seconds=2 * consistency_interval - 1))
updated_resource = self._create_resource(
vitrage_id=resource_type + '1234', resource_type=resource_type,
datasource_name=datasource_name, sample_timestamp=future_timestamp)
outdated_resource = self._create_resource(
vitrage_id=resource_type + '5678', resource_type=resource_type,
datasource_name=datasource_name, sample_timestamp=past_timestamp)
deleted_resource = self._create_resource(
vitrage_id=resource_type + '9999', resource_type=resource_type,
datasource_name=datasource_name, sample_timestamp=past_timestamp,
is_deleted=True)
updated_resource = create_func(
v_id=resource_type + '1234', v_type=resource_type,
ds_name=datasource_name, timestamp=future_timestamp)
outdated_resource = create_func(
v_id=resource_type + '5678', v_type=resource_type,
ds_name=datasource_name, timestamp=past_timestamp)
deleted_resource = create_func(
v_id=resource_type + '9999', v_type=resource_type,
ds_name=datasource_name, timestamp=past_timestamp, is_deleted=True)
self.graph.add_vertex(updated_resource)
self.graph.add_vertex(outdated_resource)
@ -342,7 +344,7 @@ class TestConsistencyFunctional(TestFunctionalBase, TestConfiguration):
# get the list of vertices
resource_vertices = self.processor.entity_graph.get_vertices({
VProps.VITRAGE_CATEGORY: EntityCategory.RESOURCE,
VProps.VITRAGE_CATEGORY: category,
VProps.VITRAGE_TYPE: resource_type
})

View File

@ -160,20 +160,24 @@ class TestEntityGraphUnitBase(base.BaseTest):
alarm_type,
project_id=None,
vitrage_resource_project_id=None,
metadata=None):
metadata=None,
vitrage_sample_timestamp=None,
datasource_name=None,
is_deleted=False):
return graph_utils.create_vertex(
vitrage_id,
vitrage_category=EntityCategory.ALARM,
vitrage_type=alarm_type,
vitrage_sample_timestamp=None,
vitrage_sample_timestamp=vitrage_sample_timestamp,
update_timestamp=str(utcnow()),
vitrage_is_deleted=False,
vitrage_is_deleted=is_deleted,
vitrage_is_placeholder=False,
entity_id=vitrage_id,
entity_state='active',
project_id=project_id,
vitrage_resource_project_id=vitrage_resource_project_id,
metadata=metadata
metadata=metadata,
datasource_name=datasource_name
)
@staticmethod