Add instance action record for lock/unlock instances

We currently don't record lock/unlock instance
actions. This is useful for auditing and debugging.

This patch adds instance lock/unlock actions.

Change-Id: I09fadf79aac1a74465af48015ef97d9e9d4ac580
partial-implements: blueprint fill-the-gap-for-instance-action-records
This commit is contained in:
Kevin_Zheng 2017-11-28 16:45:58 +08:00
parent 1cea4f0135
commit fbea321841
4 changed files with 50 additions and 10 deletions

View File

@ -3473,10 +3473,17 @@ class API(base.Base):
return
context = context.elevated()
LOG.debug('Locking', instance=instance)
instance.locked = True
instance.locked_by = 'owner' if is_owner else 'admin'
instance.save()
self._record_action_start(context, instance,
instance_actions.LOCK)
@wrap_instance_event(prefix='api')
def lock(self, context, instance):
LOG.debug('Locking', instance=instance)
instance.locked = True
instance.locked_by = 'owner' if is_owner else 'admin'
instance.save()
lock(self, context, instance)
def is_expected_locked_by(self, context, instance):
is_owner = instance.project_id == context.project_id
@ -3489,10 +3496,17 @@ class API(base.Base):
def unlock(self, context, instance):
"""Unlock the given instance."""
context = context.elevated()
LOG.debug('Unlocking', instance=instance)
instance.locked = False
instance.locked_by = None
instance.save()
self._record_action_start(context, instance,
instance_actions.UNLOCK)
@wrap_instance_event(prefix='api')
def unlock(self, context, instance):
LOG.debug('Unlocking', instance=instance)
instance.locked = False
instance.locked_by = None
instance.save()
unlock(self, context, instance)
@check_instance_lock
@check_instance_cell

View File

@ -65,3 +65,5 @@ DETACH_INTERFACE = 'detach_interface'
ATTACH_VOLUME = 'attach_volume'
DETACH_VOLUME = 'detach_volume'
SWAP_VOLUME = 'swap_volume'
LOCK = 'lock'
UNLOCK = 'unlock'

View File

@ -10457,17 +10457,39 @@ class ComputeAPITestCase(BaseTestCase):
instance = self.compute_api.get(self.context, instance['uuid'])
self.compute_api.reset_network(self.context, instance)
def test_lock(self):
@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
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
)
mock_event.assert_called_once_with(ctxt,
'api_lock',
instance.uuid)
def test_unlock(self):
@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
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
)
mock_event.assert_called_once_with(ctxt,
'api_unlock',
instance.uuid)
def test_add_remove_security_group(self):
instance = self._create_fake_instance_obj()

View File

@ -8,3 +8,5 @@ features:
* attach_volume
* detach_volume
* swap_volume
* lock
* unlock