support 'mark_down' action for instances

Implements: blueprint support-mark-down-action-for-instances

Change-Id: I664f8c8108fd7cd331dcaa6cd2210d31fbd079af
Signed-off-by: dongwenjuan <dong.wenjuan@zte.com.cn>
This commit is contained in:
dongwenjuan 2017-11-21 11:28:02 +08:00
parent 1c3ed3ba78
commit 4b1ecac0fb
4 changed files with 70 additions and 3 deletions

View File

@ -68,3 +68,7 @@ scenarios:
action_target: action_target:
source: host_down_alarm source: host_down_alarm
target: instance_alarm target: instance_alarm
- action:
action_type: mark_down
action_target:
target: instance

View File

@ -21,3 +21,8 @@ OPTS = [
help='nova notifier class path', help='nova notifier class path',
required=True), required=True),
] ]
class InstanceState(object):
ERROR = 'error'
ACTIVE = 'active'

View File

@ -16,7 +16,9 @@ from oslo_log import log as logging
from vitrage.common.constants import NotifierEventTypes from vitrage.common.constants import NotifierEventTypes
from vitrage.common.constants import VertexProperties as VProps from vitrage.common.constants import VertexProperties as VProps
from vitrage.datasources import NOVA_HOST_DATASOURCE from vitrage.datasources import NOVA_HOST_DATASOURCE
from vitrage.datasources import NOVA_INSTANCE_DATASOURCE
from vitrage.notifier.plugins.base import NotifierBase from vitrage.notifier.plugins.base import NotifierBase
from vitrage.notifier.plugins.nova import InstanceState
from vitrage import os_clients from vitrage import os_clients
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -31,13 +33,21 @@ class NovaNotifier(NotifierBase):
def __init__(self, conf): def __init__(self, conf):
super(NovaNotifier, self).__init__(conf) super(NovaNotifier, self).__init__(conf)
self.client = os_clients.nova_client(conf) self.client = os_clients.nova_client(conf)
self.actions = {
NOVA_HOST_DATASOURCE: self._mark_host_down,
NOVA_INSTANCE_DATASOURCE: self._reset_instance_state
}
def process_event(self, data, event_type): def process_event(self, data, event_type):
if data and data.get(VProps.VITRAGE_TYPE) == NOVA_HOST_DATASOURCE: if data and data.get(VProps.VITRAGE_TYPE) in self.actions:
action = self.actions[data.get(VProps.VITRAGE_TYPE)]
if event_type == NotifierEventTypes.ACTIVATE_MARK_DOWN_EVENT: if event_type == NotifierEventTypes.ACTIVATE_MARK_DOWN_EVENT:
self._mark_host_down(data.get(VProps.ID), True) action(data.get(VProps.ID), True)
elif event_type == NotifierEventTypes.DEACTIVATE_MARK_DOWN_EVENT: elif event_type == NotifierEventTypes.DEACTIVATE_MARK_DOWN_EVENT:
self._mark_host_down(data.get(VProps.ID), False) action(data.get(VProps.ID), False)
elif data:
LOG.warning('Unsupport datasource type %s for mark_down action',
data.get(VProps.VITRAGE_TYPE))
def _mark_host_down(self, host_id, is_down): def _mark_host_down(self, host_id, is_down):
try: try:
@ -48,3 +58,13 @@ class NovaNotifier(NotifierBase):
LOG.info('RESPONSE %s', str(response.to_dict())) LOG.info('RESPONSE %s', str(response.to_dict()))
except Exception as e: except Exception as e:
LOG.exception('Failed to services.force_down - %s', e) LOG.exception('Failed to services.force_down - %s', e)
def _reset_instance_state(self, server_id, is_down):
state = InstanceState.ERROR if is_down else InstanceState.ACTIVE
try:
LOG.info('Nova servers.reset_state - server: %s, state: %s',
str(server_id), str(state))
response = self.client.servers.reset_state(server_id, state)
LOG.info('RESPONSE %s', str(response))
except Exception as e:
LOG.exception('Failed to execute servers.reset_state - %s', e)

View File

@ -28,6 +28,7 @@ from vitrage.datasources.nagios import NAGIOS_DATASOURCE
from vitrage.datasources.nagios.properties import NagiosProperties as NProps from vitrage.datasources.nagios.properties import NagiosProperties as NProps
from vitrage.datasources.nagios.properties import NagiosTestStatus from vitrage.datasources.nagios.properties import NagiosTestStatus
from vitrage.datasources.nova.host import NOVA_HOST_DATASOURCE from vitrage.datasources.nova.host import NOVA_HOST_DATASOURCE
from vitrage.datasources.nova.instance import NOVA_INSTANCE_DATASOURCE
from vitrage.entity_graph.mappings.operational_alarm_severity import \ from vitrage.entity_graph.mappings.operational_alarm_severity import \
OperationalAlarmSeverity OperationalAlarmSeverity
from vitrage.entity_graph.mappings.operational_resource_state import \ from vitrage.entity_graph.mappings.operational_resource_state import \
@ -116,6 +117,43 @@ class TestActionExecutor(TestFunctionalBase):
self.assertNotIn( self.assertNotIn(
VProps.VITRAGE_STATE, host_vertex_after_undo.properties) VProps.VITRAGE_STATE, host_vertex_after_undo.properties)
def test_execute_mark_instance_down(self):
# Test Setup
processor = self._create_processor_with_graph(self.conf)
vertex_attrs = {VProps.VITRAGE_TYPE: NOVA_INSTANCE_DATASOURCE}
instance_vertices = processor.entity_graph.get_vertices(
vertex_attr_filter=vertex_attrs)
instance_vertex_before = instance_vertices[0]
targets = {TFields.TARGET: instance_vertex_before}
props = {}
action_spec = ActionSpecs(0, ActionType.MARK_DOWN, targets, props)
event_queue = queue.Queue()
action_executor = ActionExecutor(self.conf, event_queue)
# Test Action - do
action_executor.execute(action_spec, ActionMode.DO)
processor.process_event(event_queue.get())
instance_vertex_after = processor.entity_graph.get_vertex(
instance_vertex_before.vertex_id)
# Test Assertions
self.assertTrue(instance_vertex_after.get(VProps.IS_MARKED_DOWN))
# Test Action - undo
action_executor.execute(action_spec, ActionMode.UNDO)
processor.process_event(event_queue.get())
instance_vertex_after_undo = processor.entity_graph.get_vertex(
instance_vertex_before.vertex_id)
# Test Assertions
self.assertFalse(instance_vertex_after_undo.get(VProps.IS_MARKED_DOWN))
def test_execute_mark_down(self): def test_execute_mark_down(self):
# Test Setup # Test Setup