api: Log os-resetState as an instance action
It appears this was missed as this action never hits the compute API and
is fully handled within the API itself. This change simply records an
instance action directly in the API for this admin action providing a
breadcrumb to operators and users.
Closes-Bug: #1911924
Change-Id: Ifd9657f3357bc39cb904caa65168d38def8c9184
(cherry picked from commit 534b4f3895
)
This commit is contained in:
parent
d3968f17df
commit
3d84097eab
|
@ -19,8 +19,10 @@ from nova.api.openstack.compute.schemas import reset_server_state
|
|||
from nova.api.openstack import wsgi
|
||||
from nova.api import validation
|
||||
from nova.compute import api as compute
|
||||
from nova.compute import instance_actions
|
||||
from nova.compute import vm_states
|
||||
from nova import exception
|
||||
from nova import objects
|
||||
from nova.policies import admin_actions as aa_policies
|
||||
|
||||
# States usable in resetState action
|
||||
|
@ -73,9 +75,14 @@ class AdminActionsController(wsgi.Controller):
|
|||
context.can(aa_policies.POLICY_ROOT % 'reset_state',
|
||||
target={'project_id': instance.project_id})
|
||||
|
||||
# Log os-resetState as an instance action
|
||||
instance_action = objects.InstanceAction.action_start(
|
||||
context, instance.uuid, instance_actions.RESET_STATE)
|
||||
|
||||
# Identify the desired state from the body
|
||||
state = state_map[body["os-resetState"]["state"]]
|
||||
|
||||
instance.vm_state = state
|
||||
instance.task_state = None
|
||||
instance.save(admin_state_reset=True)
|
||||
instance_action.finish()
|
||||
|
|
|
@ -70,3 +70,4 @@ LOCK = 'lock'
|
|||
UNLOCK = 'unlock'
|
||||
BACKUP = 'createBackup'
|
||||
CREATE_IMAGE = 'createImage'
|
||||
RESET_STATE = 'resetState'
|
||||
|
|
|
@ -18,6 +18,7 @@ import webob
|
|||
|
||||
from nova.api.openstack.compute import admin_actions \
|
||||
as admin_actions_v21
|
||||
from nova.compute import instance_actions
|
||||
from nova.compute import vm_states
|
||||
from nova import exception
|
||||
from nova import objects
|
||||
|
@ -59,18 +60,27 @@ class ResetStateTestsV21(test.NoDBTestCase):
|
|||
def _get_request(self):
|
||||
return fakes.HTTPRequest.blank('')
|
||||
|
||||
@mock.patch(
|
||||
'nova.objects.instance_action.InstanceAction.action_start',
|
||||
new=mock.Mock(spec=objects.InstanceAction))
|
||||
def test_no_state(self):
|
||||
self.assertRaises(self.bad_request,
|
||||
self.admin_api._reset_state,
|
||||
self.request, self.uuid,
|
||||
body={"os-resetState": None})
|
||||
|
||||
@mock.patch(
|
||||
'nova.objects.instance_action.InstanceAction.action_start',
|
||||
new=mock.Mock(spec=objects.InstanceAction))
|
||||
def test_bad_state(self):
|
||||
self.assertRaises(self.bad_request,
|
||||
self.admin_api._reset_state,
|
||||
self.request, self.uuid,
|
||||
body={"os-resetState": {"state": "spam"}})
|
||||
|
||||
@mock.patch(
|
||||
'nova.objects.instance_action.InstanceAction.action_start',
|
||||
new=mock.Mock(spec=objects.InstanceAction))
|
||||
def test_no_instance(self):
|
||||
self.compute_api.get = mock.MagicMock(
|
||||
side_effect=exception.InstanceNotFound(instance_id='inst_ud'))
|
||||
|
@ -84,11 +94,14 @@ class ResetStateTestsV21(test.NoDBTestCase):
|
|||
self.context, self.uuid, expected_attrs=None,
|
||||
cell_down_support=False)
|
||||
|
||||
def test_reset_active(self):
|
||||
@mock.patch('nova.objects.instance_action.InstanceAction.action_start')
|
||||
def test_reset_active(self, mock_instance_action_start):
|
||||
expected = dict(vm_state=vm_states.ACTIVE, task_state=None)
|
||||
self.instance.save = mock.MagicMock(
|
||||
side_effect=lambda **kw: self._check_instance_state(expected))
|
||||
self.compute_api.get = mock.MagicMock(return_value=self.instance)
|
||||
mock_instance_action = mock.Mock(spec=objects.InstanceAction)
|
||||
mock_instance_action_start.return_value = mock_instance_action
|
||||
|
||||
body = {"os-resetState": {"state": "active"}}
|
||||
result = self.admin_api._reset_state(self.request, self.uuid,
|
||||
|
@ -107,11 +120,18 @@ class ResetStateTestsV21(test.NoDBTestCase):
|
|||
cell_down_support=False)
|
||||
self.instance.save.assert_called_once_with(admin_state_reset=True)
|
||||
|
||||
def test_reset_error(self):
|
||||
mock_instance_action_start.assert_called_once_with(
|
||||
self.context, self.instance.uuid, instance_actions.RESET_STATE)
|
||||
mock_instance_action.finish.assert_called_once()
|
||||
|
||||
@mock.patch('nova.objects.instance_action.InstanceAction.action_start')
|
||||
def test_reset_error(self, mock_instance_action_start):
|
||||
expected = dict(vm_state=vm_states.ERROR, task_state=None)
|
||||
self.instance.save = mock.MagicMock(
|
||||
side_effect=lambda **kw: self._check_instance_state(expected))
|
||||
self.compute_api.get = mock.MagicMock(return_value=self.instance)
|
||||
mock_instance_action = mock.Mock(spec=objects.InstanceAction)
|
||||
mock_instance_action_start.return_value = mock_instance_action
|
||||
|
||||
body = {"os-resetState": {"state": "error"}}
|
||||
result = self.admin_api._reset_state(self.request, self.uuid,
|
||||
|
@ -129,3 +149,7 @@ class ResetStateTestsV21(test.NoDBTestCase):
|
|||
self.context, self.instance.uuid, expected_attrs=None,
|
||||
cell_down_support=False)
|
||||
self.instance.save.assert_called_once_with(admin_state_reset=True)
|
||||
|
||||
mock_instance_action_start.assert_called_once_with(
|
||||
self.context, self.instance.uuid, instance_actions.RESET_STATE)
|
||||
mock_instance_action.finish.assert_called_once()
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
fixes:
|
||||
- |
|
||||
The `os-resetState`_ API will now log an instance action when called. The
|
||||
resulting instance action being visable via the `os-instance-actions`_ API
|
||||
to users and admins, resolving `bug 1911924`_.
|
||||
|
||||
.. _bug 1911924: https://launchpad.net/bugs/1911924
|
||||
.. _os-instance-actions: https://docs.openstack.org/api-ref/compute/?expanded=reset-server-state-os-resetstate-action-detail,list-actions-for-server-detail
|
||||
.. _os-resetState: https://docs.openstack.org/api-ref/compute/?expanded=reset-server-state-os-resetstate-action-detail
|
Loading…
Reference in New Issue