Add instance.unlock notification

The instance.unlock versioned notification is introduced in this
patch.

The unlock operation just changes the instance.locked to False in
API, we send the notification after db operation.

Change-Id: Ic750c33b4f88ba9c62ea8cba86915c6010f2cd6f
blueprint: trigger-notifications-when-lock-unlock-instances
This commit is contained in:
Yikun Jiang 2018-06-20 12:04:55 +08:00 committed by Matt Riedemann
parent 102cdb9315
commit 0b9b37fe9a
9 changed files with 48 additions and 12 deletions

View File

@ -0,0 +1,8 @@
{
"event_type":"instance.unlock",
"payload":{
"$ref": "common_payloads/InstanceActionPayload.json#"
},
"priority":"INFO",
"publisher_id":"nova-api:fake-mini"
}

View File

@ -3847,6 +3847,10 @@ class API(base.Base):
instance.save()
unlock(self, context, instance)
compute_utils.notify_about_instance_action(
context, instance, CONF.host,
action=fields_obj.NotificationAction.UNLOCK,
source=fields_obj.NotificationSource.API)
@check_instance_lock
@check_instance_cell

View File

@ -58,7 +58,8 @@ class EventType(NotificationObject):
# Version 1.10: UPDATE_METADATA value is added to the
# NotificationActionField enum
# Version 1.11: LOCK is added to NotificationActionField enum
VERSION = '1.11'
# Version 1.12: UNLOCK is added to NotificationActionField enum
VERSION = '1.12'
fields = {
'object': fields.StringField(nullable=False),

View File

@ -541,6 +541,7 @@ class InstanceStateUpdatePayload(base.NotificationPayloadBase):
@base.notification_sample('instance-unshelve-start.json')
@base.notification_sample('instance-unshelve-end.json')
@base.notification_sample('instance-lock.json')
@base.notification_sample('instance-unlock.json')
@nova_base.NovaObjectRegistry.register_notification
class InstanceActionNotification(base.NotificationBase):
# Version 1.0: Initial version

View File

@ -822,6 +822,7 @@ class NotificationAction(BaseNovaEnum):
ADD_MEMBER = 'add_member'
UPDATE_METADATA = 'update_metadata'
LOCK = 'lock'
UNLOCK = 'unlock'
ALL = (UPDATE, EXCEPTION, DELETE, PAUSE, UNPAUSE, RESIZE, VOLUME_SWAP,
SUSPEND, POWER_ON, REBOOT, SHUTDOWN, SNAPSHOT, INTERFACE_ATTACH,
@ -832,7 +833,7 @@ class NotificationAction(BaseNovaEnum):
LIVE_MIGRATION_ROLLBACK_DEST, REBUILD, INTERFACE_DETACH,
RESIZE_CONFIRM, RESIZE_PREP, RESIZE_REVERT, SHELVE_OFFLOAD,
SOFT_DELETE, TRIGGER_CRASH_DUMP, UNRESCUE, UNSHELVE, ADD_HOST,
REMOVE_HOST, ADD_MEMBER, UPDATE_METADATA, LOCK)
REMOVE_HOST, ADD_MEMBER, UPDATE_METADATA, LOCK, UNLOCK)
# TODO(rlrossit): These should be changed over to be a StateMachine enum from

View File

@ -305,7 +305,7 @@ class TestInstanceNotificationSample(
self._test_attach_volume_error,
self._test_interface_attach_and_detach,
self._test_interface_attach_error,
self._test_lock_instance,
self._test_lock_unlock_instance,
]
for action in actions:
@ -1663,19 +1663,28 @@ class TestInstanceNotificationSample(
'fault.traceback': self.ANY},
actual=fake_notifier.VERSIONED_NOTIFICATIONS[1])
def _test_lock_instance(self, server):
def _test_lock_unlock_instance(self, server):
self.api.post_server_action(server['id'], {'lock': {}})
self._wait_for_server_parameter(self.api, server, {'locked': True})
# One versioned notification is generated
self.api.post_server_action(server['id'], {'unlock': {}})
self._wait_for_server_parameter(self.api, server, {'locked': False})
# Two versioned notifications are generated
# 0. instance-lock
# 1. instance-unlock
self.assertEqual(1, len(fake_notifier.VERSIONED_NOTIFICATIONS))
self.assertEqual(2, len(fake_notifier.VERSIONED_NOTIFICATIONS))
self._verify_notification(
'instance-lock',
replacements={
'reservation_id': server['reservation_id'],
'uuid': server['id']},
actual=fake_notifier.VERSIONED_NOTIFICATIONS[0])
self._verify_notification(
'instance-unlock',
replacements={
'reservation_id': server['reservation_id'],
'uuid': server['id']},
actual=fake_notifier.VERSIONED_NOTIFICATIONS[1])
class TestInstanceNotificationSampleOldAttachFlow(

View File

@ -11014,23 +11014,26 @@ class ComputeAPITestCase(BaseTestCase):
self.context, instance, CONF.host, action='lock',
source='nova-api')
@mock.patch('nova.compute.utils.notify_about_instance_action')
@mock.patch('nova.context.RequestContext.elevated')
@mock.patch('nova.compute.api.API._record_action_start')
@mock.patch.object(compute_utils, 'EventReporter')
def test_unlock(self, mock_event, mock_record, mock_elevate):
ctxt = self.context.elevated()
mock_elevate.return_value = ctxt
def test_unlock(self, mock_event, mock_record, mock_elevate, mock_notify):
mock_elevate.return_value = self.context
instance = self._create_fake_instance_obj()
self.stub_out('nova.network.api.API.deallocate_for_instance',
lambda *a, **kw: None)
self.compute_api.unlock(self.context, instance)
mock_record.assert_called_once_with(
ctxt, instance, instance_actions.UNLOCK
self.context, instance, instance_actions.UNLOCK
)
mock_event.assert_called_once_with(ctxt,
mock_event.assert_called_once_with(self.context,
'api_unlock',
CONF.host,
instance.uuid)
mock_notify.assert_called_once_with(
self.context, instance, CONF.host, action='unlock',
source='nova-api')
def test_add_remove_security_group(self):
instance = self._create_fake_instance_obj()

View File

@ -369,7 +369,7 @@ notification_object_data = {
'AuditPeriodPayload': '1.0-2b429dd307b8374636703b843fa3f9cb',
'BandwidthPayload': '1.0-ee2616a7690ab78406842a2b68e34130',
'BlockDevicePayload': '1.0-29751e1b6d41b1454e36768a1e764df8',
'EventType': '1.11-0443197fd02686dacbf1ed7c4345463a',
'EventType': '1.12-db573dfb0e85f269194dcd3b1628b0d2',
'ExceptionNotification': '1.0-a73147b93b520ff0061865849d3dfa56',
'ExceptionPayload': '1.1-6c43008bd81885a63bc7f7c629f0793b',
'FlavorNotification': '1.0-a73147b93b520ff0061865849d3dfa56',

View File

@ -0,0 +1,9 @@
---
features:
- |
The versioned ``instance.lock`` and ``instance.unlock`` notifications have
been added. These notifications are emitted as a result of the respective
server ``lock`` and server ``unlock`` REST API calls.
See https://docs.openstack.org/nova/latest/reference/notifications.html#existing-versioned-notifications
for notification samples.