Synchronized patch: Nova API-Gateway Server Action Support(part2)

1. What is the problem
Originally this patch was committed to the Tricircle and provided
server action support, but after Tricircle narrowed its scope to
networking automation across Neutron, these API-Gateway features
implemented in this patch were no longer used. However Trio2o needs
these functions, so we plan to synchronize this patch from Gerrit
to Trio2o. You can find the old patch on Gerrit here[1].

The current Nova API-Gateway does not support following server actions:
   reboot: Reboot a server
   resize: Resize a server
   confirmResize: Confirm a pending resize action for a server
   revertResize: Cancel and revert a pending resize action for a server
   os-resetState: Reset the state of a server

2. What is the solution to the problem
Implement the above server actions.

3. What the features need to be implemented to the Trio2o
to realize the solution
Add the above server actions.

[1] https://review.openstack.org/#/c/369958

Change-Id: If0feb3d31fc7877ead84424c7329051857f23628
This commit is contained in:
Dongfeng Huang 2017-04-12 15:28:08 +08:00
parent 5e0b634248
commit 5cbf4c74e6
4 changed files with 218 additions and 124 deletions

View File

@ -97,3 +97,6 @@ NOVA_MICRO_VERSION_PREFIX = 'compute'
# support nova version range
NOVA_APIGW_MIN_VERSION = '2.1'
NOVA_APIGW_MAX_VERSION = '2.36'
# server action url(part url)
SERVER_ACTION_URL = '/servers/%s/action'

View File

@ -36,20 +36,25 @@ class ActionController(rest.RestController):
self.server_id = server_id
self.clients = {constants.TOP: t_client.Client()}
self.handle_map = {
'os-start': self._handle_start,
'os-stop': self._handle_stop,
'forceDelete': self._handle_force_delete,
'lock': self._handle_lock,
'unlock': self._handle_unlock,
'pause': self._handle_pause,
'unpause': self._handle_unpause,
'resume': self._handle_resume,
'suspend': self._handle_suspend,
'shelve': self._handle_shelve,
'unshelve': self._handle_unshelve,
'shelveOffload': self._handle_shelve_offload,
'migrate': self._handle_migrate,
'trigger_crash_dump': self._handle_trigger_crash_dump
'os-start': self._handle_action,
'os-stop': self._handle_action,
'forceDelete': self._handle_action,
'lock': self._handle_action,
'unlock': self._handle_action,
'pause': self._handle_action,
'unpause': self._handle_action,
'resume': self._handle_action,
'suspend': self._handle_action,
'shelve': self._handle_action,
'unshelve': self._handle_action,
'shelveOffload': self._handle_action,
'migrate': self._handle_action,
'trigger_crash_dump': self._handle_action,
'reboot': self._handle_action,
'resize': self._handle_action,
'confirmResize': self._handle_action,
'revertResize': self._handle_action,
'os-resetState': self._handle_action
}
def _get_client(self, pod_name=constants.TOP):
@ -57,62 +62,17 @@ class ActionController(rest.RestController):
self.clients[pod_name] = t_client.Client(pod_name)
return self.clients[pod_name]
def _handle_start(self, context, pod_name, body):
client = self._get_client(pod_name)
return client.action_servers(context, 'start', self.server_id)
def _handle_action(self, context, pod_name, body):
"""Perform a server action
def _handle_stop(self, context, pod_name, body):
client = self._get_client(pod_name)
return client.action_servers(context, 'stop', self.server_id)
:param pod_name: the bottom pod name.
def _handle_force_delete(self, context, pod_name, body):
client = self._get_client(pod_name)
return client.action_servers(context, 'force_delete', self.server_id)
def _handle_pause(self, context, pod_name, body):
client = self._get_client(pod_name)
return client.action_servers(context, 'pause', self.server_id)
def _handle_unpause(self, context, pod_name, body):
client = self._get_client(pod_name)
return client.action_servers(context, 'unpause', self.server_id)
def _handle_lock(self, context, pod_name, body):
client = self._get_client(pod_name)
return client.action_servers(context, 'lock', self.server_id)
def _handle_unlock(self, context, pod_name, body):
client = self._get_client(pod_name)
return client.action_servers(context, 'unlock', self.server_id)
def _handle_suspend(self, context, pod_name, body):
client = self._get_client(pod_name)
return client.action_servers(context, 'suspend', self.server_id)
def _handle_resume(self, context, pod_name, body):
client = self._get_client(pod_name)
return client.action_servers(context, 'resume', self.server_id)
def _handle_shelve(self, context, pod_name, body):
client = self._get_client(pod_name)
return client.action_servers(context, 'shelve', self.server_id)
def _handle_shelve_offload(self, context, pod_name, body):
client = self._get_client(pod_name)
return client.action_servers(context, 'shelve_offload', self.server_id)
def _handle_unshelve(self, context, pod_name, body):
client = self._get_client(pod_name)
return client.action_servers(context, 'unshelve', self.server_id)
def _handle_trigger_crash_dump(self, context, pod_name, body):
client = self._get_client(pod_name)
return client.action_servers(context, 'trigger_crash_dump',
self.server_id)
def _handle_migrate(self, context, pod_name, body):
client = self._get_client(pod_name)
return client.action_servers(context, 'migrate', self.server_id)
:param body: action parameters body.
"""
url = constants.SERVER_ACTION_URL % self.server_id
api = self._get_client(pod_name).get_native_client(constants.RT_SERVER,
context)
return api.client.post(url, body=body)
@expose(generic=True, template='json')
def post(self, **kw):

