Add instance.lock notification

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

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

Change-Id: I03a13afa91c29f4fee25336cb82ea5c887eae2f8
blueprint: trigger-notifications-when-lock-unlock-instances
This commit is contained in:
Yikun Jiang 2018-06-20 11:54:05 +08:00
parent ff5cded9af
commit 102cdb9315
8 changed files with 44 additions and 8 deletions

View File

@ -0,0 +1,11 @@
{
"event_type":"instance.lock",
"payload":{
"$ref": "common_payloads/InstanceActionPayload.json#",
"nova_object.data":{
"locked":true
}
},
"priority":"INFO",
"publisher_id":"nova-api:fake-mini"
}

View File

@ -3820,6 +3820,10 @@ class API(base.Base):
instance.save()
lock(self, context, instance)
compute_utils.notify_about_instance_action(
context, instance, CONF.host,
action=fields_obj.NotificationAction.LOCK,
source=fields_obj.NotificationSource.API)
def is_expected_locked_by(self, context, instance):
is_owner = instance.project_id == context.project_id

View File

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

View File

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

View File

@ -821,6 +821,7 @@ class NotificationAction(BaseNovaEnum):
REMOVE_HOST = 'remove_host'
ADD_MEMBER = 'add_member'
UPDATE_METADATA = 'update_metadata'
LOCK = 'lock'
ALL = (UPDATE, EXCEPTION, DELETE, PAUSE, UNPAUSE, RESIZE, VOLUME_SWAP,
SUSPEND, POWER_ON, REBOOT, SHUTDOWN, SNAPSHOT, INTERFACE_ATTACH,
@ -831,7 +832,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)
REMOVE_HOST, ADD_MEMBER, UPDATE_METADATA, LOCK)
# TODO(rlrossit): These should be changed over to be a StateMachine enum from

View File

@ -305,6 +305,7 @@ class TestInstanceNotificationSample(
self._test_attach_volume_error,
self._test_interface_attach_and_detach,
self._test_interface_attach_error,
self._test_lock_instance,
]
for action in actions:
@ -1662,6 +1663,20 @@ class TestInstanceNotificationSample(
'fault.traceback': self.ANY},
actual=fake_notifier.VERSIONED_NOTIFICATIONS[1])
def _test_lock_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
# 0. instance-lock
self.assertEqual(1, 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])
class TestInstanceNotificationSampleOldAttachFlow(
TestInstanceNotificationSample):

View File

@ -10993,23 +10993,26 @@ class ComputeAPITestCase(BaseTestCase):
instance = self.compute_api.get(self.context, instance['uuid'])
self.compute_api.reset_network(self.context, instance)
@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_lock(self, mock_event, mock_record, mock_elevate):
ctxt = self.context.elevated()
mock_elevate.return_value = ctxt
def test_lock(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.lock(self.context, instance)
mock_record.assert_called_once_with(
ctxt, instance, instance_actions.LOCK
self.context, instance, instance_actions.LOCK
)
mock_event.assert_called_once_with(ctxt,
mock_event.assert_called_once_with(self.context,
'api_lock',
CONF.host,
instance.uuid)
mock_notify.assert_called_once_with(
self.context, instance, CONF.host, action='lock',
source='nova-api')
@mock.patch('nova.context.RequestContext.elevated')
@mock.patch('nova.compute.api.API._record_action_start')

View File

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