Use wsgi.response for v2.1 API
Now a decorator @wsgi.response() can be used for specifying success status code. Most v2.1 APIs use the decorator and it makes the code more readable. This patch replaces webob.Response with the decorator for the other APIs. In addition, this patch changes some orders of decorators for showing success code and expected error codes clearly. Even if applying this patch, some webob.Response() calls still exist under the path nova/api/openstack/compute/plugins/v3/ because these cases need to contain some information in a response header. Partially implements blueprint v2-on-v3-api Change-Id: I419819b8e55427979e8d82b972cd237952a5b06b
This commit is contained in:
parent
8d8aee74b1
commit
e73cb83f9e
|
@ -12,7 +12,6 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import webob
|
||||
from webob import exc
|
||||
|
||||
from nova.api.openstack import common
|
||||
|
@ -42,6 +41,7 @@ class AdminActionsController(wsgi.Controller):
|
|||
super(AdminActionsController, self).__init__(*args, **kwargs)
|
||||
self.compute_api = compute.API()
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((404, 409))
|
||||
@wsgi.action('resetNetwork')
|
||||
def _reset_network(self, req, id, body):
|
||||
|
@ -54,8 +54,8 @@ class AdminActionsController(wsgi.Controller):
|
|||
self.compute_api.reset_network(context, instance)
|
||||
except exception.InstanceIsLocked as e:
|
||||
raise exc.HTTPConflict(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((404, 409))
|
||||
@wsgi.action('injectNetworkInfo')
|
||||
def _inject_network_info(self, req, id, body):
|
||||
|
@ -68,8 +68,8 @@ class AdminActionsController(wsgi.Controller):
|
|||
self.compute_api.inject_network_info(context, instance)
|
||||
except exception.InstanceIsLocked as e:
|
||||
raise exc.HTTPConflict(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((400, 404))
|
||||
@wsgi.action('os-resetState')
|
||||
@validation.schema(reset_server_state.reset_state)
|
||||
|
@ -86,7 +86,6 @@ class AdminActionsController(wsgi.Controller):
|
|||
instance.vm_state = state
|
||||
instance.task_state = None
|
||||
instance.save(admin_state_reset=True)
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
|
||||
class AdminActions(extensions.V3APIExtensionBase):
|
||||
|
|
|
@ -21,6 +21,7 @@ from webob import exc
|
|||
from nova.api.openstack import common
|
||||
from nova.api.openstack.compute.schemas.v3 import attach_interfaces
|
||||
from nova.api.openstack import extensions
|
||||
from nova.api.openstack import wsgi
|
||||
from nova.api import validation
|
||||
from nova import compute
|
||||
from nova import exception
|
||||
|
@ -137,6 +138,7 @@ class InterfaceAttachmentController(object):
|
|||
|
||||
return self.show(req, server_id, vif['id'])
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((404, 409, 501))
|
||||
def delete(self, req, server_id, id):
|
||||
"""Detach an interface from an instance."""
|
||||
|
@ -160,8 +162,6 @@ class InterfaceAttachmentController(object):
|
|||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'detach_interface', server_id)
|
||||
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
def _items(self, req, server_id, entity_maker):
|
||||
"""Returns a list of attachments, transformed through entity_maker."""
|
||||
context = req.environ['nova.context']
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import webob
|
||||
from webob import exc
|
||||
|
||||
from nova.api.openstack import extensions
|
||||
|
@ -81,6 +80,7 @@ class ConsolesController(object):
|
|||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
return _translate_detail_keys(console)
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors(404)
|
||||
def delete(self, req, server_id, id):
|
||||
"""Deletes a console."""
|
||||
|
@ -90,7 +90,6 @@ class ConsolesController(object):
|
|||
int(id))
|
||||
except exception.ConsoleNotFound as e:
|
||||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
|
||||
class Consoles(extensions.V3APIExtensionBase):
|
||||
|
|
|
@ -33,6 +33,7 @@ class DeferredDeleteController(wsgi.Controller):
|
|||
super(DeferredDeleteController, self).__init__(*args, **kwargs)
|
||||
self.compute_api = compute.API()
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((404, 409, 403))
|
||||
@wsgi.action('restore')
|
||||
def _restore(self, req, id, body):
|
||||
|
@ -48,8 +49,8 @@ class DeferredDeleteController(wsgi.Controller):
|
|||
except exception.InstanceInvalidState as state_error:
|
||||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'restore', id)
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((404, 409))
|
||||
@wsgi.action('forceDelete')
|
||||
def _force_delete(self, req, id, body):
|
||||
|
@ -62,7 +63,6 @@ class DeferredDeleteController(wsgi.Controller):
|
|||
self.compute_api.force_delete(context, instance)
|
||||
except exception.InstanceIsLocked as e:
|
||||
raise webob.exc.HTTPConflict(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
|
||||
class DeferredDelete(extensions.V3APIExtensionBase):
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
# under the License.
|
||||
|
||||
"""The Extended Volumes API extension."""
|
||||
import webob
|
||||
from webob import exc
|
||||
|
||||
from nova.api.openstack import common
|
||||
|
@ -52,6 +51,7 @@ class ExtendedVolumesController(wsgi.Controller):
|
|||
key = "%s:volumes_attached" % ExtendedVolumes.alias
|
||||
server[key] = [{'id': volume_id} for volume_id in volume_ids]
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((400, 404, 409))
|
||||
@wsgi.action('swap_volume_attachment')
|
||||
@validation.schema(extended_volumes.swap_volume_attachment)
|
||||
|
@ -99,8 +99,6 @@ class ExtendedVolumesController(wsgi.Controller):
|
|||
msg = _("The volume was either invalid or not attached to the "
|
||||
"instance.")
|
||||
raise exc.HTTPNotFound(explanation=msg)
|
||||
else:
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.extends
|
||||
def show(self, req, resp_obj, id):
|
||||
|
|
|
@ -32,8 +32,12 @@ class FlavorManageController(wsgi.Controller):
|
|||
def __init__(self):
|
||||
super(FlavorManageController, self).__init__()
|
||||
|
||||
@wsgi.action("delete")
|
||||
# NOTE(oomichi): Return 202 for backwards compatibility but should be
|
||||
# 204 as this operation complete the deletion of aggregate resource and
|
||||
# return no response body.
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((404))
|
||||
@wsgi.action("delete")
|
||||
def _delete(self, req, id):
|
||||
context = req.environ['nova.context']
|
||||
authorize(context)
|
||||
|
@ -46,11 +50,6 @@ class FlavorManageController(wsgi.Controller):
|
|||
|
||||
flavors.destroy(flavor['name'])
|
||||
|
||||
# NOTE(oomichi): Return 202 for backwards compatibility but should be
|
||||
# 204 as this operation complete the deletion of aggregate resource and
|
||||
# return no response body.
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
# NOTE(oomichi): Return 200 for backwards compatibility but should be 201
|
||||
# as this operation complete the creation of flavor resource.
|
||||
@wsgi.action("create")
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import webob
|
||||
|
||||
from nova.api.openstack import common
|
||||
from nova.api.openstack import extensions
|
||||
from nova.api.openstack import wsgi
|
||||
|
@ -33,6 +31,7 @@ class LockServerController(wsgi.Controller):
|
|||
super(LockServerController, self).__init__(*args, **kwargs)
|
||||
self.compute_api = compute.API()
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors(404)
|
||||
@wsgi.action('lock')
|
||||
def _lock(self, req, id, body):
|
||||
|
@ -42,8 +41,8 @@ class LockServerController(wsgi.Controller):
|
|||
instance = common.get_instance(self.compute_api, context, id,
|
||||
want_objects=True)
|
||||
self.compute_api.lock(context, instance)
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors(404)
|
||||
@wsgi.action('unlock')
|
||||
def _unlock(self, req, id, body):
|
||||
|
@ -53,7 +52,6 @@ class LockServerController(wsgi.Controller):
|
|||
instance = common.get_instance(self.compute_api, context, id,
|
||||
want_objects=True)
|
||||
self.compute_api.unlock(context, instance)
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
|
||||
class LockServer(extensions.V3APIExtensionBase):
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
# under the License.
|
||||
|
||||
from oslo.utils import strutils
|
||||
import webob
|
||||
from webob import exc
|
||||
|
||||
from nova.api.openstack import common
|
||||
|
@ -38,6 +37,7 @@ class MigrateServerController(wsgi.Controller):
|
|||
super(MigrateServerController, self).__init__(*args, **kwargs)
|
||||
self.compute_api = compute.API()
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((400, 403, 404, 409))
|
||||
@wsgi.action('migrate')
|
||||
def _migrate(self, req, id, body):
|
||||
|
@ -61,8 +61,7 @@ class MigrateServerController(wsgi.Controller):
|
|||
except exception.NoValidHost as e:
|
||||
raise exc.HTTPBadRequest(explanation=e.format_message())
|
||||
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((400, 404, 409))
|
||||
@wsgi.action('os-migrateLive')
|
||||
@validation.schema(migrate_server.migrate_live)
|
||||
|
@ -102,7 +101,6 @@ class MigrateServerController(wsgi.Controller):
|
|||
except exception.InstanceInvalidState as state_error:
|
||||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'os-migrateLive', id)
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
|
||||
class MigrateServer(extensions.V3APIExtensionBase):
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
"""The multinic extension."""
|
||||
|
||||
import webob
|
||||
from webob import exc
|
||||
|
||||
from nova.api.openstack import common
|
||||
|
@ -36,6 +35,7 @@ class MultinicController(wsgi.Controller):
|
|||
super(MultinicController, self).__init__(*args, **kwargs)
|
||||
self.compute_api = compute.API()
|
||||
|
||||
@wsgi.response(202)
|
||||
@wsgi.action('addFixedIp')
|
||||
@extensions.expected_errors((400, 404))
|
||||
@validation.schema(multinic.add_fixed_ip)
|
||||
|
@ -52,8 +52,7 @@ class MultinicController(wsgi.Controller):
|
|||
except exception.NoMoreFixedIps as e:
|
||||
raise exc.HTTPBadRequest(explanation=e.format_message())
|
||||
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.response(202)
|
||||
@wsgi.action('removeFixedIp')
|
||||
@extensions.expected_errors((400, 404))
|
||||
@validation.schema(multinic.remove_fixed_ip)
|
||||
|
@ -71,8 +70,6 @@ class MultinicController(wsgi.Controller):
|
|||
except exception.FixedIpNotFoundForSpecificInstance as e:
|
||||
raise exc.HTTPBadRequest(explanation=e.format_message())
|
||||
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
|
||||
# Note: The class name is as it has to be for this to be loaded as an
|
||||
# extension--only first character capitalized.
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
# under the License.
|
||||
|
||||
import netaddr
|
||||
import webob
|
||||
from webob import exc
|
||||
|
||||
from nova.api.openstack import extensions
|
||||
|
@ -88,9 +87,9 @@ class NetworkController(wsgi.Controller):
|
|||
result = [network_dict(context, net_ref) for net_ref in networks]
|
||||
return {'networks': result}
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((404, 501))
|
||||
@wsgi.action("disassociate")
|
||||
@wsgi.response(202)
|
||||
def _disassociate_host_and_project(self, req, id, body):
|
||||
context = req.environ['nova.context']
|
||||
authorize(context)
|
||||
|
@ -117,6 +116,7 @@ class NetworkController(wsgi.Controller):
|
|||
raise exc.HTTPNotFound(explanation=msg)
|
||||
return {'network': network_dict(context, network)}
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((404, 409))
|
||||
def delete(self, req, id):
|
||||
context = req.environ['nova.context']
|
||||
|
@ -129,7 +129,6 @@ class NetworkController(wsgi.Controller):
|
|||
except exception.NetworkNotFound:
|
||||
msg = _("Network not found")
|
||||
raise exc.HTTPNotFound(explanation=msg)
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@extensions.expected_errors((400, 409, 501))
|
||||
def create(self, req, body):
|
||||
|
@ -171,8 +170,8 @@ class NetworkController(wsgi.Controller):
|
|||
raise exc.HTTPConflict(explanation=ex.format_message())
|
||||
return {"network": network_dict(context, network)}
|
||||
|
||||
@extensions.expected_errors((400, 409, 501))
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((400, 409, 501))
|
||||
def add(self, req, body):
|
||||
context = req.environ['nova.context']
|
||||
authorize(context)
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import webob
|
||||
from webob import exc
|
||||
|
||||
from nova.api.openstack import common
|
||||
|
@ -36,6 +35,7 @@ class PauseServerController(wsgi.Controller):
|
|||
super(PauseServerController, self).__init__(*args, **kwargs)
|
||||
self.compute_api = compute.API()
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((404, 409, 501))
|
||||
@wsgi.action('pause')
|
||||
def _pause(self, req, id, body):
|
||||
|
@ -56,8 +56,8 @@ class PauseServerController(wsgi.Controller):
|
|||
except NotImplementedError:
|
||||
msg = _("Virt driver does not implement pause function.")
|
||||
raise exc.HTTPNotImplemented(explanation=msg)
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((404, 409, 501))
|
||||
@wsgi.action('unpause')
|
||||
def _unpause(self, req, id, body):
|
||||
|
@ -78,7 +78,6 @@ class PauseServerController(wsgi.Controller):
|
|||
except NotImplementedError:
|
||||
msg = _("Virt driver does not implement pause function.")
|
||||
raise exc.HTTPNotImplemented(explanation=msg)
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
|
||||
class PauseServer(extensions.V3APIExtensionBase):
|
||||
|
|
|
@ -136,6 +136,7 @@ class ServerGroupController(wsgi.Controller):
|
|||
raise webob.exc.HTTPNotFound(explanation=e.format_message())
|
||||
return {'server_group': self._format_server_group(context, sg)}
|
||||
|
||||
@wsgi.response(204)
|
||||
@extensions.expected_errors(404)
|
||||
def delete(self, req, id):
|
||||
"""Delete an server group."""
|
||||
|
@ -167,8 +168,6 @@ class ServerGroupController(wsgi.Controller):
|
|||
if quotas:
|
||||
quotas.commit()
|
||||
|
||||
return webob.Response(status_int=204)
|
||||
|
||||
@extensions.expected_errors(())
|
||||
def index(self, req):
|
||||
"""Returns a list of server groups."""
|
||||
|
|
|
@ -453,8 +453,8 @@ class ServersController(wsgi.Controller):
|
|||
req.cache_db_instance(instance)
|
||||
return self._view_builder.show(req, instance)
|
||||
|
||||
@extensions.expected_errors((400, 403, 409, 413))
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((400, 403, 409, 413))
|
||||
@validation.schema(schema_server_create)
|
||||
def create(self, req, body):
|
||||
"""Creates a new server for a given user."""
|
||||
|
@ -700,8 +700,8 @@ class ServersController(wsgi.Controller):
|
|||
# NOTE(gmann): Returns 204 for backwards compatibility but should be 202
|
||||
# for representing async API as this API just accepts the request and
|
||||
# request hypervisor driver to complete the same in async mode.
|
||||
@extensions.expected_errors((400, 404, 409))
|
||||
@wsgi.response(204)
|
||||
@extensions.expected_errors((400, 404, 409))
|
||||
@wsgi.action('confirmResize')
|
||||
def _action_confirm_resize(self, req, id, body):
|
||||
context = req.environ['nova.context']
|
||||
|
@ -717,8 +717,8 @@ class ServersController(wsgi.Controller):
|
|||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'confirmResize', id)
|
||||
|
||||
@extensions.expected_errors((400, 404, 409))
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((400, 404, 409))
|
||||
@wsgi.action('revertResize')
|
||||
def _action_revert_resize(self, req, id, body):
|
||||
context = req.environ['nova.context']
|
||||
|
@ -736,10 +736,9 @@ class ServersController(wsgi.Controller):
|
|||
except exception.InstanceInvalidState as state_error:
|
||||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'revertResize', id)
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@extensions.expected_errors((400, 404, 409))
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((400, 404, 409))
|
||||
@wsgi.action('reboot')
|
||||
def _action_reboot(self, req, id, body):
|
||||
if 'reboot' in body and 'type' in body['reboot']:
|
||||
|
@ -768,7 +767,6 @@ class ServersController(wsgi.Controller):
|
|||
except exception.InstanceInvalidState as state_error:
|
||||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'reboot', id)
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
def _resize(self, req, instance_id, flavor_id, **kwargs):
|
||||
"""Begin the resize process with given instance/flavor."""
|
||||
|
@ -810,10 +808,8 @@ class ServersController(wsgi.Controller):
|
|||
msg = _("Invalid instance image.")
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@extensions.expected_errors((404, 409))
|
||||
@wsgi.response(204)
|
||||
@extensions.expected_errors((404, 409))
|
||||
def delete(self, req, id):
|
||||
"""Destroys a server."""
|
||||
try:
|
||||
|
@ -859,8 +855,8 @@ class ServersController(wsgi.Controller):
|
|||
flavor_ref = data['server']['flavorRef']
|
||||
return common.get_id_from_href(flavor_ref)
|
||||
|
||||
@extensions.expected_errors((400, 401, 403, 404, 409))
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((400, 401, 403, 404, 409))
|
||||
@wsgi.action('resize')
|
||||
def _action_resize(self, req, id, body):
|
||||
"""Resizes a given instance to the flavor size requested."""
|
||||
|
@ -880,10 +876,10 @@ class ServersController(wsgi.Controller):
|
|||
self.resize_extension_manager.map(self._resize_extension_point,
|
||||
resize_dict, resize_kwargs)
|
||||
|
||||
return self._resize(req, id, flavor_ref, **resize_kwargs)
|
||||
self._resize(req, id, flavor_ref, **resize_kwargs)
|
||||
|
||||
@extensions.expected_errors((400, 403, 404, 409, 413))
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((400, 403, 404, 409, 413))
|
||||
@wsgi.action('rebuild')
|
||||
@validation.schema(schema_server_rebuild)
|
||||
def _action_rebuild(self, req, id, body):
|
||||
|
@ -958,8 +954,8 @@ class ServersController(wsgi.Controller):
|
|||
robj = wsgi.ResponseObject(view)
|
||||
return self._add_location(robj)
|
||||
|
||||
@extensions.expected_errors((400, 403, 404, 409))
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((400, 403, 404, 409))
|
||||
@wsgi.action('createImage')
|
||||
@common.check_snapshots_enabled
|
||||
def _action_create_image(self, req, id, body):
|
||||
|
@ -1045,6 +1041,7 @@ class ServersController(wsgi.Controller):
|
|||
except exception.InstanceNotFound as e:
|
||||
raise webob.exc.HTTPNotFound(explanation=e.format_message())
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((404, 409))
|
||||
@wsgi.action('os-start')
|
||||
def _start_server(self, req, id, body):
|
||||
|
@ -1058,8 +1055,8 @@ class ServersController(wsgi.Controller):
|
|||
except (exception.InstanceNotReady, exception.InstanceIsLocked,
|
||||
exception.InstanceInvalidState) as e:
|
||||
raise webob.exc.HTTPConflict(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((404, 409))
|
||||
@wsgi.action('os-stop')
|
||||
def _stop_server(self, req, id, body):
|
||||
|
@ -1073,7 +1070,6 @@ class ServersController(wsgi.Controller):
|
|||
except (exception.InstanceNotReady, exception.InstanceIsLocked,
|
||||
exception.InstanceInvalidState) as e:
|
||||
raise webob.exc.HTTPConflict(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
|
||||
def remove_invalid_options(context, search_options, allowed_search_options):
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
"""The shelved mode extension."""
|
||||
|
||||
import webob
|
||||
from webob import exc
|
||||
|
||||
from nova.api.openstack import common
|
||||
|
@ -36,6 +35,7 @@ class ShelveController(wsgi.Controller):
|
|||
super(ShelveController, self).__init__(*args, **kwargs)
|
||||
self.compute_api = compute.API()
|
||||
|
||||
@wsgi.response(202)
|
||||
@exts.expected_errors((404, 409))
|
||||
@wsgi.action('shelve')
|
||||
def _shelve(self, req, id, body):
|
||||
|
@ -53,8 +53,7 @@ class ShelveController(wsgi.Controller):
|
|||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'shelve', id)
|
||||
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.response(202)
|
||||
@exts.expected_errors((404, 409))
|
||||
@wsgi.action('shelveOffload')
|
||||
def _shelve_offload(self, req, id, body):
|
||||
|
@ -73,8 +72,7 @@ class ShelveController(wsgi.Controller):
|
|||
'shelveOffload',
|
||||
id)
|
||||
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.response(202)
|
||||
@exts.expected_errors((404, 409))
|
||||
@wsgi.action('unshelve')
|
||||
def _unshelve(self, req, id, body):
|
||||
|
@ -91,7 +89,6 @@ class ShelveController(wsgi.Controller):
|
|||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'unshelve',
|
||||
id)
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
|
||||
class Shelve(exts.V3APIExtensionBase):
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import webob
|
||||
from webob import exc
|
||||
|
||||
from nova.api.openstack import common
|
||||
|
@ -36,6 +35,7 @@ class SuspendServerController(wsgi.Controller):
|
|||
super(SuspendServerController, self).__init__(*args, **kwargs)
|
||||
self.compute_api = compute.API()
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((404, 409))
|
||||
@wsgi.action('suspend')
|
||||
def _suspend(self, req, id, body):
|
||||
|
@ -51,8 +51,8 @@ class SuspendServerController(wsgi.Controller):
|
|||
except exception.InstanceInvalidState as state_error:
|
||||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'suspend', id)
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors((404, 409))
|
||||
@wsgi.action('resume')
|
||||
def _resume(self, req, id, body):
|
||||
|
@ -68,7 +68,6 @@ class SuspendServerController(wsgi.Controller):
|
|||
except exception.InstanceInvalidState as state_error:
|
||||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
||||
'resume', id)
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
|
||||
class SuspendServer(extensions.V3APIExtensionBase):
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
"""The volumes extension."""
|
||||
|
||||
from oslo.utils import strutils
|
||||
import webob
|
||||
from webob import exc
|
||||
|
||||
from nova.api.openstack import common
|
||||
|
@ -98,6 +97,7 @@ class VolumeController(wsgi.Controller):
|
|||
|
||||
return {'volume': _translate_volume_detail_view(context, vol)}
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors(404)
|
||||
def delete(self, req, id):
|
||||
"""Delete a volume."""
|
||||
|
@ -110,7 +110,6 @@ class VolumeController(wsgi.Controller):
|
|||
self.volume_api.delete(context, id)
|
||||
except exception.NotFound as e:
|
||||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@extensions.expected_errors(())
|
||||
def index(self, req):
|
||||
|
@ -257,6 +256,7 @@ class SnapshotController(wsgi.Controller):
|
|||
|
||||
return {'snapshot': _translate_snapshot_detail_view(context, vol)}
|
||||
|
||||
@wsgi.response(202)
|
||||
@extensions.expected_errors(404)
|
||||
def delete(self, req, id):
|
||||
"""Delete a snapshot."""
|
||||
|
@ -269,7 +269,6 @@ class SnapshotController(wsgi.Controller):
|
|||
self.volume_api.delete_snapshot(context, id)
|
||||
except exception.NotFound as e:
|
||||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@extensions.expected_errors(())
|
||||
def index(self, req):
|
||||
|
|
|
@ -702,8 +702,14 @@ class ResetStateTestsV21(test.NoDBTestCase):
|
|||
body = {"os-resetState": {"state": "active"}}
|
||||
result = self.admin_api._reset_state(self.request, self.uuid,
|
||||
body=body)
|
||||
|
||||
self.assertEqual(result.status_int, 202)
|
||||
# NOTE: on v2.1, http status code is set as wsgi_code of API
|
||||
# method instead of status_int in a response object.
|
||||
if isinstance(self.admin_api,
|
||||
admin_actions_v21.AdminActionsController):
|
||||
status_int = self.admin_api._reset_state.wsgi_code
|
||||
else:
|
||||
status_int = result.status_int
|
||||
self.assertEqual(202, status_int)
|
||||
|
||||
def test_reset_error(self):
|
||||
self._setup_mock(dict(vm_state=vm_states.ERROR,
|
||||
|
@ -712,8 +718,14 @@ class ResetStateTestsV21(test.NoDBTestCase):
|
|||
body = {"os-resetState": {"state": "error"}}
|
||||
result = self.admin_api._reset_state(self.request, self.uuid,
|
||||
body=body)
|
||||
|
||||
self.assertEqual(result.status_int, 202)
|
||||
# NOTE: on v2.1, http status code is set as wsgi_code of API
|
||||
# method instead of status_int in a response object.
|
||||
if isinstance(self.admin_api,
|
||||
admin_actions_v21.AdminActionsController):
|
||||
status_int = self.admin_api._reset_state.wsgi_code
|
||||
else:
|
||||
status_int = result.status_int
|
||||
self.assertEqual(202, status_int)
|
||||
|
||||
|
||||
class ResetStateTestsV2(ResetStateTestsV21):
|
||||
|
|
|
@ -221,7 +221,14 @@ class InterfaceAttachTestsV21(test.NoDBTestCase):
|
|||
req.environ['nova.context'] = self.context
|
||||
|
||||
result = self.attachments.delete(req, FAKE_UUID1, FAKE_PORT_ID1)
|
||||
self.assertEqual('202 Accepted', result.status)
|
||||
# NOTE: on v2.1, http status code is set as wsgi_code of API
|
||||
# method instead of status_int in a response object.
|
||||
if isinstance(self.attachments,
|
||||
attach_interfaces_v3.InterfaceAttachmentController):
|
||||
status_int = self.attachments.delete.wsgi_code
|
||||
else:
|
||||
status_int = result.status_int
|
||||
self.assertEqual(202, status_int)
|
||||
|
||||
def test_detach_interface_instance_locked(self):
|
||||
def fake_detach_interface_from_locked_server(self, context,
|
||||
|
|
|
@ -55,7 +55,13 @@ class DeferredDeleteExtensionTestV21(test.NoDBTestCase):
|
|||
self.mox.ReplayAll()
|
||||
res = self.extension._force_delete(self.fake_req, self.fake_uuid,
|
||||
self.fake_input_dict)
|
||||
self.assertEqual(res.status_int, 202)
|
||||
# NOTE: on v2.1, http status code is set as wsgi_code of API
|
||||
# method instead of status_int in a response object.
|
||||
if isinstance(self.extension, dd_v21.DeferredDeleteController):
|
||||
status_int = self.extension._force_delete.wsgi_code
|
||||
else:
|
||||
status_int = res.status_int
|
||||
self.assertEqual(202, status_int)
|
||||
|
||||
def test_force_delete_instance_not_found(self):
|
||||
self.mox.StubOutWithMock(compute_api.API, 'get')
|
||||
|
@ -97,7 +103,13 @@ class DeferredDeleteExtensionTestV21(test.NoDBTestCase):
|
|||
self.mox.ReplayAll()
|
||||
res = self.extension._restore(self.fake_req, self.fake_uuid,
|
||||
self.fake_input_dict)
|
||||
self.assertEqual(res.status_int, 202)
|
||||
# NOTE: on v2.1, http status code is set as wsgi_code of API
|
||||
# method instead of status_int in a response object.
|
||||
if isinstance(self.extension, dd_v21.DeferredDeleteController):
|
||||
status_int = self.extension._restore.wsgi_code
|
||||
else:
|
||||
status_int = res.status_int
|
||||
self.assertEqual(202, status_int)
|
||||
|
||||
def test_restore_instance_not_found(self):
|
||||
self.mox.StubOutWithMock(compute_api.API, 'get')
|
||||
|
|
|
@ -130,7 +130,15 @@ class FlavorManageTestV21(test.NoDBTestCase):
|
|||
def test_delete(self):
|
||||
req = fakes.HTTPRequest.blank(self.base_url + '/1234')
|
||||
res = self.controller._delete(req, 1234)
|
||||
self.assertEqual(res.status_int, 202)
|
||||
|
||||
# NOTE: on v2.1, http status code is set as wsgi_code of API
|
||||
# method instead of status_int in a response object.
|
||||
if isinstance(self.controller,
|
||||
flavormanage_v21.FlavorManageController):
|
||||
status_int = self.controller._delete.wsgi_code
|
||||
else:
|
||||
status_int = res.status_int
|
||||
self.assertEqual(202, status_int)
|
||||
|
||||
# subsequent delete should fail
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
|
|
|
@ -163,7 +163,14 @@ class ServerGroupQuotasTestV21(test.TestCase):
|
|||
req = fakes.HTTPRequest.blank('/v2/fake/os-server-groups/123')
|
||||
resp = self.controller.delete(req, '123')
|
||||
self.assertTrue(self.called)
|
||||
self.assertEqual(resp.status_int, 204)
|
||||
|
||||
# NOTE: on v2.1, http status code is set as wsgi_code of API
|
||||
# method instead of status_int in a response object.
|
||||
if isinstance(self.controller, sg_v3.ServerGroupController):
|
||||
status_int = self.controller.delete.wsgi_code
|
||||
else:
|
||||
status_int = resp.status_int
|
||||
self.assertEqual(204, status_int)
|
||||
|
||||
|
||||
class ServerGroupQuotasTestV2(ServerGroupQuotasTestV21):
|
||||
|
|
|
@ -354,7 +354,14 @@ class ServerGroupTestV21(test.TestCase):
|
|||
'/os-server-groups/123')
|
||||
resp = self.controller.delete(req, '123')
|
||||
self.assertTrue(self.called)
|
||||
self.assertEqual(resp.status_int, 204)
|
||||
|
||||
# NOTE: on v2.1, http status code is set as wsgi_code of API
|
||||
# method instead of status_int in a response object.
|
||||
if isinstance(self.controller, sg_v3.ServerGroupController):
|
||||
status_int = self.controller.delete.wsgi_code
|
||||
else:
|
||||
status_int = resp.status_int
|
||||
self.assertEqual(204, status_int)
|
||||
|
||||
def test_delete_non_existing_server_group(self):
|
||||
req = fakes.HTTPRequest.blank(self._get_url() +
|
||||
|
|
|
@ -1006,7 +1006,14 @@ class DeleteSnapshotTestCaseV21(test.TestCase):
|
|||
|
||||
self.req.method = 'DELETE'
|
||||
result = self.controller.delete(self.req, result['snapshot']['id'])
|
||||
self.assertEqual(result.status_int, 202)
|
||||
|
||||
# NOTE: on v2.1, http status code is set as wsgi_code of API
|
||||
# method instead of status_int in a response object.
|
||||
if isinstance(self.controller, volumes_v3.SnapshotController):
|
||||
status_int = self.controller.delete.wsgi_code
|
||||
else:
|
||||
status_int = result.status_int
|
||||
self.assertEqual(202, status_int)
|
||||
|
||||
def test_delete_snapshot_not_exists(self):
|
||||
def fake_delete_snapshot_not_exist(self, context, snapshot_id):
|
||||
|
|
|
@ -327,8 +327,9 @@ class ExtendedVolumesTest(test.TestCase):
|
|||
|
||||
def test_swap_volume(self):
|
||||
self.stubs.Set(compute.api.API, 'swap_volume', fake_swap_volume)
|
||||
result = self._test_swap()
|
||||
self.assertEqual('202 Accepted', result.status)
|
||||
# Check any exceptions don't happen and status code
|
||||
self._test_swap()
|
||||
self.assertEqual(202, self.Controller.swap.wsgi_code)
|
||||
|
||||
def test_swap_volume_for_locked_server(self):
|
||||
def fake_swap_volume_for_locked_server(self, context, instance,
|
||||
|
|
Loading…
Reference in New Issue