View File

@ -37,8 +37,15 @@ TESTCASES="$TESTCASES|tempest.api.compute.servers.test_servers_negative.ServersN
TESTCASES="$TESTCASES|tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_suspend_server_invalid_state"
TESTCASES="$TESTCASES|tempest.api.compute.admin.test_servers_negative.ServersAdminNegativeTestJSON.test_migrate_non_existent_server"
TESTCASES="$TESTCASES|tempest.api.compute.admin.test_servers_negative.ServersAdminNegativeTestJSON.test_migrate_server_invalid_state"
# add new test cases like following line for volume_type test
# TESTCASES="$TESTCASES|tempest.api.volume.admin.test_volumes_type"
TESTCASES="$TESTCASES|tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_reboot_server_hard"
TESTCASES="$TESTCASES|tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_reboot_server_soft"
TESTCASES="$TESTCASES|tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_resize_server_revert"
TESTCASES="$TESTCASES|tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_resize_server_confirm"
TESTCASES="$TESTCASES|tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_resize_server_confirm_from_stopped"
TESTCASES="$TESTCASES|tempest.api.compute.admin.test_servers.ServersAdminTestJSON.test_reset_state_server"
TESTCASES="$TESTCASES|tempest.api.compute.admin.test_servers_negative.ServersAdminNegativeTestJSON.test_reset_state_server_invalid_state"
TESTCASES="$TESTCASES|tempest.api.compute.admin.test_servers_negative.ServersAdminNegativeTestJSON.test_reset_state_server_invalid_type"
TESTCASES="$TESTCASES|tempest.api.compute.admin.test_servers_negative.ServersAdminNegativeTestJSON.test_reset_state_server_nonexistent_server"
TESTCASES="$TESTCASES)"
ostestr --regex $TESTCASES
@ -213,13 +220,13 @@ ostestr --regex $TESTCASES
# tempest.api.compute.admin.test_servers.ServersAdminTestJSON.test_list_servers_filter_by_exist_host[id-86c7a8f7-50cf-43a9-9bac-5b985317134f]
# tempest.api.compute.admin.test_servers.ServersAdminTestJSON.test_rebuild_server_in_error_state[id-682cb127-e5bb-4f53-87ce-cb9003604442]
# tempest.api.compute.admin.test_servers.ServersAdminTestJSON.test_reset_network_inject_network_info[id-7a1323b4-a6a2-497a-96cb-76c07b945c71]
# tempest.api.compute.admin.test_servers.ServersAdminTestJSON.test_reset_state_server[id-ee8ae470-db70-474d-b752-690b7892cab1]
# **DONE** tempest.api.compute.admin.test_servers.ServersAdminTestJSON.test_reset_state_server[id-ee8ae470-db70-474d-b752-690b7892cab1]
# tempest.api.compute.admin.test_servers_negative.ServersAdminNegativeTestJSON.test_get_server_diagnostics_by_non_admin[id-e84e2234-60d2-42fa-8b30-e2d3049724ac,negative]
# **DONE** tempest.api.compute.admin.test_servers_negative.ServersAdminNegativeTestJSON.test_migrate_non_existent_server[id-46a4e1ca-87ae-4d28-987a-1b6b136a0221,negative]
# **DONE** tempest.api.compute.admin.test_servers_negative.ServersAdminNegativeTestJSON.test_migrate_server_invalid_state[id-b0b17f83-d14e-4fc4-8f31-bcc9f3cfa629,negative]
# tempest.api.compute.admin.test_servers_negative.ServersAdminNegativeTestJSON.test_reset_state_server_invalid_state[id-b0b4d8af-1256-41ef-9ee7-25f1c19dde80,negative]
# tempest.api.compute.admin.test_servers_negative.ServersAdminNegativeTestJSON.test_reset_state_server_invalid_type[id-4cdcc984-fab0-4577-9a9d-6d558527ee9d,negative]
# tempest.api.compute.admin.test_servers_negative.ServersAdminNegativeTestJSON.test_reset_state_server_nonexistent_server[id-e741298b-8df2-46f0-81cb-8f814ff2504c,negative]
# **DONE** tempest.api.compute.admin.test_servers_negative.ServersAdminNegativeTestJSON.test_reset_state_server_invalid_state[id-b0b4d8af-1256-41ef-9ee7-25f1c19dde80,negative]
# **DONE** tempest.api.compute.admin.test_servers_negative.ServersAdminNegativeTestJSON.test_reset_state_server_invalid_type[id-4cdcc984-fab0-4577-9a9d-6d558527ee9d,negative]
# **DONE** tempest.api.compute.admin.test_servers_negative.ServersAdminNegativeTestJSON.test_reset_state_server_nonexistent_server[id-e741298b-8df2-46f0-81cb-8f814ff2504c,negative]
# tempest.api.compute.admin.test_servers_negative.ServersAdminNegativeTestJSON.test_resize_server_using_overlimit_ram[id-28dcec23-f807-49da-822c-56a92ea3c687,negative]
# tempest.api.compute.admin.test_servers_negative.ServersAdminNegativeTestJSON.test_resize_server_using_overlimit_vcpus[id-7368a427-2f26-4ad9-9ba9-911a0ec2b0db,negative]
# tempest.api.compute.admin.test_servers_on_multinodes.ServersOnMultiNodesTest.test_create_servers_on_different_hosts[id-cc7ca884-6e3e-42a3-a92f-c522fcf25e8e]
@ -449,13 +456,13 @@ ostestr --regex $TESTCASES
# tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_get_vnc_console[id-c6bc11bf-592e-4015-9319-1c98dc64daf5]
# **DONE** tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_lock_unlock_server[id-80a8094c-211e-440a-ab88-9e59d556c7ee]
# **DONE** tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_pause_unpause_server[id-bd61a9fd-062f-4670-972b-2d6c3e3b9e73]
# tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_reboot_server_hard[id-2cb1baf6-ac8d-4429-bf0d-ba8a0ba53e32,smoke]
# tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_reboot_server_soft[id-4640e3ef-a5df-482e-95a1-ceeeb0faa84d]
# **DONE** tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_reboot_server_hard[id-2cb1baf6-ac8d-4429-bf0d-ba8a0ba53e32,smoke]
# **DONE** tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_reboot_server_soft[id-4640e3ef-a5df-482e-95a1-ceeeb0faa84d]
# tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_rebuild_server[id-aaa6cdf3-55a7-461a-add9-1c8596b9a07c]
# tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_rebuild_server_in_stop_state[id-30449a88-5aff-4f9b-9866-6ee9b17f906d]
# tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_resize_server_confirm[id-1499262a-9328-4eda-9068-db1ac57498d2]
# tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_resize_server_confirm_from_stopped[id-138b131d-66df-48c9-a171-64f45eb92962]
# tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_resize_server_revert[id-c03aab19-adb1-44f5-917d-c419577e9e68]
# **DONE** tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_resize_server_confirm[id-1499262a-9328-4eda-9068-db1ac57498d2]
# **DONE** tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_resize_server_confirm_from_stopped[id-138b131d-66df-48c9-a171-64f45eb92962]
# **DONE** tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_resize_server_revert[id-c03aab19-adb1-44f5-917d-c419577e9e68]
# **DONE** tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_shelve_unshelve_server[id-77eba8e0-036e-4635-944b-f7a8f3b78dc9]
# **DONE** tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_stop_start_server[id-af8eafd4-38a7-4a4b-bdbc-75145a580560]
# **DONE** tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_suspend_resume_server[id-0d8ee21e-b749-462d-83da-b85b41c86c7f]

