Deprecate volumes related APIs

This patch deprecates volumes related proxy APIs. All of those APIs
will return 404 after new Microversion.

The deprecated API endpoints are
'/os-volumes'
'/os-snapshots'

The sub-resource 'os-volume_attachments' of servers will be kept.

This patch doesn't bump the max api version, due to the patch separation.
The max api version will bump in the last patch.

Partially implements blueprint deprecate-api-proxies

Change-Id: I75bba7b3d6c25ae9f9a3b19fe7a664daaab3fb1c
This commit is contained in:
He Jie Xu 2016-06-24 15:11:48 +08:00
parent 53fffbadff
commit 83bd45bbcf
3 changed files with 56 additions and 3 deletions

View File

@ -19,6 +19,8 @@ from oslo_utils import strutils
from webob import exc
from nova.api.openstack import api_version_request
from nova.api.openstack.api_version_request \
import MAX_PROXY_API_SUPPORT_VERSION
from nova.api.openstack import common
from nova.api.openstack.compute.schemas import volumes as volumes_schema
from nova.api.openstack import extensions
@ -100,6 +102,7 @@ class VolumeController(wsgi.Controller):
self.volume_api = volume.API()
super(VolumeController, self).__init__()
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
@extensions.expected_errors(404)
def show(self, req, id):
"""Return data about the given volume."""
@ -113,6 +116,7 @@ class VolumeController(wsgi.Controller):
return {'volume': _translate_volume_detail_view(context, vol)}
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
@wsgi.response(202)
@extensions.expected_errors(404)
def delete(self, req, id):
@ -125,11 +129,13 @@ class VolumeController(wsgi.Controller):
except exception.VolumeNotFound as e:
raise exc.HTTPNotFound(explanation=e.format_message())
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
@extensions.expected_errors(())
def index(self, req):
"""Returns a summary list of volumes."""
return self._items(req, entity_maker=_translate_volume_summary_view)
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
@extensions.expected_errors(())
def detail(self, req):
"""Returns a detailed list of volumes."""
@ -145,6 +151,7 @@ class VolumeController(wsgi.Controller):
res = [entity_maker(context, vol) for vol in limited_list]
return {'volumes': res}
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
@extensions.expected_errors((400, 403, 404))
@validation.schema(volumes_schema.create)
def create(self, req, body):
@ -214,7 +221,7 @@ def _translate_attachment_summary_view(volume_id, instance_uuid, mountpoint):
"""Maps keys for attachment summary view."""
d = {}
# NOTE(justinsb): We use the volume id as the id of the attachment object
# NOTE(justinsb): We use the volume id as he id of the attachment object
d['id'] = volume_id
d['volumeId'] = volume_id
@ -504,6 +511,7 @@ class SnapshotController(wsgi.Controller):
self.volume_api = volume.API()
super(SnapshotController, self).__init__()
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
@extensions.expected_errors(404)
def show(self, req, id):
"""Return data about the given snapshot."""
@ -517,6 +525,7 @@ class SnapshotController(wsgi.Controller):
return {'snapshot': _translate_snapshot_detail_view(context, vol)}
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
@wsgi.response(202)
@extensions.expected_errors(404)
def delete(self, req, id):
@ -529,11 +538,13 @@ class SnapshotController(wsgi.Controller):
except exception.SnapshotNotFound as e:
raise exc.HTTPNotFound(explanation=e.format_message())
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
@extensions.expected_errors(())
def index(self, req):
"""Returns a summary list of snapshots."""
return self._items(req, entity_maker=_translate_snapshot_summary_view)
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
@extensions.expected_errors(())
def detail(self, req):
"""Returns a detailed list of snapshots."""
@ -549,6 +560,7 @@ class SnapshotController(wsgi.Controller):
res = [entity_maker(context, snapshot) for snapshot in limited_list]
return {'snapshots': res}
@wsgi.Controller.api_version("2.1", MAX_PROXY_API_SUPPORT_VERSION)
@extensions.expected_errors((400, 403))
@validation.schema(volumes_schema.snapshot_create)
def create(self, req, body):

View File

@ -73,12 +73,13 @@ class SnapshotApiTestV21(test.NoDBTestCase):
def test_snapshot_delete(self):
snapshot_id = '123'
result = self.controller.delete(self.req, snapshot_id)
delete = self.controller.delete
result = delete(self.req, snapshot_id)
# 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_v21.SnapshotController):
status_int = self.controller.delete.wsgi_code
status_int = delete.wsgi_code
else:
status_int = result.status_int
self.assertEqual(202, status_int)
@ -117,3 +118,23 @@ class SnapshotApiTestV21(test.NoDBTestCase):
self.assertIn('snapshots', resp_dict)
resp_snapshots = resp_dict['snapshots']
self.assertEqual(3, len(resp_snapshots))
class TestSnapshotAPIDeprecation(test.NoDBTestCase):
def setUp(self):
super(TestSnapshotAPIDeprecation, self).setUp()
self.controller = volumes_v21.SnapshotController()
self.req = fakes.HTTPRequest.blank('', version='2.36')
def test_all_apis_return_not_found(self):
self.assertRaises(exception.VersionNotFoundForAPIMethod,
self.controller.show, self.req, fakes.FAKE_UUID)
self.assertRaises(exception.VersionNotFoundForAPIMethod,
self.controller.delete, self.req, fakes.FAKE_UUID)
self.assertRaises(exception.VersionNotFoundForAPIMethod,
self.controller.index, self.req)
self.assertRaises(exception.VersionNotFoundForAPIMethod,
self.controller.create, self.req, {})
self.assertRaises(exception.VersionNotFoundForAPIMethod,
self.controller.detail, self.req)

View File

@ -979,3 +979,23 @@ class TestVolumeAttachPolicyEnforcementV21(test.NoDBTestCase):
rule_name: "project:non_fake"}
self._common_policy_check(rules, rule_name, self.controller.delete,
self.req, FAKE_UUID, FAKE_UUID_A)
class TestVolumesAPIDeprecation(test.NoDBTestCase):
def setUp(self):
super(TestVolumesAPIDeprecation, self).setUp()
self.controller = volumes_v21.VolumeController()
self.req = fakes.HTTPRequest.blank('', version='2.36')
def test_all_apis_return_not_found(self):
self.assertRaises(exception.VersionNotFoundForAPIMethod,
self.controller.show, self.req, fakes.FAKE_UUID)
self.assertRaises(exception.VersionNotFoundForAPIMethod,
self.controller.delete, self.req, fakes.FAKE_UUID)
self.assertRaises(exception.VersionNotFoundForAPIMethod,
self.controller.index, self.req)
self.assertRaises(exception.VersionNotFoundForAPIMethod,
self.controller.create, self.req, {})
self.assertRaises(exception.VersionNotFoundForAPIMethod,
self.controller.detail, self.req)