Merge "api: Log os-resetState as an instance action"
This commit is contained in:
commit
87d05fbae2
nova
api/openstack/compute
compute
tests/unit/api/openstack/compute
releasenotes/notes
@ -19,8 +19,10 @@ from nova.api.openstack.compute.schemas import reset_server_state
|
|||||||
from nova.api.openstack import wsgi
|
from nova.api.openstack import wsgi
|
||||||
from nova.api import validation
|
from nova.api import validation
|
||||||
from nova.compute import api as compute
|
from nova.compute import api as compute
|
||||||
|
from nova.compute import instance_actions
|
||||||
from nova.compute import vm_states
|
from nova.compute import vm_states
|
||||||
from nova import exception
|
from nova import exception
|
||||||
|
from nova import objects
|
||||||
from nova.policies import admin_actions as aa_policies
|
from nova.policies import admin_actions as aa_policies
|
||||||
|
|
||||||
# States usable in resetState action
|
# States usable in resetState action
|
||||||
@ -65,9 +67,14 @@ class AdminActionsController(wsgi.Controller):
|
|||||||
context.can(aa_policies.POLICY_ROOT % 'reset_state',
|
context.can(aa_policies.POLICY_ROOT % 'reset_state',
|
||||||
target={'project_id': instance.project_id})
|
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
|
# Identify the desired state from the body
|
||||||
state = state_map[body["os-resetState"]["state"]]
|
state = state_map[body["os-resetState"]["state"]]
|
||||||
|
|
||||||
instance.vm_state = state
|
instance.vm_state = state
|
||||||
instance.task_state = None
|
instance.task_state = None
|
||||||
instance.save(admin_state_reset=True)
|
instance.save(admin_state_reset=True)
|
||||||
|
instance_action.finish()
|
||||||
|
@ -70,3 +70,4 @@ LOCK = 'lock'
|
|||||||
UNLOCK = 'unlock'
|
UNLOCK = 'unlock'
|
||||||
BACKUP = 'createBackup'
|
BACKUP = 'createBackup'
|
||||||
CREATE_IMAGE = 'createImage'
|
CREATE_IMAGE = 'createImage'
|
||||||
|
RESET_STATE = 'resetState'
|
||||||
|
@ -18,6 +18,7 @@ import webob
|
|||||||
|
|
||||||
from nova.api.openstack.compute import admin_actions \
|
from nova.api.openstack.compute import admin_actions \
|
||||||
as admin_actions_v21
|
as admin_actions_v21
|
||||||
|
from nova.compute import instance_actions
|
||||||
from nova.compute import vm_states
|
from nova.compute import vm_states
|
||||||
from nova import exception
|
from nova import exception
|
||||||
from nova import objects
|
from nova import objects
|
||||||
@ -59,18 +60,27 @@ class ResetStateTestsV21(test.NoDBTestCase):
|
|||||||
def _get_request(self):
|
def _get_request(self):
|
||||||
return fakes.HTTPRequest.blank('')
|
return fakes.HTTPRequest.blank('')
|
||||||
|
|
||||||
|
@mock.patch(
|
||||||
|
'nova.objects.instance_action.InstanceAction.action_start',
|
||||||
|
new=mock.Mock(spec=objects.InstanceAction))
|
||||||
def test_no_state(self):
|
def test_no_state(self):
|
||||||
self.assertRaises(self.bad_request,
|
self.assertRaises(self.bad_request,
|
||||||
self.admin_api._reset_state,
|
self.admin_api._reset_state,
|
||||||
self.request, self.uuid,
|
self.request, self.uuid,
|
||||||
body={"os-resetState": None})
|
body={"os-resetState": None})
|
||||||
|
|
||||||
|
@mock.patch(
|
||||||
|
'nova.objects.instance_action.InstanceAction.action_start',
|
||||||
|
new=mock.Mock(spec=objects.InstanceAction))
|
||||||
def test_bad_state(self):
|
def test_bad_state(self):
|
||||||
self.assertRaises(self.bad_request,
|
self.assertRaises(self.bad_request,
|
||||||
self.admin_api._reset_state,
|
self.admin_api._reset_state,
|
||||||
self.request, self.uuid,
|
self.request, self.uuid,
|
||||||
body={"os-resetState": {"state": "spam"}})
|
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):
|
def test_no_instance(self):
|
||||||
self.compute_api.get = mock.MagicMock(
|
self.compute_api.get = mock.MagicMock(
|
||||||
side_effect=exception.InstanceNotFound(instance_id='inst_ud'))
|
side_effect=exception.InstanceNotFound(instance_id='inst_ud'))
|
||||||
@ -84,11 +94,14 @@ class ResetStateTestsV21(test.NoDBTestCase):
|
|||||||
self.context, self.uuid, expected_attrs=None,
|
self.context, self.uuid, expected_attrs=None,
|
||||||
cell_down_support=False)
|
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)
|
expected = dict(vm_state=vm_states.ACTIVE, task_state=None)
|
||||||
self.instance.save = mock.MagicMock(
|
self.instance.save = mock.MagicMock(
|
||||||
side_effect=lambda **kw: self._check_instance_state(expected))
|
side_effect=lambda **kw: self._check_instance_state(expected))
|
||||||
self.compute_api.get = mock.MagicMock(return_value=self.instance)
|
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"}}
|
body = {"os-resetState": {"state": "active"}}
|
||||||
result = self.admin_api._reset_state(self.request, self.uuid,
|
result = self.admin_api._reset_state(self.request, self.uuid,
|
||||||
@ -107,11 +120,18 @@ class ResetStateTestsV21(test.NoDBTestCase):
|
|||||||
cell_down_support=False)
|
cell_down_support=False)
|
||||||
self.instance.save.assert_called_once_with(admin_state_reset=True)
|
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)
|
expected = dict(vm_state=vm_states.ERROR, task_state=None)
|
||||||
self.instance.save = mock.MagicMock(
|
self.instance.save = mock.MagicMock(
|
||||||
side_effect=lambda **kw: self._check_instance_state(expected))
|
side_effect=lambda **kw: self._check_instance_state(expected))
|
||||||
self.compute_api.get = mock.MagicMock(return_value=self.instance)
|
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"}}
|
body = {"os-resetState": {"state": "error"}}
|
||||||
result = self.admin_api._reset_state(self.request, self.uuid,
|
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,
|
self.context, self.instance.uuid, expected_attrs=None,
|
||||||
cell_down_support=False)
|
cell_down_support=False)
|
||||||
self.instance.save.assert_called_once_with(admin_state_reset=True)
|
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()
|
||||||
|
10
releasenotes/notes/bug-1911924-6e93d8a5038d18c1.yaml
Normal file
10
releasenotes/notes/bug-1911924-6e93d8a5038d18c1.yaml
Normal file
@ -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…
x
Reference in New Issue
Block a user