View File

@ -14,12 +14,12 @@
# under the License.
from mock import patch
from novaclient.client import SessionClient
import pecan
import unittest
from oslo_utils import uuidutils
from trio2o.common import client
from trio2o.common import constants
from trio2o.common import context
from trio2o.common import exceptions
@ -40,8 +40,9 @@ class ActionTest(unittest.TestCase):
def setUp(self):
core.initialize()
core.ModelBase.metadata.create_all(core.get_engine())
self.context = context.get_admin_context()
self.context = context.Context()
self.project_id = 'test_project'
self.context.tenant = self.project_id
self.controller = action.ActionController(self.project_id, '')
def _prepare_pod(self, bottom_pod_num=1):
@ -63,6 +64,13 @@ class ActionTest(unittest.TestCase):
b_pods.append(b_pod)
return t_pod, b_pods
def _prepare_pod_service(self, pod_id, service):
config_dict = {'service_id': uuidutils.generate_uuid(),
'pod_id': pod_id,
'service_type': service,
'service_url': 'fake_pod_service'}
api.create_pod_service_configuration(self.context, config_dict)
def _prepare_server(self, pod):
t_server_id = uuidutils.generate_uuid()
b_server_id = t_server_id
@ -96,12 +104,13 @@ class ActionTest(unittest.TestCase):
self._validate_error_code(res, 404)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(client.Client, 'action_resources')
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_action_exception(self, mock_context, mock_action):
mock_context.return_value = self.context
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
@ -122,241 +131,356 @@ class ActionTest(unittest.TestCase):
self._validate_error_code(res, 500)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(client.Client, 'action_resources')
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_start_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {'os-start': ''}
res = self.controller.post(**body)
mock_action.assert_called_once_with(
'server', self.context, 'start', t_server_id)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(client.Client, 'action_resources')
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_stop_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {'os-stop': ''}
res = self.controller.post(**body)
mock_action.assert_called_once_with(
'server', self.context, 'stop', t_server_id)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(client.Client, 'action_resources')
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_force_delete_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {'forceDelete': ''}
res = self.controller.post(**body)
mock_action.assert_called_once_with(
'server', self.context, 'force_delete', t_server_id)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(client.Client, 'action_resources')
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_lock_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {'lock': ''}
res = self.controller.post(**body)
mock_action.assert_called_once_with(
'server', self.context, 'lock', t_server_id)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(client.Client, 'action_resources')
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_unlock_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {'unlock': ''}
res = self.controller.post(**body)
mock_action.assert_called_once_with(
'server', self.context, 'unlock', t_server_id)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(client.Client, 'action_resources')
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_pause_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {'pause': ''}
res = self.controller.post(**body)
mock_action.assert_called_once_with(
'server', self.context, 'pause', t_server_id)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(client.Client, 'action_resources')
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_unpause_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {'unpause': ''}
res = self.controller.post(**body)
mock_action.assert_called_once_with(
'server', self.context, 'unpause', t_server_id)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(client.Client, 'action_resources')
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_suspend_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {'suspend': ''}
res = self.controller.post(**body)
mock_action.assert_called_once_with(
'server', self.context, 'suspend', t_server_id)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(client.Client, 'action_resources')
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_resume_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {'resume': ''}
res = self.controller.post(**body)
mock_action.assert_called_once_with(
'server', self.context, 'resume', t_server_id)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(client.Client, 'action_resources')
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_shelveOffload_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {'shelveOffload': ''}
res = self.controller.post(**body)
mock_action.assert_called_once_with(
'server', self.context, 'shelve_offload', t_server_id)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(client.Client, 'action_resources')
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_shelve_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {'shelve': ''}
res = self.controller.post(**body)
mock_action.assert_called_once_with(
'server', self.context, 'shelve', t_server_id)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(client.Client, 'action_resources')
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_unshelve_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {'unshelve': ''}
res = self.controller.post(**body)
mock_action.assert_called_once_with(
'server', self.context, 'unshelve', t_server_id)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(client.Client, 'action_resources')
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_trigger_crash_dump_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {'trigger_crash_dump': ''}
res = self.controller.post(**body)
mock_action.assert_called_once_with(
'server', self.context, 'trigger_crash_dump', t_server_id)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(client.Client, 'action_resources')
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_migrate_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {'migrate': ''}
res = self.controller.post(**body)
mock_action.assert_called_once_with(
'server', self.context, 'migrate', t_server_id)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_confirm_resize_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {"confirmResize": ''}
res = self.controller.post(**body)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_revert_resize_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {"revertResize": ''}
res = self.controller.post(**body)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_resize_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {"resize": {"flavorRef": "2"}}
res = self.controller.post(**body)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_reset_state_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {"os-resetState": {"state": "active"}}
res = self.controller.post(**body)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_soft_reboot_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {"reboot": {"type": "SOFT"}}
res = self.controller.post(**body)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
@patch.object(pecan, 'response', new=FakeResponse)
@patch.object(SessionClient, 'post')
@patch.object(context, 'extract_context_from_environ')
def test_hard_reboot_action(self, mock_context, mock_action):
mock_context.return_value = self.context
mock_action.return_value = (FakeResponse(202), None)
t_pod, b_pods = self._prepare_pod()
self._prepare_pod_service(b_pods[0]['pod_id'], constants.ST_NOVA)
t_server_id = self._prepare_server(b_pods[0])
self.controller.server_id = t_server_id
body = {"reboot": {"type": "HARD"}}
res = self.controller.post(**body)
url = '/servers/%s/action' % t_server_id
mock_action.assert_called_once_with(url, body=body)
self.assertEqual(202, res.status)
def tearDown(self):