From e05b261af7dcd24096b229860df65dff1d385910 Mon Sep 17 00:00:00 2001 From: Brian Rosmaita Date: Wed, 19 May 2021 14:57:17 -0400 Subject: [PATCH] Remove Block Storage API v2 In this patch: - adjusted VersionsController to return only v3 - removed cinder.api.v2.router - adjustments to cinder.tests.unit.api.contrib to use /v3 only - moved cinder.api.v2.snapshot_metadata (and tests) to cinder.api.v3 - moved cinder.api.v2.types (and view, tests) to cinder.api.v3 - updated versions response in api-ref - removed unnecessary config option - updated various sample config files - removed experimental tempest-cinder-v2-api job - updated some docs - updated non-voting rally job config Some cinder.api.v2 modules are left because the v3 classes depend on them, but with the v2 router removed, these are unreachable via the /v2 path. Depends-on: https://review.opendev.org/c/openstack/rally-openstack/+/794891 (changes rally to use Block Storage API v3) Depends-on: https://review.opendev.org/c/openstack/requirements/+/794894 (corrects regression in upper-constraint on Sphinx) Change-Id: I2093d77db9beec7543c7524d2cd273e79dd5fd5d --- .zuul.yaml | 2 - .../versions/version-show-response.json | 2 +- .../samples/versions/versions-response.json | 26 +-- cinder/api/__init__.py | 15 +- cinder/api/contrib/admin_actions.py | 2 +- cinder/api/contrib/backups.py | 2 +- cinder/api/contrib/volume_actions.py | 2 +- cinder/api/contrib/volume_manage.py | 2 +- cinder/api/microversions.py | 2 - cinder/api/openstack/api_version_request.py | 8 +- cinder/api/openstack/wsgi.py | 18 +- cinder/api/v2/router.py | 93 ---------- cinder/api/v2/volumes.py | 11 +- cinder/api/v3/router.py | 4 +- cinder/api/{v2 => v3}/snapshot_metadata.py | 0 cinder/api/{v2 => v3}/types.py | 2 +- cinder/api/{v2 => v3}/views/types.py | 0 cinder/api/v3/volumes.py | 10 +- cinder/api/versions.py | 29 +--- cinder/common/config.py | 8 +- .../versions/versions-response.json.tpl | 24 --- .../unit/api/contrib/test_admin_actions.py | 53 +++--- cinder/tests/unit/api/contrib/test_backups.py | 163 +++++++++--------- .../unit/api/contrib/test_cgsnapshots.py | 30 ++-- .../api/contrib/test_consistencygroups.py | 130 +++++++------- .../test_extended_snapshot_attributes.py | 4 +- .../unit/api/contrib/test_qos_specs_manage.py | 106 ++++++------ .../unit/api/contrib/test_scheduler_hints.py | 22 +-- .../unit/api/contrib/test_scheduler_stats.py | 6 +- .../tests/unit/api/contrib/test_services.py | 18 +- .../unit/api/contrib/test_snapshot_actions.py | 12 +- .../unit/api/contrib/test_snapshot_manage.py | 8 +- .../api/contrib/test_snapshot_unmanage.py | 6 +- .../api/contrib/test_types_extra_specs.py | 10 +- .../unit/api/contrib/test_types_manage.py | 66 +++---- .../unit/api/contrib/test_volume_actions.py | 116 ++++++------- .../test_volume_encryption_metadata.py | 22 +-- .../api/contrib/test_volume_host_attribute.py | 14 +- .../api/contrib/test_volume_image_metadata.py | 32 ++-- .../unit/api/contrib/test_volume_manage.py | 47 +---- .../test_volume_migration_status_attribute.py | 14 +- .../contrib/test_volume_tenant_attribute.py | 16 +- .../unit/api/contrib/test_volume_transfer.py | 50 +++--- .../api/contrib/test_volume_type_access.py | 58 +++---- .../contrib/test_volume_type_encryption.py | 32 ++-- .../unit/api/contrib/test_volume_unmanage.py | 6 +- cinder/tests/unit/api/fakes.py | 12 +- cinder/tests/unit/api/test_versions.py | 60 ++----- cinder/tests/unit/api/v3/fakes.py | 44 +++++ cinder/tests/unit/api/v3/test_backups.py | 2 +- .../api/{v2 => v3}/test_snapshot_metadata.py | 18 +- cinder/tests/unit/api/v3/test_types.py | 2 +- .../test_types.py => v3/test_types_orig.py} | 54 +++--- contrib/block-box/etc/api-paste.ini | 10 -- .../admin/blockstorage-get-capabilities.rst | 2 +- .../drivers/dell-emc-unity-driver.rst | 2 +- .../drivers/dell-emc-vnx-driver.rst | 2 +- .../block-storage/samples/api-paste.ini.inc | 10 -- .../contributor/addmethod.openstackapi.rst | 2 +- .../install/cinder-controller-install-obs.rst | 80 +-------- .../install/cinder-controller-install-rdo.rst | 78 +-------- .../cinder-controller-install-ubuntu.rst | 80 +-------- etc/cinder/api-paste.ini | 10 -- rally-jobs/cinder.yaml | 90 +++++----- .../notes/remove-api-v2-dadd877ee5457f79.yaml | 14 ++ 65 files changed, 720 insertions(+), 1155 deletions(-) delete mode 100644 cinder/api/v2/router.py rename cinder/api/{v2 => v3}/snapshot_metadata.py (100%) rename cinder/api/{v2 => v3}/types.py (98%) rename cinder/api/{v2 => v3}/views/types.py (100%) rename cinder/tests/unit/api/{v2 => v3}/test_snapshot_metadata.py (98%) rename cinder/tests/unit/api/{v2/test_types.py => v3/test_types_orig.py} (92%) create mode 100644 releasenotes/notes/remove-api-v2-dadd877ee5457f79.yaml diff --git a/.zuul.yaml b/.zuul.yaml index 76254854ba5..f11ad821102 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -91,8 +91,6 @@ irrelevant-files: *gate-irrelevant-files experimental: jobs: - - tempest-cinder-v2-api: - irrelevant-files: *gate-irrelevant-files - legacy-tempest-dsvm-multibackend-matrix: irrelevant-files: *gate-irrelevant-files - cinder-grenade-mn-sub-volschbak: diff --git a/api-ref/source/v3/samples/versions/version-show-response.json b/api-ref/source/v3/samples/versions/version-show-response.json index df31cb2f2b5..5e34efae7c3 100644 --- a/api-ref/source/v3/samples/versions/version-show-response.json +++ b/api-ref/source/v3/samples/versions/version-show-response.json @@ -21,7 +21,7 @@ ], "min_version": "3.0", "status": "CURRENT", - "updated": "2021-02-03T00:00:00Z", + "updated": "2021-05-30T00:00:00Z", "version": "3.64" } ] diff --git a/api-ref/source/v3/samples/versions/versions-response.json b/api-ref/source/v3/samples/versions/versions-response.json index b1c96e54281..529ca5d2140 100644 --- a/api-ref/source/v3/samples/versions/versions-response.json +++ b/api-ref/source/v3/samples/versions/versions-response.json @@ -1,29 +1,5 @@ { "versions": [ - { - "id": "v2.0", - "links": [ - { - "href": "https://docs.openstack.org/", - "rel": "describedby", - "type": "text/html" - }, - { - "href": "http://127.0.0.1:45697/v2/", - "rel": "self" - } - ], - "media-types": [ - { - "base": "application/json", - "type": "application/vnd.openstack.volume+json;version=2" - } - ], - "min_version": "", - "status": "DEPRECATED", - "updated": "2017-02-25T12:00:00Z", - "version": "" - }, { "id": "v3.0", "links": [ @@ -45,7 +21,7 @@ ], "min_version": "3.0", "status": "CURRENT", - "updated": "2021-02-03T00:00:00Z", + "updated": "2021-05-30T00:00:00Z", "version": "3.64" } ] diff --git a/cinder/api/__init__.py b/cinder/api/__init__.py index 7351dfadf44..90692a1d491 100644 --- a/cinder/api/__init__.py +++ b/cinder/api/__init__.py @@ -29,15 +29,16 @@ def root_app_factory(loader, global_conf, **local_conf): # to check for and remove any legacy references to the v1 API if '/v1' in local_conf: LOG.warning('The v1 API has been removed and is no longer ' - 'available. Client applications should now be ' - 'moving to v3. Ensure enable_v3_api=true in your ' + 'available. Client applications should be ' + 'using v3. Ensure enable_v3_api=true in your ' 'cinder.conf file.') del local_conf['/v1'] - if CONF.enable_v2_api: - LOG.warning('The v2 API is deprecated and is not under active ' - 'development. You should set enable_v2_api=false ' - 'and enable_v3_api=true in your cinder.conf file.') - else: + if '/v2' in local_conf: + LOG.warning('The v2 API has been removed and is no longer available. ' + 'Client applications must now use the v3 API only. ' + 'The \'enable_v2_api\' option has been removed and is ' + 'ignored in the cinder.conf file.') del local_conf['/v2'] + return paste.urlmap.urlmap_factory(loader, global_conf, **local_conf) diff --git a/cinder/api/contrib/admin_actions.py b/cinder/api/contrib/admin_actions.py index ffb7e624d97..37beb31e6b6 100644 --- a/cinder/api/contrib/admin_actions.py +++ b/cinder/api/contrib/admin_actions.py @@ -202,7 +202,7 @@ class VolumeAdminController(AdminController): @wsgi.response(HTTPStatus.ACCEPTED) @wsgi.action('os-migrate_volume') - @validation.schema(admin_actions.migrate_volume, mv.V2_BASE_VERSION, + @validation.schema(admin_actions.migrate_volume, mv.BASE_VERSION, mv.get_prior_version(mv.VOLUME_MIGRATE_CLUSTER)) @validation.schema(admin_actions.migrate_volume_v316, mv.VOLUME_MIGRATE_CLUSTER) diff --git a/cinder/api/contrib/backups.py b/cinder/api/contrib/backups.py index 2951a1e0adc..baba04df021 100644 --- a/cinder/api/contrib/backups.py +++ b/cinder/api/contrib/backups.py @@ -145,7 +145,7 @@ class BackupsController(wsgi.Controller): # immediately # - maybe also do validation of swift container name @wsgi.response(HTTPStatus.ACCEPTED) - @validation.schema(backup.create, mv.V2_BASE_VERSION, + @validation.schema(backup.create, mv.BASE_VERSION, mv.get_prior_version(mv.BACKUP_METADATA)) @validation.schema(backup.create_backup_v343, mv.BACKUP_METADATA, mv.get_prior_version(mv.BACKUP_AZ)) diff --git a/cinder/api/contrib/volume_actions.py b/cinder/api/contrib/volume_actions.py index a9d578115f2..e1389e6b73a 100644 --- a/cinder/api/contrib/volume_actions.py +++ b/cinder/api/contrib/volume_actions.py @@ -192,7 +192,7 @@ class VolumeActionsController(wsgi.Controller): @wsgi.response(HTTPStatus.ACCEPTED) @wsgi.action('os-volume_upload_image') - @validation.schema(volume_action.volume_upload_image, mv.V2_BASE_VERSION, + @validation.schema(volume_action.volume_upload_image, mv.BASE_VERSION, mv.get_prior_version(mv.UPLOAD_IMAGE_PARAMS)) @validation.schema(volume_action.volume_upload_image_v31, mv.UPLOAD_IMAGE_PARAMS) diff --git a/cinder/api/contrib/volume_manage.py b/cinder/api/contrib/volume_manage.py index 959654a7411..02b4ce17fca 100644 --- a/cinder/api/contrib/volume_manage.py +++ b/cinder/api/contrib/volume_manage.py @@ -46,7 +46,7 @@ class VolumeManageController(wsgi.Controller): self._list_manageable_view = list_manageable_view.ViewBuilder() @wsgi.response(HTTPStatus.ACCEPTED) - @validation.schema(volume_manage.volume_manage_create, mv.V2_BASE_VERSION, + @validation.schema(volume_manage.volume_manage_create, mv.BASE_VERSION, mv.get_prior_version(mv.VOLUME_MIGRATE_CLUSTER)) @validation.schema(volume_manage.volume_manage_create_v316, mv.VOLUME_MIGRATE_CLUSTER) diff --git a/cinder/api/microversions.py b/cinder/api/microversions.py index e8605c691b5..e72c76c07a0 100644 --- a/cinder/api/microversions.py +++ b/cinder/api/microversions.py @@ -37,8 +37,6 @@ from cinder import exception # Add new constants here for each new microversion. -V2_BASE_VERSION = '2.0' - BASE_VERSION = '3.0' UPLOAD_IMAGE_PARAMS = '3.1' diff --git a/cinder/api/openstack/api_version_request.py b/cinder/api/openstack/api_version_request.py index bde0205d45e..b6597346de1 100644 --- a/cinder/api/openstack/api_version_request.py +++ b/cinder/api/openstack/api_version_request.py @@ -153,11 +153,9 @@ REST_API_VERSION_HISTORY = """ # The minimum and maximum versions of the API supported # The default api version request is defined to be the # minimum version of the API supported. -# Explicitly using /v2 endpoints will still work _MIN_API_VERSION = "3.0" _MAX_API_VERSION = "3.64" -_LEGACY_API_VERSION2 = "2.0" -UPDATED = "2021-02-03T00:00:00Z" +UPDATED = "2021-05-30T00:00:00Z" # NOTE(cyeoh): min and max versions declared as functions so we can @@ -171,10 +169,6 @@ def max_api_version(): return APIVersionRequest(_MAX_API_VERSION) -def legacy_api_version2(): - return APIVersionRequest(_LEGACY_API_VERSION2) - - class APIVersionRequest(utils.ComparableMixin): """This class represents an API Version Request. diff --git a/cinder/api/openstack/wsgi.py b/cinder/api/openstack/wsgi.py index ab9e0273ec8..2c3dc16d909 100644 --- a/cinder/api/openstack/wsgi.py +++ b/cinder/api/openstack/wsgi.py @@ -275,16 +275,9 @@ class Request(webob.Request): return self.accept_language.best_match(all_languages) def set_api_version_request(self, url): - """Set API version request based on the request header information. + """Set API version request based on the request header information.""" - Microversions starts with /v3, so if a client sends a request for - version 1.0 or 2.0 with the /v3 endpoint, throw an exception. - Sending a header with any microversion to a /v2 endpoint will - be ignored. - Note that a microversion must be set for the legacy endpoint. This - will appear as 2.0 for /v2. - """ - if API_VERSION_REQUEST_HEADER in self.headers and 'v3' in url: + if API_VERSION_REQUEST_HEADER in self.headers: hdr_string = self.headers[API_VERSION_REQUEST_HEADER] # 'latest' is a special keyword which is equivalent to requesting # the maximum version of the API supported @@ -314,11 +307,8 @@ class Request(webob.Request): max_ver=api_version.max_api_version().get_string()) else: - if 'v2' in url: - self.api_version_request = api_version.legacy_api_version2() - else: - self.api_version_request = api_version.APIVersionRequest( - api_version._MIN_API_VERSION) + self.api_version_request = api_version.APIVersionRequest( + api_version._MIN_API_VERSION) class ActionDispatcher(object): diff --git a/cinder/api/v2/router.py b/cinder/api/v2/router.py deleted file mode 100644 index 3a5ba81ecb7..00000000000 --- a/cinder/api/v2/router.py +++ /dev/null @@ -1,93 +0,0 @@ -# Copyright 2011 OpenStack Foundation -# Copyright 2011 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -WSGI middleware for OpenStack Volume API. -""" - -from cinder.api import extensions -import cinder.api.openstack -from cinder.api.v2 import limits -from cinder.api.v2 import snapshot_metadata -from cinder.api.v2 import snapshots -from cinder.api.v2 import types -from cinder.api.v2 import volume_metadata -from cinder.api.v2 import volumes -from cinder.api import versions - - -class APIRouter(cinder.api.openstack.APIRouter): - """Routes requests on the API to the appropriate controller and method.""" - ExtensionManager = extensions.ExtensionManager - - def _setup_routes(self, mapper, ext_mgr): - self.resources['versions'] = versions.create_resource() - mapper.connect("versions", "/", - controller=self.resources['versions'], - action='index') - - mapper.redirect("", "/") - - self.resources['volumes'] = volumes.create_resource(ext_mgr) - mapper.resource("volume", "volumes", - controller=self.resources['volumes'], - collection={'detail': 'GET'}, - member={'action': 'POST'}) - - self.resources['types'] = types.create_resource() - mapper.resource("type", "types", - controller=self.resources['types'], - member={'action': 'POST'}) - - self.resources['snapshots'] = snapshots.create_resource(ext_mgr) - mapper.resource("snapshot", "snapshots", - controller=self.resources['snapshots'], - collection={'detail': 'GET'}, - member={'action': 'POST'}) - - self.resources['limits'] = limits.create_resource() - mapper.resource("limit", "limits", - controller=self.resources['limits']) - - self.resources['snapshot_metadata'] = \ - snapshot_metadata.create_resource() - snapshot_metadata_controller = self.resources['snapshot_metadata'] - - mapper.resource("snapshot_metadata", "metadata", - controller=snapshot_metadata_controller, - parent_resource=dict(member_name='snapshot', - collection_name='snapshots')) - - mapper.connect("metadata", - "/{project_id}/snapshots/{snapshot_id}/metadata", - controller=snapshot_metadata_controller, - action='update_all', - conditions={"method": ['PUT']}) - - self.resources['volume_metadata'] = volume_metadata.create_resource() - volume_metadata_controller = self.resources['volume_metadata'] - - mapper.resource("volume_metadata", "metadata", - controller=volume_metadata_controller, - parent_resource=dict(member_name='volume', - collection_name='volumes')) - - mapper.connect("metadata", - "/{project_id}/volumes/{volume_id}/metadata", - controller=volume_metadata_controller, - action='update_all', - conditions={"method": ['PUT']}) diff --git a/cinder/api/v2/volumes.py b/cinder/api/v2/volumes.py index fb2e0158bdc..ddff0471e6c 100644 --- a/cinder/api/v2/volumes.py +++ b/cinder/api/v2/volumes.py @@ -177,8 +177,14 @@ class VolumeController(wsgi.Controller): "access requested image.") raise exc.HTTPBadRequest(explanation=msg) + # NOTE: using mv.BASE_VERSION (which is 3.0) is a bit nonstandard, + # but this class is no longer consumed by the v2 API, though it is + # a superclass of cinder.api.v3.volumes. Although create() is + # overridden in the subclass, I didn't want to remove it from + # here until we are sure that the v3 unit tests for create() test + # everything that the v2 unit tests covered. @wsgi.response(HTTPStatus.ACCEPTED) - @validation.schema(volumes.create, mv.V2_BASE_VERSION) + @validation.schema(volumes.create, mv.BASE_VERSION) def create(self, req, body): """Creates a new volume.""" @@ -279,7 +285,8 @@ class VolumeController(wsgi.Controller): """Return volume search options allowed by non-admin.""" return common.get_enabled_resource_filters('volume').get('volume', []) - @validation.schema(volumes.update, mv.V2_BASE_VERSION, + # NOTE: see NOTE for create(), above + @validation.schema(volumes.update, mv.BASE_VERSION, mv.get_prior_version(mv.SUPPORT_VOLUME_SCHEMA_CHANGES)) @validation.schema(volumes.update_volume_v353, mv.SUPPORT_VOLUME_SCHEMA_CHANGES) diff --git a/cinder/api/v3/router.py b/cinder/api/v3/router.py index dad5585190d..4ad2acfdb6c 100644 --- a/cinder/api/v3/router.py +++ b/cinder/api/v3/router.py @@ -21,8 +21,6 @@ WSGI middleware for OpenStack Volume API. from cinder.api import extensions import cinder.api.openstack -from cinder.api.v2 import snapshot_metadata -from cinder.api.v2 import types from cinder.api.v3 import attachments from cinder.api.v3 import backups from cinder.api.v3 import clusters @@ -36,7 +34,9 @@ from cinder.api.v3 import limits from cinder.api.v3 import messages from cinder.api.v3 import resource_filters from cinder.api.v3 import snapshot_manage +from cinder.api.v3 import snapshot_metadata from cinder.api.v3 import snapshots +from cinder.api.v3 import types from cinder.api.v3 import volume_manage from cinder.api.v3 import volume_metadata from cinder.api.v3 import volume_transfer diff --git a/cinder/api/v2/snapshot_metadata.py b/cinder/api/v3/snapshot_metadata.py similarity index 100% rename from cinder/api/v2/snapshot_metadata.py rename to cinder/api/v3/snapshot_metadata.py diff --git a/cinder/api/v2/types.py b/cinder/api/v3/types.py similarity index 98% rename from cinder/api/v2/types.py rename to cinder/api/v3/types.py index ae19cbedf16..d6579dd9d30 100644 --- a/cinder/api/v2/types.py +++ b/cinder/api/v3/types.py @@ -23,7 +23,7 @@ from cinder.api import api_utils from cinder.api import common from cinder.api import microversions as mv from cinder.api.openstack import wsgi -from cinder.api.v2.views import types as views_types +from cinder.api.v3.views import types as views_types from cinder import exception from cinder.i18n import _ from cinder.policies import volume_type as type_policy diff --git a/cinder/api/v2/views/types.py b/cinder/api/v3/views/types.py similarity index 100% rename from cinder/api/v2/views/types.py rename to cinder/api/v3/views/types.py diff --git a/cinder/api/v3/volumes.py b/cinder/api/v3/volumes.py index 09b57386df9..e5c5f18ef16 100644 --- a/cinder/api/v3/volumes.py +++ b/cinder/api/v3/volumes.py @@ -147,7 +147,8 @@ class VolumeController(volumes_v2.VolumeController): self._process_volume_filtering(context=context, filters=filters, req_version=req_version) - # NOTE(thingee): v2 API allows name instead of display_name + # NOTE: it's 'name' in the REST API, but 'display_name' in the + # database layer, so we need to do this translation if 'name' in sort_keys: sort_keys[sort_keys.index('name')] = 'display_name' @@ -302,12 +303,11 @@ class VolumeController(volumes_v2.VolumeController): kwargs = {} self.validate_name_and_description(volume, check_length=False) - # NOTE(thingee): v2 API allows name instead of display_name + # NOTE: it's 'name'/'description' in the REST API, but + # 'display_name'/display_description' in the database layer, + # so we need to do this translation if 'name' in volume: volume['display_name'] = volume.pop('name') - - # NOTE(thingee): v2 API allows description instead of - # display_description if 'description' in volume: volume['display_description'] = volume.pop('description') diff --git a/cinder/api/versions.py b/cinder/api/versions.py index 24b91975953..a4883d2e5ce 100644 --- a/cinder/api/versions.py +++ b/cinder/api/versions.py @@ -38,18 +38,6 @@ _LINKS = [{ _KNOWN_VERSIONS = { - "v2.0": { - "id": "v2.0", - "status": "DEPRECATED", - "version": "", - "min_version": "", - "updated": "2017-02-25T12:00:00Z", - "links": _LINKS, - "media-types": [{ - "base": "application/json", - "type": "application/vnd.openstack.volume+json;version=2", - }] - }, "v3.0": { "id": "v3.0", "status": "CURRENT", @@ -93,24 +81,15 @@ class VersionsController(wsgi.Controller): def __init__(self): super(VersionsController, self).__init__(None) - @wsgi.Controller.api_version('2.0') - def index(self, req): # pylint: disable=E0102 - """Return versions supported prior to the microversions epoch.""" - builder = views_versions.get_view_builder(req) - known_versions = copy.deepcopy(_KNOWN_VERSIONS) - known_versions.pop('v3.0') - return builder.build_versions(known_versions) - - @index.api_version('3.0') + @wsgi.Controller.api_version('3.0') def index(self, req): # pylint: disable=E0102 """Return versions supported after the start of microversions.""" builder = views_versions.get_view_builder(req) known_versions = copy.deepcopy(_KNOWN_VERSIONS) - known_versions.pop('v2.0') return builder.build_versions(known_versions) # NOTE (cknight): Calling the versions API without - # /v2 or /v3 in the URL will lead to this unversioned + # /v3 in the URL will lead to this unversioned # method, which should always return info about all # available versions. @wsgi.response(HTTPStatus.MULTIPLE_CHOICES) @@ -119,8 +98,8 @@ class VersionsController(wsgi.Controller): builder = views_versions.get_view_builder(req) known_versions = copy.deepcopy(_KNOWN_VERSIONS) - if not CONF.enable_v2_api: - known_versions.pop('v2.0') + # FIXME: remove this in Y ... I suppose we should honor + # it in Xena, even though it doesn't make any sense if not CONF.enable_v3_api: known_versions.pop('v3.0') diff --git a/cinder/common/config.py b/cinder/common/config.py index 799afcc064f..8f2fc414ca1 100644 --- a/cinder/common/config.py +++ b/cinder/common/config.py @@ -47,12 +47,12 @@ core_opts = [ CONF.register_cli_opts(core_opts) api_opts = [ - cfg.BoolOpt('enable_v2_api', - default=True, - deprecated_for_removal=True, - help="DEPRECATED: Deploy v2 of the Cinder API."), cfg.BoolOpt('enable_v3_api', default=True, + deprecated_for_removal=True, + deprecated_reason=('This is the only API version available, ' + 'so disabling it is not an option.'), + deprecated_since="Xena", help="Deploy v3 of the Cinder API."), cfg.BoolOpt('api_rate_limit', default=True, diff --git a/cinder/tests/functional/api_sample_tests/samples/versions/versions-response.json.tpl b/cinder/tests/functional/api_sample_tests/samples/versions/versions-response.json.tpl index 686799d99d9..68141ee7022 100644 --- a/cinder/tests/functional/api_sample_tests/samples/versions/versions-response.json.tpl +++ b/cinder/tests/functional/api_sample_tests/samples/versions/versions-response.json.tpl @@ -1,29 +1,5 @@ { "versions": [ - { - "status": "DEPRECATED", - "updated": "%(isotime)s", - "links": [ - { - "href": "https://docs.openstack.org/", - "type": "text/html", - "rel": "describedby" - }, - { - "href": "%(host)s/v2/", - "rel": "self" - } - ], - "min_version": "", - "version": "", - "media-types": [ - { - "base": "application/json", - "type": "application/vnd.openstack.volume+json;version=2" - } - ], - "id": "v2.0" - }, { "status": "CURRENT", "updated": "%(isotime)s", diff --git a/cinder/tests/unit/api/contrib/test_admin_actions.py b/cinder/tests/unit/api/contrib/test_admin_actions.py index ef46274ba29..5f7ff7c12c2 100644 --- a/cinder/tests/unit/api/contrib/test_admin_actions.py +++ b/cinder/tests/unit/api/contrib/test_admin_actions.py @@ -35,7 +35,7 @@ from cinder.objects import base as obj_base from cinder.objects import fields from cinder.scheduler import rpcapi as scheduler_rpcapi from cinder.tests.unit.api import fakes -from cinder.tests.unit.api.v2 import fakes as v2_fakes +from cinder.tests.unit.api.v3 import fakes as v3_fakes from cinder.tests.unit import cast_as_call from cinder.tests.unit import fake_constants as fake from cinder.tests.unit import fake_snapshot @@ -48,14 +48,7 @@ from cinder.volume import volume_types def app(): # no auth, just let environ['cinder.context'] pass through - api = fakes.router.APIRouter() - mapper = fakes.urlmap.URLMap() - mapper['/v2'] = api - return mapper - - -def app_v3(): - api = fakes.router.APIRouter() + api = fakes.router_v3.APIRouter() mapper = fakes.urlmap.URLMap() mapper['/v3'] = api return mapper @@ -123,7 +116,7 @@ class AdminActionsTest(BaseAdminTest): super(AdminActionsTest, self).tearDown() def _issue_resource_reset(self, ctx, name, id, status): - req = webob.Request.blank('/v2/%s/%s/%s/action' % ( + req = webob.Request.blank('/v3/%s/%s/%s/action' % ( fake.PROJECT_ID, name, id)) req.method = 'POST' req.headers['content-type'] = 'application/json' @@ -370,7 +363,7 @@ class AdminActionsTest(BaseAdminTest): 'user_id': fake.USER_ID, 'project_id': fake.PROJECT_ID}) - req = webob.Request.blank('/v2/%s/%s/%s/action' % ( + req = webob.Request.blank('/v3/%s/%s/%s/action' % ( fake.PROJECT_ID, 'backups', backup['id'])) req.method = 'POST' req.headers['content-type'] = 'application/json' @@ -405,7 +398,7 @@ class AdminActionsTest(BaseAdminTest): self.assertEqual('available', volume['status']) def test_reset_status_for_missing_volume(self): - req = webob.Request.blank('/v2/%s/volumes/%s/action' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID)) req.method = 'POST' req.headers['content-type'] = 'application/json' @@ -541,7 +534,7 @@ class AdminActionsTest(BaseAdminTest): snapshot.create() self.addCleanup(snapshot.destroy) - req = webob.Request.blank('/v2/%s/%s/%s/action' % ( + req = webob.Request.blank('/v3/%s/%s/%s/action' % ( fake.PROJECT_ID, 'snapshots', snapshot['id'])) req.method = 'POST' req.headers['content-type'] = 'application/json' @@ -553,7 +546,7 @@ class AdminActionsTest(BaseAdminTest): def test_force_delete(self): # current status is creating volume = self._create_volume(self.ctx, {'size': 1, 'host': None}) - req = webob.Request.blank('/v2/%s/volumes/%s/action' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, volume['id'])) req.method = 'POST' req.headers['content-type'] = 'application/json' @@ -573,14 +566,14 @@ class AdminActionsTest(BaseAdminTest): @mock.patch.object(db, 'volume_get') def test_force_delete_snapshot(self, volume_get, snapshot_get, get_by_id, delete_snapshot): - volume = v2_fakes.create_fake_volume(fake.VOLUME_ID) - snapshot = v2_fakes.fake_snapshot(fake.SNAPSHOT_ID) + volume = v3_fakes.create_volume(fake.VOLUME_ID) + snapshot = v3_fakes.fake_snapshot(fake.SNAPSHOT_ID) snapshot_obj = fake_snapshot.fake_snapshot_obj(self.ctx, **snapshot) volume_get.return_value = volume snapshot_get.return_value = snapshot get_by_id.return_value = snapshot_obj - path = '/v2/%s/snapshots/%s/action' % ( + path = '/v3/%s/snapshots/%s/action' % ( fake.PROJECT_ID, snapshot['id']) req = webob.Request.blank(path) req.method = 'POST' @@ -633,7 +626,7 @@ class AdminActionsTest(BaseAdminTest): body['os-migrate_volume']['cluster'] = cluster req.body = jsonutils.dump_as_bytes(body) req.environ['cinder.context'] = ctx - resp = req.get_response(app_v3()) + resp = req.get_response(app()) # verify status self.assertEqual(expected_status, resp.status_int) @@ -676,7 +669,7 @@ class AdminActionsTest(BaseAdminTest): def _migrate_volume_exec(self, ctx, volume, host, expected_status, force_host_copy=False, lock_volume=False): # build request to migrate to host - req = webob.Request.blank('/v2/%s/volumes/%s/action' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, volume['id'])) req.method = 'POST' req.headers['content-type'] = 'application/json' @@ -737,7 +730,7 @@ class AdminActionsTest(BaseAdminTest): host = 'test3' volume = self._migrate_volume_prep() # build request to migrate without host - req = webob.Request.blank('/v2/%s/volumes/%s/action' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, volume['id'])) req.method = 'POST' req.headers['content-type'] = 'application/json' @@ -804,7 +797,7 @@ class AdminActionsTest(BaseAdminTest): def _migrate_volume_comp_exec(self, ctx, volume, new_volume, error, expected_status, expected_id, no_body=False): - req = webob.Request.blank('/v2/%s/volumes/%s/action' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, volume['id'])) req.method = 'POST' req.headers['content-type'] = 'application/json' @@ -893,7 +886,7 @@ class AdminActionsTest(BaseAdminTest): volume = db.volume_create(self.ctx, {'id': fake.VOLUME_ID, 'volume_type_id': fake.VOLUME_TYPE_ID}) - req = webob.Request.blank('/v2/%s/volumes/%s/action' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, volume['id'])) req.method = 'POST' req.headers['content-type'] = 'application/json' @@ -920,7 +913,7 @@ class AdminActionsTest(BaseAdminTest): backup = test_utils.create_backup(self.ctx, status=test_status, size=1, availability_zone='az1', host='testhost') - req = webob.Request.blank('/v2/%s/backups/%s/action' % ( + req = webob.Request.blank('/v3/%s/backups/%s/action' % ( fake.PROJECT_ID, backup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -957,7 +950,7 @@ class AdminActionsTest(BaseAdminTest): # admin context self.override_config('backup_driver', 'cinder.backup.drivers.ceph') backup = test_utils.create_backup(self.ctx, size=1) - req = webob.Request.blank('/v2/%s/backups/%s/action' % ( + req = webob.Request.blank('/v3/%s/backups/%s/action' % ( fake.PROJECT_ID, backup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1003,7 +996,7 @@ class AdminActionsAttachDetachTest(BaseAdminTest): connector) self.assertEqual('rw', conn_info['data']['access_mode']) # build request to force detach - req = webob.Request.blank('/v2/%s/volumes/%s/action' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, volume.id)) req.method = 'POST' req.headers['content-type'] = 'application/json' @@ -1055,7 +1048,7 @@ class AdminActionsAttachDetachTest(BaseAdminTest): volume, connector) self.assertEqual('ro', conn_info['data']['access_mode']) # build request to force detach - req = webob.Request.blank('/v2/%s/volumes/%s/action' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, volume.id)) req.method = 'POST' req.headers['content-type'] = 'application/json' @@ -1109,7 +1102,7 @@ class AdminActionsAttachDetachTest(BaseAdminTest): messaging.RemoteError(exc_type='VolumeAttachmentNotFound') with mock.patch.object(volume_api.API, 'detach', side_effect=volume_remote_error): - req = webob.Request.blank('/v2/%s/volumes/%s/action' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, volume.id)) req.method = 'POST' req.headers['content-type'] = 'application/json' @@ -1126,7 +1119,7 @@ class AdminActionsAttachDetachTest(BaseAdminTest): messaging.RemoteError(exc_type='VolumeBackendAPIException')) with mock.patch.object(volume_api.API, 'detach', side_effect=volume_remote_error): - req = webob.Request.blank('/v2/%s/volumes/%s/action' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, volume.id)) req.method = 'POST' req.headers['content-type'] = 'application/json' @@ -1172,7 +1165,7 @@ class AdminActionsAttachDetachTest(BaseAdminTest): volume_remote_error = messaging.RemoteError(exc_type='DBError') with mock.patch.object(volume_api.API, 'detach', side_effect=volume_remote_error): - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, volume.id)) req.method = 'POST' req.headers['content-type'] = 'application/json' @@ -1214,7 +1207,7 @@ class AdminActionsAttachDetachTest(BaseAdminTest): # test when missing connector with mock.patch.object(volume_api.API, 'detach'): - req = webob.Request.blank('/v2/%s/volumes/%s/action' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, volume.id)) req.method = 'POST' req.headers['content-type'] = 'application/json' diff --git a/cinder/tests/unit/api/contrib/test_backups.py b/cinder/tests/unit/api/contrib/test_backups.py index 56567f3260d..9c6bb4955bf 100644 --- a/cinder/tests/unit/api/contrib/test_backups.py +++ b/cinder/tests/unit/api/contrib/test_backups.py @@ -82,7 +82,7 @@ class BackupsAPITestCase(test.TestCase): container='volumebackups', size=1, availability_zone='az1') - req = webob.Request.blank('/v2/%s/backups/%s' % ( + req = webob.Request.blank('/v3/%s/backups/%s' % ( fake.PROJECT_ID, backup.id)) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -129,7 +129,7 @@ class BackupsAPITestCase(test.TestCase): backup.destroy() def test_show_backup_with_backup_NotFound(self): - req = webob.Request.blank('/v2/%s/backups/%s' % ( + req = webob.Request.blank('/v3/%s/backups/%s' % ( fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID)) req.method = 'GET' req.headers = mv.get_mv_header(mv.BACKUP_METADATA) @@ -150,7 +150,7 @@ class BackupsAPITestCase(test.TestCase): backup2 = utils.create_backup(self.context) backup3 = utils.create_backup(self.context) - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.method = 'GET' req.headers['Content-Type'] = 'application/json' res = req.get_response(fakes.wsgi_app( @@ -177,7 +177,7 @@ class BackupsAPITestCase(test.TestCase): backup2 = utils.create_backup(self.context) backup3 = utils.create_backup(self.context) - req = webob.Request.blank('/v2/%s/backups?limit=2' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups?limit=2' % fake.PROJECT_ID) req.method = 'GET' req.headers['Content-Type'] = 'application/json' res = req.get_response(fakes.wsgi_app( @@ -198,7 +198,7 @@ class BackupsAPITestCase(test.TestCase): backup1.destroy() def test_list_backups_with_offset_out_of_range(self): - url = '/v2/%s/backups?offset=252452434242342434' % fake.PROJECT_ID + url = '/v3/%s/backups?offset=252452434242342434' % fake.PROJECT_ID req = webob.Request.blank(url) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -210,7 +210,7 @@ class BackupsAPITestCase(test.TestCase): backup1 = utils.create_backup(self.context) backup2 = utils.create_backup(self.context) backup3 = utils.create_backup(self.context) - url = '/v2/%s/backups?marker=%s' % (fake.PROJECT_ID, backup3.id) + url = '/v3/%s/backups?marker=%s' % (fake.PROJECT_ID, backup3.id) req = webob.Request.blank(url) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -236,7 +236,7 @@ class BackupsAPITestCase(test.TestCase): backup2 = utils.create_backup(self.context) backup3 = utils.create_backup(self.context) - url = ('/v2/%s/backups?limit=1&marker=%s' % (fake.PROJECT_ID, + url = ('/v3/%s/backups?limit=1&marker=%s' % (fake.PROJECT_ID, backup3.id)) req = webob.Request.blank(url) req.method = 'GET' @@ -264,7 +264,7 @@ class BackupsAPITestCase(test.TestCase): backup3 = utils.create_backup(self.context, availability_zone='az1', container='volumebackups', size=1) - req = webob.Request.blank('/v2/%s/backups/detail' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups/detail' % fake.PROJECT_ID) req.method = 'GET' req.headers['Content-Type'] = 'application/json' req.headers['Accept'] = 'application/json' @@ -302,7 +302,7 @@ class BackupsAPITestCase(test.TestCase): backup3 = utils.create_backup(self.context, availability_zone='az1', container='volumebackups', size=1) - req = webob.Request.blank('/v2/%s/backups/detail' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups/detail' % fake.PROJECT_ID) req.method = 'GET' req.headers['Content-Type'] = 'application/json' req.headers['Accept'] = 'application/json' @@ -395,7 +395,7 @@ class BackupsAPITestCase(test.TestCase): status=fields.BackupStatus.AVAILABLE) backup3 = utils.create_backup(self.context, volume_id=fake.VOLUME3_ID) - req = webob.Request.blank('/v2/%s/backups/detail?name=test2' % + req = webob.Request.blank('/v3/%s/backups/detail?name=test2' % fake.PROJECT_ID) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -408,7 +408,7 @@ class BackupsAPITestCase(test.TestCase): self.assertEqual(HTTPStatus.OK, res.status_int) self.assertEqual(backup1.id, res_dict['backups'][0]['id']) - req = webob.Request.blank('/v2/%s/backups/detail?status=available' % + req = webob.Request.blank('/v3/%s/backups/detail?status=available' % fake.PROJECT_ID) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -421,7 +421,7 @@ class BackupsAPITestCase(test.TestCase): self.assertEqual(HTTPStatus.OK, res.status_int) self.assertEqual(backup2.id, res_dict['backups'][0]['id']) - req = webob.Request.blank('/v2/%s/backups/detail?volume_id=%s' % ( + req = webob.Request.blank('/v3/%s/backups/detail?volume_id=%s' % ( fake.PROJECT_ID, fake.VOLUME3_ID)) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -442,7 +442,7 @@ class BackupsAPITestCase(test.TestCase): backup1 = utils.create_backup(self.context) backup2 = utils.create_backup(self.context) backup3 = utils.create_backup(self.context) - url = ('/v2/%s/backups/detail?limit=2&sort_key=created_at' + url = ('/v3/%s/backups/detail?limit=2&sort_key=created_at' '&sort_dir=desc' % fake.PROJECT_ID) req = webob.Request.blank(url) req.method = 'GET' @@ -467,7 +467,7 @@ class BackupsAPITestCase(test.TestCase): backup2 = utils.create_backup(self.context) backup3 = utils.create_backup(self.context) - url = ('/v2/%s/backups/detail?marker=%s' % ( + url = ('/v3/%s/backups/detail?marker=%s' % ( fake.PROJECT_ID, backup3.id)) req = webob.Request.blank(url) req.method = 'GET' @@ -492,7 +492,7 @@ class BackupsAPITestCase(test.TestCase): backup2 = utils.create_backup(self.context) backup3 = utils.create_backup(self.context) - url = ('/v2/%s/backups/detail?limit=1&marker=%s' % ( + url = ('/v3/%s/backups/detail?limit=1&marker=%s' % ( fake.PROJECT_ID, backup3.id)) req = webob.Request.blank(url) req.method = 'GET' @@ -511,7 +511,7 @@ class BackupsAPITestCase(test.TestCase): backup1.destroy() def test_list_backups_detail_with_offset_out_of_range(self): - url = ('/v2/%s/backups/detail?offset=234534543657634523' % + url = ('/v3/%s/backups/detail?offset=234534543657634523' % fake.PROJECT_ID) req = webob.Request.blank(url) req.method = 'GET' @@ -530,7 +530,7 @@ class BackupsAPITestCase(test.TestCase): "container": "nightlybackups", } } - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -560,7 +560,7 @@ class BackupsAPITestCase(test.TestCase): volume = utils.create_volume(self.context, size=5) body['backup']['volume_id'] = volume.id - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -570,7 +570,7 @@ class BackupsAPITestCase(test.TestCase): # create backup call doesn't return 'description' in response so get # the created backup to assert name and description - req = webob.Request.blank('/v2/%s/backups/%s' % ( + req = webob.Request.blank('/v3/%s/backups/%s' % ( fake.PROJECT_ID, res_dict['backup']['id'])) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -668,7 +668,7 @@ class BackupsAPITestCase(test.TestCase): "container": "nightlybackups", } } - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -698,7 +698,7 @@ class BackupsAPITestCase(test.TestCase): "force": True, } } - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -723,7 +723,7 @@ class BackupsAPITestCase(test.TestCase): "container": "nightlybackups", } } - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -750,7 +750,7 @@ class BackupsAPITestCase(test.TestCase): "container": "nightlybackups", } } - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -777,7 +777,7 @@ class BackupsAPITestCase(test.TestCase): } } - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -802,7 +802,7 @@ class BackupsAPITestCase(test.TestCase): "volume_id": volume.id, } } - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -825,11 +825,10 @@ class BackupsAPITestCase(test.TestCase): "container": "a" * 256 } } - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.method = 'POST' req.environ['cinder.context'] = self.context - req.api_version_request = api_version.APIVersionRequest() - req.api_version_request = api_version.APIVersionRequest("2.0") + req.api_version_request = api_version.APIVersionRequest("3.0") self.assertRaises(exception.ValidationError, self.controller.create, req, @@ -868,7 +867,7 @@ class BackupsAPITestCase(test.TestCase): size=1, availability_zone='az1', host='testhost') - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -905,7 +904,7 @@ class BackupsAPITestCase(test.TestCase): "incremental": True, } } - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -924,7 +923,7 @@ class BackupsAPITestCase(test.TestCase): def test_create_backup_with_no_body(self): # omit body from the request - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.body = jsonutils.dump_as_bytes(None) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -947,7 +946,7 @@ class BackupsAPITestCase(test.TestCase): "container": "nightlybackups", } } - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -969,7 +968,7 @@ class BackupsAPITestCase(test.TestCase): "container": "nightlybackups", } } - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -992,7 +991,7 @@ class BackupsAPITestCase(test.TestCase): "container": "nightlybackups", } } - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -1013,7 +1012,7 @@ class BackupsAPITestCase(test.TestCase): "container": "nightlybackups", } } - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -1033,7 +1032,7 @@ class BackupsAPITestCase(test.TestCase): _mock_service_get_all.return_value = [] volume = utils.create_volume(self.context, size=2) - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) body = {"backup": {"name": "nightly001", "description": "Nightly Backup 03-Sep-2012", @@ -1069,7 +1068,7 @@ class BackupsAPITestCase(test.TestCase): "incremental": True, } } - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -1095,7 +1094,7 @@ class BackupsAPITestCase(test.TestCase): "snapshot_id": None, } } - req = webob.Request.blank('/v2/%s/backups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -1265,7 +1264,7 @@ class BackupsAPITestCase(test.TestCase): backup = utils.create_backup(self.context, status=fields.BackupStatus.AVAILABLE, availability_zone='az1', host='testhost') - req = webob.Request.blank('/v2/%s/backups/%s' % ( + req = webob.Request.blank('/v3/%s/backups/%s' % ( fake.PROJECT_ID, backup.id)) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' @@ -1293,7 +1292,7 @@ class BackupsAPITestCase(test.TestCase): status=fields.BackupStatus.AVAILABLE, incremental=True, availability_zone='az1', host='testhost') - req = webob.Request.blank('/v2/%s/backups/%s' % ( + req = webob.Request.blank('/v3/%s/backups/%s' % ( fake.PROJECT_ID, delta.id)) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' @@ -1318,7 +1317,7 @@ class BackupsAPITestCase(test.TestCase): backup = utils.create_backup(self.context, status=fields.BackupStatus.ERROR, availability_zone='az1', host='testhost') - req = webob.Request.blank('/v2/%s/backups/%s' % ( + req = webob.Request.blank('/v3/%s/backups/%s' % ( fake.PROJECT_ID, backup.id)) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' @@ -1333,7 +1332,7 @@ class BackupsAPITestCase(test.TestCase): backup.destroy() def test_delete_backup_with_backup_NotFound(self): - req = webob.Request.blank('/v2/%s/backups/%s' % ( + req = webob.Request.blank('/v3/%s/backups/%s' % ( fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID)) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' @@ -1350,7 +1349,7 @@ class BackupsAPITestCase(test.TestCase): def test_delete_backup_with_InvalidBackup(self): backup = utils.create_backup(self.context) - req = webob.Request.blank('/v2/%s/backups/%s' % ( + req = webob.Request.blank('/v3/%s/backups/%s' % ( fake.PROJECT_ID, backup.id)) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' @@ -1382,7 +1381,7 @@ class BackupsAPITestCase(test.TestCase): status=fields.BackupStatus.AVAILABLE, incremental=True, parent_id=backup.id) - req = webob.Request.blank('/v2/%s/backups/%s' % ( + req = webob.Request.blank('/v3/%s/backups/%s' % ( fake.PROJECT_ID, backup.id)) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' @@ -1407,7 +1406,7 @@ class BackupsAPITestCase(test.TestCase): 'disabled': 0, 'updated_at': '1775-04-19 05:00:00', 'uuid': 'a3a593da-7f8d-4bb7-8b4c-f2bc1e0b4824'}] backup = utils.create_backup(self.context, status='available') - req = webob.Request.blank('/v2/%s/backups/%s' % ( + req = webob.Request.blank('/v3/%s/backups/%s' % ( fake.PROJECT_ID, backup.id)) req.method = 'DELETE' @@ -1432,7 +1431,7 @@ class BackupsAPITestCase(test.TestCase): status=fields.BackupStatus.AVAILABLE, availability_zone='az1', host='testhost', service=None) - req = webob.Request.blank('/v2/%s/backups/%s' % ( + req = webob.Request.blank('/v3/%s/backups/%s' % ( fake.PROJECT_ID, backup.id)) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' @@ -1453,7 +1452,7 @@ class BackupsAPITestCase(test.TestCase): display_name=volume_name) body = {"restore": {"volume_id": volume.id, }} - req = webob.Request.blank('/v2/%s/backups/%s/restore' % ( + req = webob.Request.blank('/v3/%s/backups/%s/restore' % ( fake.PROJECT_ID, backup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1472,7 +1471,7 @@ class BackupsAPITestCase(test.TestCase): backup = utils.create_backup(self.context, status=fields.BackupStatus.AVAILABLE) - req = webob.Request.blank('/v2/%s/backups/%s/restore' % ( + req = webob.Request.blank('/v3/%s/backups/%s/restore' % ( fake.PROJECT_ID, backup.id)) req.body = jsonutils.dump_as_bytes(None) req.method = 'POST' @@ -1495,7 +1494,7 @@ class BackupsAPITestCase(test.TestCase): backup = utils.create_backup(self.context, status=fields.BackupStatus.AVAILABLE) - req = webob.Request.blank('/v2/%s/backups/%s/restore' % ( + req = webob.Request.blank('/v3/%s/backups/%s/restore' % ( fake.PROJECT_ID, backup.id)) body = {"restore": {'': ''}} req.method = 'POST' @@ -1537,7 +1536,7 @@ class BackupsAPITestCase(test.TestCase): availability_zone='az1', host='testhost') body = {"restore": {}} - req = webob.Request.blank('/v2/%s/backups/%s/restore' % ( + req = webob.Request.blank('/v3/%s/backups/%s/restore' % ( fake.PROJECT_ID, backup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1572,7 +1571,7 @@ class BackupsAPITestCase(test.TestCase): availability_zone='az1', host='testhost') body = {"restore": {'name': 'vol-01'}} - req = webob.Request.blank('/v2/%s/backups/%s/restore' % + req = webob.Request.blank('/v3/%s/backups/%s/restore' % (fake.PROJECT_ID, backup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1602,7 +1601,7 @@ class BackupsAPITestCase(test.TestCase): volume = utils.create_volume(self.context, size=5, display_name=orig_vol_name) body = {"restore": {'name': 'vol-01', 'volume_id': volume.id}} - req = webob.Request.blank('/v2/%s/backups/%s/restore' % ( + req = webob.Request.blank('/v3/%s/backups/%s/restore' % ( fake.PROJECT_ID, backup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1630,7 +1629,7 @@ class BackupsAPITestCase(test.TestCase): body = {"restore": {"name": None, "volume_id": volume.id}} - req = webob.Request.blank('/v2/%s/backups/%s/restore' % ( + req = webob.Request.blank('/v3/%s/backups/%s/restore' % ( fake.PROJECT_ID, backup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1655,7 +1654,7 @@ class BackupsAPITestCase(test.TestCase): # need to create the volume referenced below first volume = utils.create_volume(self.context, size=0) body = {"restore": {"volume_id": volume.id, }} - req = webob.Request.blank('/v2/%s/backups/%s/restore' % ( + req = webob.Request.blank('/v3/%s/backups/%s/restore' % ( fake.PROJECT_ID, backup.id)) req.method = 'POST' @@ -1678,7 +1677,7 @@ class BackupsAPITestCase(test.TestCase): volume = utils.create_volume(self.context, size=5, status='attaching') body = {"restore": {"volume_id": volume.id, }} - req = webob.Request.blank('/v2/%s/backups/%s/restore' % ( + req = webob.Request.blank('/v3/%s/backups/%s/restore' % ( fake.PROJECT_ID, backup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1704,7 +1703,7 @@ class BackupsAPITestCase(test.TestCase): volume = utils.create_volume(self.context, size=5) body = {"restore": {"volume_id": volume.id, }} - req = webob.Request.blank('/v2/%s/backups/%s/restore' % ( + req = webob.Request.blank('/v3/%s/backups/%s/restore' % ( fake.PROJECT_ID, backup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1727,7 +1726,7 @@ class BackupsAPITestCase(test.TestCase): volume = utils.create_volume(self.context, size=5) body = {"restore": {"volume_id": volume.id, }} - req = webob.Request.blank('/v2/%s/backups/%s/restore' % + req = webob.Request.blank('/v3/%s/backups/%s/restore' % (fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1750,7 +1749,7 @@ class BackupsAPITestCase(test.TestCase): status=fields.BackupStatus.AVAILABLE) body = {"restore": {"volume_id": fake.WILL_NOT_BE_FOUND_ID, }} - req = webob.Request.blank('/v2/%s/backups/%s/restore' % ( + req = webob.Request.blank('/v3/%s/backups/%s/restore' % ( fake.PROJECT_ID, backup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1784,7 +1783,7 @@ class BackupsAPITestCase(test.TestCase): volume = utils.create_volume(self.context, size=5) body = {"restore": {"volume_id": volume.id, }} - req = webob.Request.blank('/v2/%s/backups/%s/restore' % ( + req = webob.Request.blank('/v3/%s/backups/%s/restore' % ( fake.PROJECT_ID, backup.id)) req.method = 'POST' @@ -1815,7 +1814,7 @@ class BackupsAPITestCase(test.TestCase): volume = utils.create_volume(self.context, size=5) body = {"restore": {"volume_id": volume.id, }} - req = webob.Request.blank('/v2/%s/backups/%s/restore' % ( + req = webob.Request.blank('/v3/%s/backups/%s/restore' % ( fake.PROJECT_ID, backup.id)) req.method = 'POST' @@ -1841,7 +1840,7 @@ class BackupsAPITestCase(test.TestCase): volume = utils.create_volume(self.context, size=volume_size) body = {"restore": {"volume_id": volume.id, }} - req = webob.Request.blank('/v2/%s/backups/%s/restore' % ( + req = webob.Request.blank('/v3/%s/backups/%s/restore' % ( fake.PROJECT_ID, backup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1873,7 +1872,7 @@ class BackupsAPITestCase(test.TestCase): display_name=volume_name) body = {"restore": {"volume_id": volume.id, }} - req = webob.Request.blank('/v2/%s/backups/%s/restore' % ( + req = webob.Request.blank('/v3/%s/backups/%s/restore' % ( fake.PROJECT_ID, backup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1904,7 +1903,7 @@ class BackupsAPITestCase(test.TestCase): _mock_get_backup_host.return_value = 'testhost' body = {"restore": {"volume_id": volume.id, }} - req = webob.Request.blank('/v2/%s/backups/%s/restore' % ( + req = webob.Request.blank('/v3/%s/backups/%s/restore' % ( fake.PROJECT_ID, backup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1929,7 +1928,7 @@ class BackupsAPITestCase(test.TestCase): backup = utils.create_backup(self.context, status=fields.BackupStatus.AVAILABLE, size=10) - req = webob.Request.blank('/v2/%s/backups/%s/export_record' % ( + req = webob.Request.blank('/v3/%s/backups/%s/export_record' % ( fake.PROJECT_ID, backup.id)) req.method = 'GET' req.headers['content-type'] = 'application/json' @@ -1955,7 +1954,7 @@ class BackupsAPITestCase(test.TestCase): {'backup_service': backup_service, 'backup_url': backup_url} _mock_get_backup_host.return_value = 'testhost' - req = webob.Request.blank('/v2/%s/backups/%s/export_record' % ( + req = webob.Request.blank('/v3/%s/backups/%s/export_record' % ( fake.PROJECT_ID, backup.id)) req.method = 'GET' req.headers['content-type'] = 'application/json' @@ -1975,7 +1974,7 @@ class BackupsAPITestCase(test.TestCase): ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, is_admin=True) backup_id = fake.WILL_NOT_BE_FOUND_ID - req = webob.Request.blank('/v2/%s/backups/%s/export_record' % + req = webob.Request.blank('/v3/%s/backups/%s/export_record' % (fake.PROJECT_ID, backup_id)) req.method = 'GET' req.headers['content-type'] = 'application/json' @@ -1994,7 +1993,7 @@ class BackupsAPITestCase(test.TestCase): status=fields.BackupStatus.RESTORING) ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, is_admin=True) - req = webob.Request.blank('/v2/%s/backups/%s/export_record' % + req = webob.Request.blank('/v3/%s/backups/%s/export_record' % (fake.PROJECT_ID, backup.id)) req.method = 'GET' req.headers['content-type'] = 'application/json' @@ -2022,7 +2021,7 @@ class BackupsAPITestCase(test.TestCase): status=fields.BackupStatus.AVAILABLE) ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, is_admin=True) - req = webob.Request.blank('/v2/%s/backups/%s/export_record' % + req = webob.Request.blank('/v3/%s/backups/%s/export_record' % (fake.PROJECT_ID, backup.id)) req.method = 'GET' req.headers['content-type'] = 'application/json' @@ -2040,7 +2039,7 @@ class BackupsAPITestCase(test.TestCase): def test_import_record_as_non_admin(self): backup_service = 'fake' backup_url = 'fake' - req = webob.Request.blank('/v2/%s/backups/import_record' % + req = webob.Request.blank('/v3/%s/backups/import_record' % fake.PROJECT_ID) body = {'backup-record': {'backup_service': backup_service, 'backup_url': backup_url}} @@ -2077,7 +2076,7 @@ class BackupsAPITestCase(test.TestCase): _mock_import_record_rpc.return_value = None _mock_list_services.return_value = [backup_service] - req = webob.Request.blank('/v2/%s/backups/import_record' % + req = webob.Request.blank('/v3/%s/backups/import_record' % fake.PROJECT_ID) body = {'backup-record': {'backup_service': backup_service, 'backup_url': backup_url}} @@ -2134,7 +2133,7 @@ class BackupsAPITestCase(test.TestCase): _mock_import_record_rpc.return_value = None _mock_list_services.return_value = [backup_service] - req = webob.Request.blank('/v2/%s/backups/import_record' % + req = webob.Request.blank('/v3/%s/backups/import_record' % fake.PROJECT_ID) body = {'backup-record': {'backup_service': backup_service, 'backup_url': backup_url}} @@ -2170,7 +2169,7 @@ class BackupsAPITestCase(test.TestCase): backup_url = 'fake' _mock_list_services.return_value = [] - req = webob.Request.blank('/v2/%s/backups/import_record' % + req = webob.Request.blank('/v3/%s/backups/import_record' % fake.PROJECT_ID) body = {'backup-record': {'backup_service': backup_service, 'backup_url': backup_url}} @@ -2194,7 +2193,7 @@ class BackupsAPITestCase(test.TestCase): backup_service = 'fake' backup_url = 'fake' _mock_list_services.return_value = ['no-match1', 'no-match2'] - req = webob.Request.blank('/v2/%s/backups/import_record' % + req = webob.Request.blank('/v3/%s/backups/import_record' % fake.PROJECT_ID) body = {'backup-record': {'backup_service': backup_service, 'backup_url': backup_url}} @@ -2226,7 +2225,7 @@ class BackupsAPITestCase(test.TestCase): backup_service = 'fake' backup_url = backup.encode_record() _mock_list_services.return_value = ['no-match1', 'no-match2'] - req = webob.Request.blank('/v2/%s/backups/import_record' % + req = webob.Request.blank('/v3/%s/backups/import_record' % fake.PROJECT_ID) body = {'backup-record': {'backup_service': backup_service, 'backup_url': backup_url}} @@ -2266,7 +2265,7 @@ class BackupsAPITestCase(test.TestCase): _mock_list_services.return_value = ['no-match1', 'no-match2'] _mock_import_record.side_effect = \ exception.ServiceNotFound(service_id='fake') - req = webob.Request.blank('/v2/%s/backups/import_record' % + req = webob.Request.blank('/v3/%s/backups/import_record' % fake.PROJECT_ID) body = {'backup-record': {'backup_service': backup_service, 'backup_url': backup_url}} @@ -2291,7 +2290,7 @@ class BackupsAPITestCase(test.TestCase): backup_url = 'fake' # test with no backup_service - req = webob.Request.blank('/v2/%s/backups/import_record' % + req = webob.Request.blank('/v3/%s/backups/import_record' % fake.PROJECT_ID) body = {'backup-record': {'backup_url': backup_url}} req.body = jsonutils.dump_as_bytes(body) @@ -2309,7 +2308,7 @@ class BackupsAPITestCase(test.TestCase): res_dict['badRequest']['message']) # test with no backup_url - req = webob.Request.blank('/v2/%s/backups/import_record' % + req = webob.Request.blank('/v3/%s/backups/import_record' % fake.PROJECT_ID) body = {'backup-record': {'backup_service': backup_service}} req.body = jsonutils.dump_as_bytes(body) @@ -2328,7 +2327,7 @@ class BackupsAPITestCase(test.TestCase): res_dict['badRequest']['message']) # test with no backup_url and backup_url - req = webob.Request.blank('/v2/%s/backups/import_record' % + req = webob.Request.blank('/v3/%s/backups/import_record' % fake.PROJECT_ID) body = {'backup-record': {}} req.body = jsonutils.dump_as_bytes(body) @@ -2349,7 +2348,7 @@ class BackupsAPITestCase(test.TestCase): ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, is_admin=True) - req = webob.Request.blank('/v2/%s/backups/import_record' % + req = webob.Request.blank('/v3/%s/backups/import_record' % fake.PROJECT_ID) req.body = jsonutils.dump_as_bytes(None) req.method = 'POST' @@ -2394,7 +2393,7 @@ class BackupsAPITestCase(test.TestCase): self.context, volume.id, status=fields.BackupStatus.AVAILABLE, incremental=True, parent_id=backup.id, snapshot_id=snapshot_id) - req = webob.Request.blank('/v2/%s/backups/%s' % ( + req = webob.Request.blank('/v3/%s/backups/%s' % ( fake.PROJECT_ID, backup.id)) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -2407,7 +2406,7 @@ class BackupsAPITestCase(test.TestCase): self.assertTrue(res_dict['backup']['has_dependent_backups']) self.assertIsNone(res_dict['backup']['snapshot_id']) - req = webob.Request.blank('/v2/%s/backups/%s' % ( + req = webob.Request.blank('/v3/%s/backups/%s' % ( fake.PROJECT_ID, parent_backup.id)) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -2420,7 +2419,7 @@ class BackupsAPITestCase(test.TestCase): self.assertTrue(res_dict['backup']['has_dependent_backups']) self.assertIsNone(res_dict['backup']['snapshot_id']) - req = webob.Request.blank('/v2/%s/backups/%s' % ( + req = webob.Request.blank('/v3/%s/backups/%s' % ( fake.PROJECT_ID, child_backup.id)) req.method = 'GET' req.headers['Content-Type'] = 'application/json' diff --git a/cinder/tests/unit/api/contrib/test_cgsnapshots.py b/cinder/tests/unit/api/contrib/test_cgsnapshots.py index 8f2303882bb..942b36baf7f 100644 --- a/cinder/tests/unit/api/contrib/test_cgsnapshots.py +++ b/cinder/tests/unit/api/contrib/test_cgsnapshots.py @@ -65,7 +65,7 @@ class CgsnapshotsAPITestCase(test.TestCase): volume_id=volume_id, group_snapshot_id=cgsnapshot.id)['id'] - req = webob.Request.blank('/v2/%s/cgsnapshots/%s' % ( + req = webob.Request.blank('/v3/%s/cgsnapshots/%s' % ( fake.PROJECT_ID, cgsnapshot.id)) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -87,7 +87,7 @@ class CgsnapshotsAPITestCase(test.TestCase): consistencygroup.destroy() def test_show_cgsnapshot_with_cgsnapshot_NotFound(self): - req = webob.Request.blank('/v2/%s/cgsnapshots/%s' % ( + req = webob.Request.blank('/v3/%s/cgsnapshots/%s' % ( fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID)) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -123,7 +123,7 @@ class CgsnapshotsAPITestCase(test.TestCase): self.context, group_id=consistencygroup.id, group_type_id=fake.GROUP_TYPE_ID,) - req = webob.Request.blank('/v2/%s/cgsnapshots' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/cgsnapshots' % fake.PROJECT_ID) req.method = 'GET' req.headers['Content-Type'] = 'application/json' res = req.get_response(fakes.wsgi_app( @@ -171,7 +171,7 @@ class CgsnapshotsAPITestCase(test.TestCase): self.context, group_id=consistencygroup.id, group_type_id=fake.GROUP_TYPE_ID,) - req = webob.Request.blank('/v2/%s/cgsnapshots/detail' % + req = webob.Request.blank('/v3/%s/cgsnapshots/detail' % fake.PROJECT_ID) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -232,7 +232,7 @@ class CgsnapshotsAPITestCase(test.TestCase): "description": "CG Snapshot 1", "consistencygroup_id": consistencygroup.id}} - req = webob.Request.blank('/v2/%s/cgsnapshots' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/cgsnapshots' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -270,7 +270,7 @@ class CgsnapshotsAPITestCase(test.TestCase): "description": "CG Snapshot 1", "consistencygroup_id": consistencygroup.id}} - req = webob.Request.blank('/v2/%s/cgsnapshots' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/cgsnapshots' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -293,7 +293,7 @@ class CgsnapshotsAPITestCase(test.TestCase): def test_create_cgsnapshot_with_no_body(self): # omit body from the request - req = webob.Request.blank('/v2/%s/cgsnapshots' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/cgsnapshots' % fake.PROJECT_ID) req.body = jsonutils.dump_as_bytes(None) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -327,7 +327,7 @@ class CgsnapshotsAPITestCase(test.TestCase): "description": "CG Snapshot 1", "consistencygroup_id": consistencygroup.id}} - req = webob.Request.blank('/v2/%s/cgsnapshots' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/cgsnapshots' % fake.PROJECT_ID) req.body = jsonutils.dump_as_bytes(body) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -363,7 +363,7 @@ class CgsnapshotsAPITestCase(test.TestCase): "CG Snapshot 1", "consistencygroup_id": consistencygroup.id}} - req = webob.Request.blank('/v2/%s/cgsnapshots' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/cgsnapshots' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -393,7 +393,7 @@ class CgsnapshotsAPITestCase(test.TestCase): "CG Snapshot 1", "consistencygroup_id": consistencygroup.id}} - req = webob.Request.blank('/v2/%s/cgsnapshots' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/cgsnapshots' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -427,7 +427,7 @@ class CgsnapshotsAPITestCase(test.TestCase): self.context, group_id=consistencygroup.id, group_type_id=fake.GROUP_TYPE_ID, status='available') - req = webob.Request.blank('/v2/%s/cgsnapshots/%s' % + req = webob.Request.blank('/v3/%s/cgsnapshots/%s' % (fake.PROJECT_ID, cgsnapshot.id)) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' @@ -463,7 +463,7 @@ class CgsnapshotsAPITestCase(test.TestCase): self.context, status='creating', group_snapshot_id=cgsnapshot.id, group_type_id=fake.GROUP_TYPE_ID) - req = webob.Request.blank('/v2/fake/cgsnapshots/%s' % + req = webob.Request.blank('/v3/fake/cgsnapshots/%s' % cgsnapshot.id) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' @@ -480,7 +480,7 @@ class CgsnapshotsAPITestCase(test.TestCase): cg2.destroy() def test_delete_cgsnapshot_with_cgsnapshot_NotFound(self): - req = webob.Request.blank('/v2/%s/cgsnapshots/%s' % + req = webob.Request.blank('/v3/%s/cgsnapshots/%s' % (fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID)) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' @@ -511,7 +511,7 @@ class CgsnapshotsAPITestCase(test.TestCase): group_type_id=fake.GROUP_TYPE_ID, status='invalid') - req = webob.Request.blank('/v2/%s/cgsnapshots/%s' % ( + req = webob.Request.blank('/v3/%s/cgsnapshots/%s' % ( fake.PROJECT_ID, cgsnapshot.id)) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' @@ -546,7 +546,7 @@ class CgsnapshotsAPITestCase(test.TestCase): status='available') mock_delete.side_effect = exception.PolicyNotAuthorized( message='PolicyNotAuthorized') - req = webob.Request.blank('/v2/%s/cgsnapshots/%s' % + req = webob.Request.blank('/v3/%s/cgsnapshots/%s' % (fake.PROJECT_ID, cgsnapshot.id)) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' diff --git a/cinder/tests/unit/api/contrib/test_consistencygroups.py b/cinder/tests/unit/api/contrib/test_consistencygroups.py index 760ee110583..59c958e8922 100644 --- a/cinder/tests/unit/api/contrib/test_consistencygroups.py +++ b/cinder/tests/unit/api/contrib/test_consistencygroups.py @@ -30,7 +30,7 @@ from cinder.i18n import _ from cinder import objects from cinder.objects import fields from cinder.tests.unit.api import fakes -from cinder.tests.unit.api.v2 import fakes as v2_fakes +from cinder.tests.unit.api.v3 import fakes as v3_fakes from cinder.tests.unit import fake_constants as fake from cinder.tests.unit import test from cinder.tests.unit import utils @@ -51,7 +51,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): fake.USER_ID, fake.PROJECT_ID, auth_token=True) self.admin_ctxt = context.get_admin_context() db.volume_type_create(self.admin_ctxt, - v2_fakes.fake_default_type_get( + v3_fakes.fake_default_type_get( fake.VOLUME_TYPE2_ID)) self.vol_type = db.volume_type_get_by_name(self.admin_ctxt, 'vol_type_name') @@ -90,7 +90,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): self, name='my_vol_type') consistencygroup = self._create_consistencygroup( volume_type_ids=[vol_type['id']]) - req = webob.Request.blank('/v2/%s/consistencygroups/%s' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -113,7 +113,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): res_dict['consistencygroup']['volume_types']) def test_show_consistencygroup_with_consistencygroup_NotFound(self): - req = webob.Request.blank('/v2/%s/consistencygroups/%s' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s' % (fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID)) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -130,7 +130,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): def test_show_consistencygroup_with_null_volume_type(self): consistencygroup = self._create_consistencygroup(volume_type_id=None) - req = webob.Request.blank('/v2/%s/consistencygroups/%s' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -151,16 +151,14 @@ class ConsistencyGroupsAPITestCase(test.TestCase): consistencygroup.destroy() - @ddt.data(2, 3) - def test_list_consistencygroups_json(self, version): + def test_list_consistencygroups_json(self): consistencygroup1 = self._create_consistencygroup() consistencygroup2 = self._create_consistencygroup() consistencygroup3 = self._create_consistencygroup() - req = webob.Request.blank('/v%(version)s/%(project_id)s/' + req = webob.Request.blank('/v3/%(project_id)s/' 'consistencygroups' - % {'version': version, - 'project_id': fake.PROJECT_ID}) + % {'project_id': fake.PROJECT_ID}) req.method = 'GET' req.headers['Content-Type'] = 'application/json' res = req.get_response(fakes.wsgi_app( @@ -190,9 +188,9 @@ class ConsistencyGroupsAPITestCase(test.TestCase): consistencygroup1 = self._create_consistencygroup() consistencygroup2 = self._create_consistencygroup() consistencygroup3 = self._create_consistencygroup() - url = '/v2/%s/consistencygroups?limit=1' % fake.PROJECT_ID + url = '/v3/%s/consistencygroups?limit=1' % fake.PROJECT_ID if is_detail: - url = '/v2/%s/consistencygroups/detail?limit=1' % fake.PROJECT_ID + url = '/v3/%s/consistencygroups/detail?limit=1' % fake.PROJECT_ID req = webob.Request.blank(url) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -205,7 +203,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): self.assertEqual(consistencygroup3.id, res_dict['consistencygroups'][0]['id']) next_link = ( - 'http://localhost/v2/%s/consistencygroups?limit=' + 'http://localhost/v3/%s/consistencygroups?limit=' '1&marker=%s' % (fake.PROJECT_ID, res_dict['consistencygroups'][0]['id'])) self.assertEqual(next_link, @@ -219,9 +217,9 @@ class ConsistencyGroupsAPITestCase(test.TestCase): consistencygroup1 = self._create_consistencygroup() consistencygroup2 = self._create_consistencygroup() consistencygroup3 = self._create_consistencygroup() - url = '/v2/%s/consistencygroups?offset=1' % fake.PROJECT_ID + url = '/v3/%s/consistencygroups?offset=1' % fake.PROJECT_ID if is_detail: - url = '/v2/%s/consistencygroups/detail?offset=1' % fake.PROJECT_ID + url = '/v3/%s/consistencygroups/detail?offset=1' % fake.PROJECT_ID req = webob.Request.blank(url) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -241,10 +239,10 @@ class ConsistencyGroupsAPITestCase(test.TestCase): @ddt.data(False, True) def test_list_consistencygroups_with_offset_out_of_range(self, is_detail): - url = ('/v2/%s/consistencygroups?offset=234523423455454' % + url = ('/v3/%s/consistencygroups?offset=234523423455454' % fake.PROJECT_ID) if is_detail: - url = ('/v2/%s/consistencygroups/detail?offset=234523423455454' % + url = ('/v3/%s/consistencygroups/detail?offset=234523423455454' % fake.PROJECT_ID) req = webob.Request.blank(url) req.method = 'GET' @@ -258,9 +256,9 @@ class ConsistencyGroupsAPITestCase(test.TestCase): consistencygroup1 = self._create_consistencygroup() consistencygroup2 = self._create_consistencygroup() consistencygroup3 = self._create_consistencygroup() - url = '/v2/%s/consistencygroups?limit=2&offset=1' % fake.PROJECT_ID + url = '/v3/%s/consistencygroups?limit=2&offset=1' % fake.PROJECT_ID if is_detail: - url = ('/v2/%s/consistencygroups/detail?limit=2&offset=1' % + url = ('/v3/%s/consistencygroups/detail?limit=2&offset=1' % fake.PROJECT_ID) req = webob.Request.blank(url) req.method = 'GET' @@ -287,11 +285,11 @@ class ConsistencyGroupsAPITestCase(test.TestCase): auth_token=True, is_admin=False) consistencygroup3 = self._create_consistencygroup(ctxt=common_ctxt) - url = ('/v2/%s/consistencygroups?' + url = ('/v3/%s/consistencygroups?' 'all_tenants=True&id=%s') % (fake.PROJECT_ID, consistencygroup3.id) if is_detail: - url = ('/v2/%s/consistencygroups/detail?' + url = ('/v3/%s/consistencygroups/detail?' 'all_tenants=True&id=%s') % (fake.PROJECT_ID, consistencygroup3.id) req = webob.Request.blank(url) @@ -314,11 +312,11 @@ class ConsistencyGroupsAPITestCase(test.TestCase): consistencygroup2 = self._create_consistencygroup( name="group", project_id=fake.PROJECT2_ID) - url = ('/v2/%s/consistencygroups?' + url = ('/v3/%s/consistencygroups?' 'all_tenants=True&project_id=%s') % (fake.PROJECT_ID, fake.PROJECT2_ID) if is_detail: - url = ('/v2/%s/consistencygroups/detail?' + url = ('/v3/%s/consistencygroups/detail?' 'all_tenants=True&project_id=%s') % (fake.PROJECT_ID, fake.PROJECT2_ID) req = webob.Request.blank(url) @@ -338,9 +336,9 @@ class ConsistencyGroupsAPITestCase(test.TestCase): consistencygroup1 = self._create_consistencygroup() consistencygroup2 = self._create_consistencygroup() consistencygroup3 = self._create_consistencygroup() - url = '/v2/%s/consistencygroups?sort=id:asc' % fake.PROJECT_ID + url = '/v3/%s/consistencygroups?sort=id:asc' % fake.PROJECT_ID if is_detail: - url = ('/v2/%s/consistencygroups/detail?sort=id:asc' % + url = ('/v3/%s/consistencygroups/detail?sort=id:asc' % fake.PROJECT_ID) req = webob.Request.blank(url) req.method = 'GET' @@ -375,7 +373,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): volume_type_ids=[vol_type1['id']]) consistencygroup3 = self._create_consistencygroup( volume_type_ids=[vol_type1['id'], vol_type2['id']]) - req = webob.Request.blank('/v2/%s/consistencygroups/detail' % + req = webob.Request.blank('/v3/%s/consistencygroups/detail' % fake.PROJECT_ID) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -443,7 +441,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): "volume_types": vol_type_id, "description": "Consistency Group 1", }} - req = webob.Request.blank('/v2/%s/consistencygroups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/consistencygroups' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -462,7 +460,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): def test_create_consistencygroup_with_no_body(self): # omit body from the request - req = webob.Request.blank('/v2/%s/consistencygroups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/consistencygroups' % fake.PROJECT_ID) req.body = jsonutils.dump_as_bytes(None) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -481,7 +479,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): def test_delete_consistencygroup_available(self): consistencygroup = self._create_consistencygroup( status=fields.ConsistencyGroupStatus.AVAILABLE) - req = webob.Request.blank('/v2/%s/consistencygroups/%s/delete' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/delete' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -498,7 +496,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): def test_delete_consistencygroup_available_used_as_source_success(self): consistencygroup = self._create_consistencygroup( status=fields.ConsistencyGroupStatus.AVAILABLE) - req = webob.Request.blank('/v2/%s/consistencygroups/%s/delete' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/delete' % (fake.PROJECT_ID, consistencygroup.id)) # The other CG used the first CG as source, but it's no longer in # creating status, so we should be able to delete it. @@ -520,7 +518,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): def test_delete_consistencygroup_available_no_force(self): consistencygroup = self._create_consistencygroup(status='available') - req = webob.Request.blank('/v2/%s/consistencygroups/%s/delete' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/delete' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -538,7 +536,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): consistencygroup.destroy() def test_delete_consistencygroup_with_consistencygroup_NotFound(self): - req = webob.Request.blank('/v2/%s/consistencygroups/%s/delete' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/delete' % (fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -563,7 +561,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): def test_delete_consistencygroup_invalid_force(self): consistencygroup = self._create_consistencygroup( status=fields.ConsistencyGroupStatus.CREATING) - req = webob.Request.blank('/v2/%s/consistencygroups/%s/delete' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/delete' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -580,7 +578,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): consistencygroup = self._create_consistencygroup( host=None, status=fields.ConsistencyGroupStatus.ERROR) - req = webob.Request.blank('/v2/%s/consistencygroups/%s/delete' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/delete' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -634,7 +632,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): def test_delete_consistencygroup_with_invalid_body(self): consistencygroup = self._create_consistencygroup( status=fields.ConsistencyGroupStatus.AVAILABLE) - req = webob.Request.blank('/v2/%s/consistencygroups/%s/delete' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/delete' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -648,7 +646,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): def test_delete_consistencygroup_with_invalid_force_value_in_body(self): consistencygroup = self._create_consistencygroup( status=fields.ConsistencyGroupStatus.AVAILABLE) - req = webob.Request.blank('/v2/%s/consistencygroups/%s/delete' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/delete' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -662,7 +660,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): def test_delete_consistencygroup_with_empty_force_value_in_body(self): consistencygroup = self._create_consistencygroup( status=fields.ConsistencyGroupStatus.AVAILABLE) - req = webob.Request.blank('/v2/%s/consistencygroups/%s/delete' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/delete' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -674,7 +672,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): self.assertEqual(HTTPStatus.BAD_REQUEST, res.status_int) def _assert_deleting_result_400(self, cg_id, force=False): - req = webob.Request.blank('/v2/%s/consistencygroups/%s/delete' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/delete' % (fake.PROJECT_ID, cg_id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -730,7 +728,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): utils.create_volume(self.ctxt, consistencygroup_id=consistencygroup.id, testcase_instance=self) - req = webob.Request.blank('/v2/%s/consistencygroups/%s/delete' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/delete' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -751,7 +749,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): utils.create_snapshot(self.ctxt, vol.id, status='deleted', deleted=True, testcase_instance=self) - req = webob.Request.blank('/v2/%s/consistencygroups/%s/delete' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/delete' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -770,7 +768,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): body = {"consistencygroup": {"name": name, "description": "Consistency Group 1", }} - req = webob.Request.blank('/v2/%s/consistencygroups' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/consistencygroups' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' req.body = jsonutils.dump_as_bytes(body) @@ -841,7 +839,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): self.ctxt, testcase_instance=self, volume_type_id=volume_type_id)['id'] - req = webob.Request.blank('/v2/%s/consistencygroups/%s/update' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/update' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'PUT' req.headers['Content-Type'] = 'application/json' @@ -890,7 +888,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): volume_type_id=volume_type_id, consistencygroup_id=consistencygroup.id)['id'] - req = webob.Request.blank('/v2/%s/consistencygroups/%s/update' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/update' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'PUT' req.headers['Content-Type'] = 'application/json' @@ -935,7 +933,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): self.ctxt, volume_type_id=volume_type_id)['id'] - req = webob.Request.blank('/v2/%s/consistencygroups/%s/update' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/update' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'PUT' req.headers['Content-Type'] = 'application/json' @@ -961,7 +959,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): consistencygroup = self._create_consistencygroup( ctxt=self.ctxt, status=fields.ConsistencyGroupStatus.AVAILABLE) - req = webob.Request.blank('/v2/%s/consistencygroups/%s/update' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/update' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'PUT' req.headers['Content-Type'] = 'application/json' @@ -985,7 +983,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): consistencygroup = self._create_consistencygroup( ctxt=self.ctxt, status=fields.ConsistencyGroupStatus.AVAILABLE) - req = webob.Request.blank('/v2/%s/consistencygroups/%s/update' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/update' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'PUT' req.headers['Content-Type'] = 'application/json' @@ -1009,7 +1007,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): consistencygroup = self._create_consistencygroup( ctxt=self.ctxt, status=fields.ConsistencyGroupStatus.AVAILABLE) - req = webob.Request.blank('/v2/%s/consistencygroups/%s/update' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/update' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'PUT' req.headers['Content-Type'] = 'application/json' @@ -1037,7 +1035,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): self.ctxt, volume_type_id=volume_type_id, status='wrong_status')['id'] - req = webob.Request.blank('/v2/%s/consistencygroups/%s/update' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/update' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'PUT' req.headers['Content-Type'] = 'application/json' @@ -1066,7 +1064,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): add_volume_id = utils.create_volume( self.ctxt, volume_type_id=wrong_type)['id'] - req = webob.Request.blank('/v2/%s/consistencygroups/%s/update' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/update' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'PUT' req.headers['Content-Type'] = 'application/json' @@ -1094,7 +1092,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): add_volume_id = utils.create_volume( self.ctxt, consistencygroup_id=fake.CONSISTENCY_GROUP2_ID)['id'] - req = webob.Request.blank('/v2/%s/consistencygroups/%s/update' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/update' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'PUT' req.headers['Content-Type'] = 'application/json' @@ -1126,7 +1124,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): self.ctxt, testcase_instance=self, volume_type_id=volume_type_id)['id'] - req = webob.Request.blank('/v2/%s/consistencygroups/%s/update' % + req = webob.Request.blank('/v3/%s/consistencygroups/%s/update' % (fake.PROJECT_ID, consistencygroup.id)) req.method = 'PUT' req.headers['Content-Type'] = 'application/json' @@ -1151,7 +1149,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): @mock.patch('cinder.scheduler.rpcapi.SchedulerAPI.validate_host_capacity') def test_create_consistencygroup_from_src_snap(self, mock_validate_host, mock_validate): - self.mock_object(volume_api.API, "create", v2_fakes.fake_volume_create) + self.mock_object(volume_api.API, "create", v3_fakes.fake_volume_create) consistencygroup = utils.create_group( self.ctxt, group_type_id=fake.GROUP_TYPE_ID, @@ -1175,7 +1173,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): "description": "Consistency Group 1", "cgsnapshot_id": cgsnapshot.id}} - req = webob.Request.blank('/v2/%s/consistencygroups/create_from_src' % + req = webob.Request.blank('/v3/%s/consistencygroups/create_from_src' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1201,7 +1199,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): @mock.patch('cinder.scheduler.rpcapi.SchedulerAPI.validate_host_capacity') def test_create_consistencygroup_from_src_cg(self, mock_validate): - self.mock_object(volume_api.API, "create", v2_fakes.fake_volume_create) + self.mock_object(volume_api.API, "create", v3_fakes.fake_volume_create) source_cg = utils.create_group( self.ctxt, group_type_id=fake.GROUP_TYPE_ID, @@ -1217,7 +1215,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): "description": "Consistency Group 1", "source_cgid": source_cg.id}} - req = webob.Request.blank('/v2/%s/consistencygroups/create_from_src' % + req = webob.Request.blank('/v3/%s/consistencygroups/create_from_src' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1237,7 +1235,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): source_cg.destroy() def test_create_consistencygroup_from_src_both_snap_cg(self): - self.mock_object(volume_api.API, "create", v2_fakes.fake_volume_create) + self.mock_object(volume_api.API, "create", v3_fakes.fake_volume_create) consistencygroup = utils.create_group( self.ctxt, group_type_id=fake.GROUP_TYPE_ID, @@ -1263,7 +1261,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): "cgsnapshot_id": cgsnapshot_id, "source_cgid": consistencygroup.id}} - req = webob.Request.blank('/v2/%s/consistencygroups/create_from_src' % + req = webob.Request.blank('/v3/%s/consistencygroups/create_from_src' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1287,7 +1285,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): body = {"invalid": {"name": name, "description": "Consistency Group 1", }} - req = webob.Request.blank('/v2/%s/consistencygroups/create_from_src' % + req = webob.Request.blank('/v3/%s/consistencygroups/create_from_src' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1307,7 +1305,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): body = {"consistencygroup-from-src": {"name": name, "description": "Consistency Group 1", }} - req = webob.Request.blank('/v2/%s/consistencygroups/create_from_src' % + req = webob.Request.blank('/v3/%s/consistencygroups/create_from_src' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1342,7 +1340,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): "description": "Consistency Group 1", "cgsnapshot_id": cgsnapshot.id}} - req = webob.Request.blank('/v2/%s/consistencygroups/create_from_src' % + req = webob.Request.blank('/v3/%s/consistencygroups/create_from_src' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1381,7 +1379,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): "description": "Consistency Group 1", "cgsnapshot_id": cgsnapshot.id}} - req = webob.Request.blank('/v2/%s/consistencygroups/create_from_src' % + req = webob.Request.blank('/v3/%s/consistencygroups/create_from_src' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1412,7 +1410,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): "description": "Consistency Group 1", "source_cgid": source_cg.id}} - req = webob.Request.blank('/v2/%s/consistencygroups/create_from_src' % + req = webob.Request.blank('/v3/%s/consistencygroups/create_from_src' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1445,7 +1443,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): "source_cgid": fake.CGSNAPSHOT_ID } } - req = webob.Request.blank('/v2/%s/consistencygroups/create_from_src' % + req = webob.Request.blank('/v3/%s/consistencygroups/create_from_src' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1472,7 +1470,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): "source_cgid": fake.CONSISTENCY_GROUP_ID } } - req = webob.Request.blank('/v2/%s/consistencygroups/create_from_src' % + req = webob.Request.blank('/v3/%s/consistencygroups/create_from_src' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1513,7 +1511,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): "description": "Consistency Group 1", "cgsnapshot_id": cgsnapshot.id}} - req = webob.Request.blank('/v2/%s/consistencygroups/create_from_src' % + req = webob.Request.blank('/v3/%s/consistencygroups/create_from_src' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1554,7 +1552,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase): "description": "Consistency Group 1", "source_cgid": source_cg.id}} - req = webob.Request.blank('/v2/%s/consistencygroups/create_from_src' % + req = webob.Request.blank('/v3/%s/consistencygroups/create_from_src' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' diff --git a/cinder/tests/unit/api/contrib/test_extended_snapshot_attributes.py b/cinder/tests/unit/api/contrib/test_extended_snapshot_attributes.py index f7e73119a87..a10f1021a34 100644 --- a/cinder/tests/unit/api/contrib/test_extended_snapshot_attributes.py +++ b/cinder/tests/unit/api/contrib/test_extended_snapshot_attributes.py @@ -98,7 +98,7 @@ class ExtendedSnapshotAttributesTest(test.TestCase): snapshot_get_by_id.return_value = snapshot_obj volume_get_by_id.return_value = fake_volume_obj - url = '/v2/%s/snapshots/%s' % (fake.PROJECT_ID, UUID1) + url = '/v3/%s/snapshots/%s' % (fake.PROJECT_ID, UUID1) res = self._make_request(url) self.assertEqual(HTTPStatus.OK, res.status_int) @@ -111,7 +111,7 @@ class ExtendedSnapshotAttributesTest(test.TestCase): @mock.patch('cinder.context.RequestContext.authorize') def test_detail(self, mock_authorize): - url = '/v2/%s/snapshots/detail' % fake.PROJECT_ID + url = '/v3/%s/snapshots/detail' % fake.PROJECT_ID res = self._make_request(url) mock_authorize.return_value = False diff --git a/cinder/tests/unit/api/contrib/test_qos_specs_manage.py b/cinder/tests/unit/api/contrib/test_qos_specs_manage.py index 83fe2b5453a..1590ddff60d 100644 --- a/cinder/tests/unit/api/contrib/test_qos_specs_manage.py +++ b/cinder/tests/unit/api/contrib/test_qos_specs_manage.py @@ -177,7 +177,7 @@ class QoSSpecManageApiTest(test.TestCase): @mock.patch('cinder.volume.qos_specs.get_all_specs', side_effect=return_qos_specs_get_all) def test_index(self, mock_get_all_specs): - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs' % fake.PROJECT_ID, + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs' % fake.PROJECT_ID, use_admin_context=True) res = self.controller.index(req) @@ -193,7 +193,7 @@ class QoSSpecManageApiTest(test.TestCase): self.assertEqual(set(expected_names), names) def test_index_with_limit(self): - url = '/v2/%s/qos-specs?limit=2' % fake.PROJECT_ID + url = '/v3/%s/qos-specs?limit=2' % fake.PROJECT_ID req = fakes.HTTPRequest.blank(url, use_admin_context=True) res = self.controller.index(req) @@ -201,26 +201,26 @@ class QoSSpecManageApiTest(test.TestCase): self.assertEqual(self.qos_id4, res['qos_specs'][0]['id']) self.assertEqual(self.qos_id3, res['qos_specs'][1]['id']) - expect_next_link = ('http://localhost/v2/%s/qos-specs?limit' + expect_next_link = ('http://localhost/v3/%s/qos-specs?limit' '=2&marker=%s') % ( fake.PROJECT_ID, res['qos_specs'][1]['id']) self.assertEqual(expect_next_link, res['qos_specs_links'][0]['href']) def test_index_with_offset(self): - url = '/v2/%s/qos-specs?offset=1' % fake.PROJECT_ID + url = '/v3/%s/qos-specs?offset=1' % fake.PROJECT_ID req = fakes.HTTPRequest.blank(url, use_admin_context=True) res = self.controller.index(req) self.assertEqual(3, len(res['qos_specs'])) def test_index_with_offset_out_of_range(self): - url = '/v2/%s/qos-specs?offset=356576877698707' % fake.PROJECT_ID + url = '/v3/%s/qos-specs?offset=356576877698707' % fake.PROJECT_ID req = fakes.HTTPRequest.blank(url, use_admin_context=True) self.assertRaises(webob.exc.HTTPBadRequest, self.controller.index, req) def test_index_with_limit_and_offset(self): - url = '/v2/%s/qos-specs?limit=2&offset=1' % fake.PROJECT_ID + url = '/v3/%s/qos-specs?limit=2&offset=1' % fake.PROJECT_ID req = fakes.HTTPRequest.blank(url, use_admin_context=True) res = self.controller.index(req) @@ -229,14 +229,14 @@ class QoSSpecManageApiTest(test.TestCase): self.assertEqual(self.qos_id2, res['qos_specs'][1]['id']) def test_index_with_marker(self): - url = '/v2/%s/qos-specs?marker=%s' % (fake.PROJECT_ID, self.qos_id4) + url = '/v3/%s/qos-specs?marker=%s' % (fake.PROJECT_ID, self.qos_id4) req = fakes.HTTPRequest.blank(url, use_admin_context=True) res = self.controller.index(req) self.assertEqual(3, len(res['qos_specs'])) def test_index_with_filter(self): - url = '/v2/%s/qos-specs?id=%s' % (fake.PROJECT_ID, self.qos_id4) + url = '/v3/%s/qos-specs?id=%s' % (fake.PROJECT_ID, self.qos_id4) req = fakes.HTTPRequest.blank(url, use_admin_context=True) res = self.controller.index(req) @@ -244,7 +244,7 @@ class QoSSpecManageApiTest(test.TestCase): self.assertEqual(self.qos_id4, res['qos_specs'][0]['id']) def test_index_with_sort_keys(self): - url = '/v2/%s/qos-specs?sort=id' % fake.PROJECT_ID + url = '/v3/%s/qos-specs?sort=id' % fake.PROJECT_ID req = fakes.HTTPRequest.blank(url, use_admin_context=True) res = self.controller.index(req) self.assertEqual(4, len(res['qos_specs'])) @@ -258,7 +258,7 @@ class QoSSpecManageApiTest(test.TestCase): self.assertEqual(expect_result[3], res['qos_specs'][3]['id']) def test_index_with_sort_keys_and_sort_dirs(self): - url = '/v2/%s/qos-specs?sort=id:asc' % fake.PROJECT_ID + url = '/v3/%s/qos-specs?sort=id:asc' % fake.PROJECT_ID req = fakes.HTTPRequest.blank(url, use_admin_context=True) res = self.controller.index(req) self.assertEqual(4, len(res['qos_specs'])) @@ -276,7 +276,7 @@ class QoSSpecManageApiTest(test.TestCase): @mock.patch('cinder.volume.qos_specs.delete', side_effect=return_qos_specs_delete) def test_qos_specs_delete(self, mock_qos_delete, mock_qos_get_specs): - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs/%s' % ( fake.PROJECT_ID, fake.QOS_SPEC_ID), use_admin_context=True) self.controller.delete(req, fake.QOS_SPEC_ID) self.assertEqual(1, self.notifier.get_notification_count()) @@ -287,7 +287,7 @@ class QoSSpecManageApiTest(test.TestCase): side_effect=return_qos_specs_delete) def test_qos_specs_delete_not_found(self, mock_qos_delete, mock_qos_get_specs): - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs/%s' % + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs/%s' % (fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID), use_admin_context=True) @@ -302,7 +302,7 @@ class QoSSpecManageApiTest(test.TestCase): side_effect=return_qos_specs_delete) def test_qos_specs_delete_inuse(self, mock_qos_delete, mock_qos_get_specs): - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs/%s' % ( fake.PROJECT_ID, fake.IN_USE_ID), use_admin_context=True) self.assertRaises(webob.exc.HTTPBadRequest, self.controller.delete, @@ -315,7 +315,7 @@ class QoSSpecManageApiTest(test.TestCase): side_effect=return_qos_specs_delete) def test_qos_specs_delete_inuse_force(self, mock_qos_delete, mock_qos_get_specs): - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs/%s?force=True' % + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs/%s?force=True' % (fake.PROJECT_ID, fake.IN_USE_ID), use_admin_context=True) @@ -327,7 +327,7 @@ class QoSSpecManageApiTest(test.TestCase): def test_qos_specs_delete_with_invalid_force(self): invalid_force = "invalid_bool" req = fakes.HTTPRequest.blank( - '/v2/%s/qos-specs/%s/delete_keys?force=%s' % + '/v3/%s/qos-specs/%s/delete_keys?force=%s' % (fake.PROJECT_ID, fake.QOS_SPEC_ID, invalid_force), use_admin_context=True) @@ -342,7 +342,7 @@ class QoSSpecManageApiTest(test.TestCase): def test_qos_specs_delete_keys(self, mock_qos_delete_keys, mock_get_qos): body = {"keys": ['bar', 'zoo']} - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs/%s/delete_keys' % + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs/%s/delete_keys' % (fake.PROJECT_ID, fake.IN_USE_ID), use_admin_context=True) @@ -353,7 +353,7 @@ class QoSSpecManageApiTest(test.TestCase): side_effect=return_qos_specs_delete_keys) def test_qos_specs_delete_keys_qos_notfound(self, mock_qos_specs_delete): body = {"keys": ['bar', 'zoo']} - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs/%s/delete_keys' % + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs/%s/delete_keys' % (fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID), use_admin_context=True) @@ -365,7 +365,7 @@ class QoSSpecManageApiTest(test.TestCase): def test_qos_specs_delete_keys_invalid_key(self): body = {"keys": ['', None]} - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs/%s/delete_keys' % + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs/%s/delete_keys' % (fake.PROJECT_ID, fake.IN_USE_ID), use_admin_context=True) @@ -380,7 +380,7 @@ class QoSSpecManageApiTest(test.TestCase): side_effect=return_qos_specs_delete_keys) def test_qos_specs_delete_keys_badkey(self, mock_qos_specs_delete, mock_get_qos): - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs/%s/delete_keys' % + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs/%s/delete_keys' % (fake.PROJECT_ID, fake.IN_USE_ID), use_admin_context=True) body = {"keys": ['foo', 'zoo']} @@ -397,7 +397,7 @@ class QoSSpecManageApiTest(test.TestCase): def test_qos_specs_delete_keys_get_notifier(self, mock_get_qos_specs, mock_qos_delete_keys): body = {"keys": ['bar', 'zoo']} - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs/%s/delete_keys' % + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs/%s/delete_keys' % (fake.PROJECT_ID, fake.IN_USE_ID), use_admin_context=True) @@ -410,7 +410,7 @@ class QoSSpecManageApiTest(test.TestCase): body = {"qos_specs": {"name": "qos_specs_%s" % fake.QOS_SPEC_ID, "key1": "value1"}} - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs' % + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs' % fake.PROJECT_ID, use_admin_context=True) @@ -425,7 +425,7 @@ class QoSSpecManageApiTest(test.TestCase): def test_create_invalid_input(self, mock_qos_get_specs): body = {"qos_specs": {"name": 'qos_spec_%s' % fake.INVALID_ID, "consumer": "invalid_consumer"}} - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs' % fake.PROJECT_ID, + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs' % fake.PROJECT_ID, use_admin_context=True) self.assertRaises(webob.exc.HTTPBadRequest, @@ -437,7 +437,7 @@ class QoSSpecManageApiTest(test.TestCase): def test_create_conflict(self, mock_qos_spec_create): body = {"qos_specs": {"name": 'qos_spec_%s' % fake.ALREADY_EXISTS_ID, "key1": "value1"}} - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs' % fake.PROJECT_ID, + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs' % fake.PROJECT_ID, use_admin_context=True) self.assertRaises(webob.exc.HTTPConflict, @@ -449,7 +449,7 @@ class QoSSpecManageApiTest(test.TestCase): def test_create_failed(self, mock_qos_spec_create): body = {"qos_specs": {"name": 'qos_spec_%s' % fake.ACTION_FAILED_ID, "key1": "value1"}} - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs' % fake.PROJECT_ID, + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs' % fake.PROJECT_ID, use_admin_context=True) self.assertRaises(webob.exc.HTTPInternalServerError, @@ -461,7 +461,7 @@ class QoSSpecManageApiTest(test.TestCase): {'qos_specs': 'string'}, None) def test_create_invalid_body_bad_request(self, body): - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs' % fake.PROJECT_ID, + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs' % fake.PROJECT_ID, use_admin_context=True) req.method = 'POST' self.assertRaises(exception.ValidationError, @@ -472,7 +472,7 @@ class QoSSpecManageApiTest(test.TestCase): {'name': 'fake_name', '': 'a'}) def test_create_qos_with_invalid_specs(self, value): body = {'qos_specs': value} - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs' % fake.PROJECT_ID, + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs' % fake.PROJECT_ID, use_admin_context=True) req.method = 'POST' self.assertRaises(exception.InvalidInput, @@ -485,7 +485,7 @@ class QoSSpecManageApiTest(test.TestCase): @ddt.unpack def test_create_qos_with_invalid_spec_name(self, value, exception_class): body = {'qos_specs': value} - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs' % fake.PROJECT_ID, + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs' % fake.PROJECT_ID, use_admin_context=True) req.method = 'POST' self.assertRaises(exception_class, @@ -496,7 +496,7 @@ class QoSSpecManageApiTest(test.TestCase): @mock.patch('cinder.volume.qos_specs.get_qos_specs', side_effect=return_qos_specs_get_qos_specs) def test_update(self, mock_get_qos, mock_qos_update): - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs/%s' % + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs/%s' % (fake.PROJECT_ID, fake.QOS_SPEC_ID), use_admin_context=True) body = {'qos_specs': {'key1': 'value1', @@ -510,7 +510,7 @@ class QoSSpecManageApiTest(test.TestCase): @mock.patch('cinder.volume.qos_specs.get_qos_specs', side_effect=return_qos_specs_get_qos_specs) def test_update_not_found(self, mock_get_qos_specs, mock_qos_update): - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs/%s' % + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs/%s' % (fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID), use_admin_context=True) @@ -526,7 +526,7 @@ class QoSSpecManageApiTest(test.TestCase): @mock.patch('cinder.volume.qos_specs.update', side_effect=return_qos_specs_update) def test_update_invalid_input(self, mock_qos_update, mock_get_qos): - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs/%s' % + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs/%s' % (fake.PROJECT_ID, fake.INVALID_ID), use_admin_context=True) body = {'qos_specs': {'key1': 'value1', @@ -542,7 +542,7 @@ class QoSSpecManageApiTest(test.TestCase): {'qos_specs': {1: 'value1'}} ) def test_update_non_string_key_or_value(self, body, mock_get_qos): - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs/%s' % + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs/%s' % (fake.PROJECT_ID, fake.UUID1), use_admin_context=True) self.assertRaises(exception.ValidationError, @@ -555,7 +555,7 @@ class QoSSpecManageApiTest(test.TestCase): @mock.patch('cinder.volume.qos_specs.update', side_effect=return_qos_specs_update) def test_update_failed(self, mock_qos_update, mock_get_qos): - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs/%s' % + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs/%s' % (fake.PROJECT_ID, fake.UPDATE_FAILED_ID), use_admin_context=True) @@ -569,7 +569,7 @@ class QoSSpecManageApiTest(test.TestCase): @mock.patch('cinder.volume.qos_specs.get_qos_specs', side_effect=return_qos_specs_get_qos_specs) def test_show(self, mock_get_qos_specs): - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs/%s' % ( fake.PROJECT_ID, fake.QOS_SPEC_ID), use_admin_context=True) res_dict = self.controller.show(req, fake.QOS_SPEC_ID) @@ -583,7 +583,7 @@ class QoSSpecManageApiTest(test.TestCase): side_effect=return_qos_specs_get_qos_specs) def test_get_associations(self, mock_get_qos, mock_get_assciations): req = fakes.HTTPRequest.blank( - '/v2/%s/qos-specs/%s/associations' % ( + '/v3/%s/qos-specs/%s/associations' % ( fake.PROJECT_ID, fake.QOS_SPEC_ID), use_admin_context=True) res = self.controller.associations(req, fake.QOS_SPEC_ID) @@ -596,7 +596,7 @@ class QoSSpecManageApiTest(test.TestCase): side_effect=return_get_qos_associations) def test_get_associations_not_found(self, mock_get_assciations): req = fakes.HTTPRequest.blank( - '/v2/%s/qos-specs/%s/associations' % + '/v3/%s/qos-specs/%s/associations' % (fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID), use_admin_context=True) self.assertRaises(exception.QoSSpecsNotFound, @@ -610,7 +610,7 @@ class QoSSpecManageApiTest(test.TestCase): def test_get_associations_failed(self, mock_get_qos, mock_get_associations): req = fakes.HTTPRequest.blank( - '/v2/%s/qos-specs/%s/associations' % ( + '/v3/%s/qos-specs/%s/associations' % ( fake.PROJECT_ID, fake.RAISE_ID), use_admin_context=True) self.assertRaises(webob.exc.HTTPInternalServerError, self.controller.associations, @@ -622,7 +622,7 @@ class QoSSpecManageApiTest(test.TestCase): side_effect=return_associate_qos_specs) def test_associate(self, mock_associate, mock_get_qos): req = fakes.HTTPRequest.blank( - '/v2/%s/qos-specs/%s/associate?vol_type_id=%s' % + '/v3/%s/qos-specs/%s/associate?vol_type_id=%s' % (fake.PROJECT_ID, fake.QOS_SPEC_ID, fake.VOLUME_TYPE_ID), use_admin_context=True) res = self.controller.associate(req, fake.QOS_SPEC_ID) @@ -634,7 +634,7 @@ class QoSSpecManageApiTest(test.TestCase): @mock.patch('cinder.volume.qos_specs.associate_qos_with_type', side_effect=return_associate_qos_specs) def test_associate_no_type(self, mock_associate, mock_get_qos): - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs/%s/associate' % + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs/%s/associate' % (fake.PROJECT_ID, fake.QOS_SPEC_ID), use_admin_context=True) self.assertRaises(webob.exc.HTTPBadRequest, @@ -646,7 +646,7 @@ class QoSSpecManageApiTest(test.TestCase): side_effect=return_associate_qos_specs) def test_associate_not_found(self, mock_associate, mock_get_qos): req = fakes.HTTPRequest.blank( - '/v2/%s/qos-specs/%s/associate?vol_type_id=%s' % ( + '/v3/%s/qos-specs/%s/associate?vol_type_id=%s' % ( fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID, fake.VOLUME_TYPE_ID), use_admin_context=True) self.assertRaises(exception.QoSSpecsNotFound, @@ -654,7 +654,7 @@ class QoSSpecManageApiTest(test.TestCase): fake.WILL_NOT_BE_FOUND_ID) req = fakes.HTTPRequest.blank( - '/v2/%s/qos-specs/%s/associate?vol_type_id=%s' % + '/v3/%s/qos-specs/%s/associate?vol_type_id=%s' % (fake.PROJECT_ID, fake.QOS_SPEC_ID, fake.WILL_NOT_BE_FOUND_ID), use_admin_context=True) @@ -667,7 +667,7 @@ class QoSSpecManageApiTest(test.TestCase): side_effect=return_associate_qos_specs) def test_associate_fail(self, mock_associate, mock_get_qos): req = fakes.HTTPRequest.blank( - '/v2/%s/qos-specs/%s/associate?vol_type_id=%s' % + '/v3/%s/qos-specs/%s/associate?vol_type_id=%s' % (fake.PROJECT_ID, fake.ACTION_FAILED_ID, fake.VOLUME_TYPE_ID), use_admin_context=True) self.assertRaises(webob.exc.HTTPInternalServerError, @@ -680,7 +680,7 @@ class QoSSpecManageApiTest(test.TestCase): side_effect=return_associate_qos_specs) def test_disassociate(self, mock_disassociate, mock_get_qos): req = fakes.HTTPRequest.blank( - '/v2/%s/qos-specs/%s/disassociate?vol_type_id=%s' % ( + '/v3/%s/qos-specs/%s/disassociate?vol_type_id=%s' % ( fake.PROJECT_ID, fake.QOS_SPEC_ID, fake.VOLUME_TYPE_ID), use_admin_context=True) res = self.controller.disassociate(req, fake.QOS_SPEC_ID) @@ -692,7 +692,7 @@ class QoSSpecManageApiTest(test.TestCase): side_effect=return_associate_qos_specs) def test_disassociate_no_type(self, mock_disassociate, mock_get_qos): req = fakes.HTTPRequest.blank( - '/v2/%s/qos-specs/%s/disassociate' % ( + '/v3/%s/qos-specs/%s/disassociate' % ( fake.PROJECT_ID, fake.QOS_SPEC_ID), use_admin_context=True) self.assertRaises(webob.exc.HTTPBadRequest, @@ -704,7 +704,7 @@ class QoSSpecManageApiTest(test.TestCase): side_effect=return_associate_qos_specs) def test_disassociate_not_found(self, mock_disassociate, mock_get_qos): req = fakes.HTTPRequest.blank( - '/v2/%s/qos-specs/%s/disassociate?vol_type_id=%s' % ( + '/v3/%s/qos-specs/%s/disassociate?vol_type_id=%s' % ( fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID, fake.VOLUME_TYPE_ID), use_admin_context=True) self.assertRaises(exception.QoSSpecsNotFound, @@ -712,7 +712,7 @@ class QoSSpecManageApiTest(test.TestCase): fake.WILL_NOT_BE_FOUND_ID) req = fakes.HTTPRequest.blank( - '/v2/%s/qos-specs/%s/disassociate?vol_type_id=%s' % + '/v3/%s/qos-specs/%s/disassociate?vol_type_id=%s' % (fake.PROJECT_ID, fake.VOLUME_TYPE_ID, fake.WILL_NOT_BE_FOUND_ID), use_admin_context=True) self.assertRaises(exception.VolumeTypeNotFound, @@ -725,7 +725,7 @@ class QoSSpecManageApiTest(test.TestCase): side_effect=return_associate_qos_specs) def test_disassociate_failed(self, mock_disassociate, mock_get_qos): req = fakes.HTTPRequest.blank( - '/v2/%s/qos-specs/%s/disassociate?vol_type_id=%s' % ( + '/v3/%s/qos-specs/%s/disassociate?vol_type_id=%s' % ( fake.PROJECT_ID, fake.ACTION2_FAILED_ID, fake.VOLUME_TYPE_ID), use_admin_context=True) self.assertRaises(webob.exc.HTTPInternalServerError, @@ -738,7 +738,7 @@ class QoSSpecManageApiTest(test.TestCase): side_effect=return_disassociate_all) def test_disassociate_all(self, mock_disassociate, mock_get_qos): req = fakes.HTTPRequest.blank( - '/v2/%s/qos-specs/%s/disassociate_all' % ( + '/v3/%s/qos-specs/%s/disassociate_all' % ( fake.PROJECT_ID, fake.QOS_SPEC_ID), use_admin_context=True) res = self.controller.disassociate_all(req, fake.QOS_SPEC_ID) self.assertEqual(HTTPStatus.ACCEPTED, res.status_int) @@ -750,7 +750,7 @@ class QoSSpecManageApiTest(test.TestCase): def test_disassociate_all_not_found(self, mock_disassociate, mock_get_qos): req = fakes.HTTPRequest.blank( - '/v2/%s/qos-specs/%s/disassociate_all' % ( + '/v3/%s/qos-specs/%s/disassociate_all' % ( fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID), use_admin_context=True) self.assertRaises(exception.QoSSpecsNotFound, @@ -763,7 +763,7 @@ class QoSSpecManageApiTest(test.TestCase): side_effect=return_disassociate_all) def test_disassociate_all_failed(self, mock_disassociate, mock_get): req = fakes.HTTPRequest.blank( - '/v2/%s/qos-specs/%s/disassociate_all' % ( + '/v3/%s/qos-specs/%s/disassociate_all' % ( fake.PROJECT_ID, fake.ACTION2_FAILED_ID), use_admin_context=True) self.assertRaises(webob.exc.HTTPInternalServerError, @@ -771,7 +771,7 @@ class QoSSpecManageApiTest(test.TestCase): fake.ACTION2_FAILED_ID) def test_index_no_admin_user(self): - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs' % + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs' % fake.PROJECT_ID, use_admin_context=False) self.assertRaises(exception.PolicyNotAuthorized, self.controller.index, req) @@ -779,13 +779,13 @@ class QoSSpecManageApiTest(test.TestCase): def test_create_no_admin_user(self): body = {"qos_specs": {"name": "qos_specs_%s" % fake.QOS_SPEC_ID, "key1": "value1"}} - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs' % + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs' % fake.PROJECT_ID, use_admin_context=False) self.assertRaises(exception.PolicyNotAuthorized, self.controller.create, req, body=body) def test_update_no_admin_user(self): - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs/%s' % + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs/%s' % (fake.PROJECT_ID, fake.QOS_SPEC_ID), use_admin_context=False) body = {'qos_specs': {'key1': 'value1', @@ -795,7 +795,7 @@ class QoSSpecManageApiTest(test.TestCase): body=body) def test_qos_specs_delete_no_admin_user(self): - req = fakes.HTTPRequest.blank('/v2/%s/qos-specs/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/qos-specs/%s' % ( fake.PROJECT_ID, fake.QOS_SPEC_ID), use_admin_context=False) self.assertRaises(exception.PolicyNotAuthorized, self.controller.delete, req, fake.QOS_SPEC_ID) diff --git a/cinder/tests/unit/api/contrib/test_scheduler_hints.py b/cinder/tests/unit/api/contrib/test_scheduler_hints.py index b0be6a8a5c5..9096e5167e0 100644 --- a/cinder/tests/unit/api/contrib/test_scheduler_hints.py +++ b/cinder/tests/unit/api/contrib/test_scheduler_hints.py @@ -23,7 +23,7 @@ import cinder from cinder.api.openstack import wsgi from cinder import context from cinder.tests.unit.api import fakes -from cinder.tests.unit.api.v2 import fakes as v2_fakes +from cinder.tests.unit.api.v3 import fakes as v3_fakes from cinder.tests.unit import fake_constants as fake from cinder.tests.unit import test @@ -36,8 +36,8 @@ class SchedulerHintsTestCase(test.TestCase): def setUp(self): super(SchedulerHintsTestCase, self).setUp() - self.fake_instance = v2_fakes.create_fake_volume(fake.VOLUME_ID, - uuid=UUID) + self.fake_instance = v3_fakes.create_volume(fake.VOLUME_ID, + uuid=UUID) self.fake_instance['created_at'] =\ datetime.datetime(2013, 1, 1, 1, 1, 1) self.fake_instance['launched_at'] =\ @@ -51,7 +51,7 @@ class SchedulerHintsTestCase(test.TestCase): self.app = fakes.wsgi_app(fake_auth_context=self.user_ctxt) self.admin_ctxt = context.get_admin_context() cinder.db.volume_type_create(self.admin_ctxt, - v2_fakes.fake_default_type_get( + v3_fakes.fake_default_type_get( fake.VOLUME_TYPE2_ID)) self.vol_type = cinder.db.volume_type_get_by_name(self.admin_ctxt, 'vol_type_name') @@ -63,10 +63,10 @@ class SchedulerHintsTestCase(test.TestCase): self.assertNotIn('scheduler_hints', kwargs['body']) return self.fake_instance - self.mock_object(cinder.api.v2.volumes.VolumeController, 'create', + self.mock_object(cinder.api.v3.volumes.VolumeController, 'create', fake_create) - req = fakes.HTTPRequest.blank('/v2/%s/volumes' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/volumes' % fake.PROJECT_ID) req.method = 'POST' req.content_type = 'application/json' body = {'id': UUID, @@ -84,10 +84,10 @@ class SchedulerHintsTestCase(test.TestCase): self.assertEqual({"a": "b"}, kwargs['body']['scheduler_hints']) return self.fake_instance - self.mock_object(cinder.api.v2.volumes.VolumeController, 'create', + self.mock_object(cinder.api.v3.volumes.VolumeController, 'create', fake_create) - req = fakes.HTTPRequest.blank('/v2/%s/volumes' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/volumes' % fake.PROJECT_ID) req.method = 'POST' req.content_type = 'application/json' body = {'id': UUID, @@ -100,7 +100,7 @@ class SchedulerHintsTestCase(test.TestCase): self.assertEqual(HTTPStatus.ACCEPTED, res.status_int) def test_create_server_bad_hints(self): - req = fakes.HTTPRequest.blank('/v2/%s/volumes' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/volumes' % fake.PROJECT_ID) req.method = 'POST' req.content_type = 'application/json' body = {'volume': { @@ -123,7 +123,7 @@ class SchedulerHintsTestCase(test.TestCase): {'query': {}}, None) def test_scheduler_hints_with_valid_body(self, value): - req = fakes.HTTPRequest.blank('/v2/%s/volumes' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/volumes' % fake.PROJECT_ID) req.method = 'POST' req.content_type = 'application/json' body = {'volume': {'size': 1, 'volume_type': self.vol_type['id']}, @@ -143,7 +143,7 @@ class SchedulerHintsTestCase(test.TestCase): {'query': None}, {'scheduler_hints'}) def test_scheduler_hints_with_invalid_body(self, value): - req = fakes.HTTPRequest.blank('/v2/%s/volumes' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/volumes' % fake.PROJECT_ID) req.method = 'POST' req.content_type = 'application/json' body = {'volume': {'size': 1}, diff --git a/cinder/tests/unit/api/contrib/test_scheduler_stats.py b/cinder/tests/unit/api/contrib/test_scheduler_stats.py index 11b1a7226ef..957956efb93 100644 --- a/cinder/tests/unit/api/contrib/test_scheduler_stats.py +++ b/cinder/tests/unit/api/contrib/test_scheduler_stats.py @@ -60,7 +60,7 @@ class SchedulerStatsAPITest(test.TestCase): @mock.patch('cinder.scheduler.rpcapi.SchedulerAPI.get_pools', schedule_rpcapi_get_pools) def test_get_pools_summary(self): - req = fakes.HTTPRequest.blank('/v2/%s/scheduler_stats' % + req = fakes.HTTPRequest.blank('/v3/%s/scheduler_stats' % fake.PROJECT_ID) req.environ['cinder.context'] = self.ctxt res = self.controller.get_pools(req) @@ -130,7 +130,7 @@ class SchedulerStatsAPITest(test.TestCase): @mock.patch('cinder.scheduler.rpcapi.SchedulerAPI.get_pools', schedule_rpcapi_get_pools) def test_get_pools_detail(self): - req = fakes.HTTPRequest.blank('/v2/%s/scheduler_stats?detail=True' % + req = fakes.HTTPRequest.blank('/v3/%s/scheduler_stats?detail=True' % fake.PROJECT_ID) req.environ['cinder.context'] = self.ctxt res = self.controller.get_pools(req) @@ -170,7 +170,7 @@ class SchedulerStatsAPITest(test.TestCase): def test_get_pools_detail_invalid_bool(self): req = fakes.HTTPRequest.blank( - '/v2/%s/scheduler_stats?detail=InvalidBool' % + '/v3/%s/scheduler_stats?detail=InvalidBool' % fake.PROJECT_ID) req.environ['cinder.context'] = self.ctxt self.assertRaises(exception.InvalidParameterValue, diff --git a/cinder/tests/unit/api/contrib/test_services.py b/cinder/tests/unit/api/contrib/test_services.py index 053f108a56d..ebe728f7cf3 100644 --- a/cinder/tests/unit/api/contrib/test_services.py +++ b/cinder/tests/unit/api/contrib/test_services.py @@ -637,7 +637,7 @@ class ServicesTest(test.TestCase): def test_services_enable_with_service_key(self): body = {'host': 'host1', 'service': constants.VOLUME_BINARY} req = fakes.HTTPRequest.blank( - '/v2/%s/os-services/enable' % fake.PROJECT_ID) + '/v3/%s/os-services/enable' % fake.PROJECT_ID) res_dict = self.controller.update(req, "enable", body) self.assertEqual('enabled', res_dict['status']) @@ -645,14 +645,14 @@ class ServicesTest(test.TestCase): def test_services_enable_with_binary_key(self): body = {'host': 'host1', 'binary': constants.VOLUME_BINARY} req = fakes.HTTPRequest.blank( - '/v2/%s/os-services/enable' % fake.PROJECT_ID) + '/v3/%s/os-services/enable' % fake.PROJECT_ID) res_dict = self.controller.update(req, "enable", body) self.assertEqual('enabled', res_dict['status']) def test_services_disable_with_service_key(self): req = fakes.HTTPRequest.blank( - '/v2/%s/os-services/disable' % fake.PROJECT_ID) + '/v3/%s/os-services/disable' % fake.PROJECT_ID) body = {'host': 'host1', 'service': constants.VOLUME_BINARY} res_dict = self.controller.update(req, "disable", body) @@ -660,7 +660,7 @@ class ServicesTest(test.TestCase): def test_services_disable_with_binary_key(self): req = fakes.HTTPRequest.blank( - '/v2/%s/os-services/disable' % fake.PROJECT_ID) + '/v3/%s/os-services/disable' % fake.PROJECT_ID) body = {'host': 'host1', 'binary': constants.VOLUME_BINARY} res_dict = self.controller.update(req, "disable", body) @@ -723,7 +723,7 @@ class ServicesTest(test.TestCase): req, "disable-log-reason", body) def test_services_failover_host(self): - url = '/v2/%s/os-services/failover_host' % fake.PROJECT_ID + url = '/v3/%s/os-services/failover_host' % fake.PROJECT_ID req = fakes.HTTPRequest.blank(url) body = {'host': 'fake_host', 'backend_id': 'fake_backend'} @@ -744,7 +744,7 @@ class ServicesTest(test.TestCase): @mock.patch('cinder.objects.ServiceList.get_all') def test_services_action_host_not_found(self, method, body, mock_get_all_services): - url = '/v2/%s/os-services/%s' % (fake.PROJECT_ID, method) + url = '/v3/%s/os-services/%s' % (fake.PROJECT_ID, method) req = fakes.HTTPRequest.blank(url) mock_get_all_services.return_value = [] msg = 'No service found with host=%s' % 'fake_host' @@ -771,7 +771,7 @@ class ServicesTest(test.TestCase): self.assertEqual(msg, result.msg) def test_services_freeze(self): - url = '/v2/%s/os-services/freeze' % fake.PROJECT_ID + url = '/v3/%s/os-services/freeze' % fake.PROJECT_ID req = fakes.HTTPRequest.blank(url) body = {'host': 'fake_host'} with mock.patch.object(self.controller.volume_api, 'freeze_host') \ @@ -782,7 +782,7 @@ class ServicesTest(test.TestCase): self.assertEqual(freeze_mock.return_value, res) def test_services_thaw(self): - url = '/v2/%s/os-services/thaw' % fake.PROJECT_ID + url = '/v3/%s/os-services/thaw' % fake.PROJECT_ID req = fakes.HTTPRequest.blank(url) body = {'host': 'fake_host'} with mock.patch.object(self.controller.volume_api, 'thaw_host') \ @@ -794,7 +794,7 @@ class ServicesTest(test.TestCase): @ddt.data('freeze', 'thaw', 'failover_host') def test_services_replication_calls_no_host(self, method): - url = '/v2/%s/os-services/%s' % (fake.PROJECT_ID, method) + url = '/v3/%s/os-services/%s' % (fake.PROJECT_ID, method) req = fakes.HTTPRequest.blank(url) self.assertRaises(exception.InvalidInput, self.controller.update, req, method, {}) diff --git a/cinder/tests/unit/api/contrib/test_snapshot_actions.py b/cinder/tests/unit/api/contrib/test_snapshot_actions.py index e2d0428c88c..fb3feb31bba 100644 --- a/cinder/tests/unit/api/contrib/test_snapshot_actions.py +++ b/cinder/tests/unit/api/contrib/test_snapshot_actions.py @@ -26,13 +26,13 @@ from cinder import db from cinder import exception from cinder.objects import fields from cinder.tests.unit.api import fakes -from cinder.tests.unit.api.v2 import fakes as v2_fakes +from cinder.tests.unit.api.v3 import fakes as v3_fakes from cinder.tests.unit import fake_constants as fake from cinder.tests.unit import test def fake_snapshot_get(context, snapshot_id): - snapshot = v2_fakes.fake_snapshot(snapshot_id) + snapshot = v3_fakes.fake_snapshot(snapshot_id) if snapshot_id == fake.SNAPSHOT_ID: snapshot['status'] = fields.SnapshotStatus.CREATING @@ -58,7 +58,7 @@ class SnapshotActionsTest(test.TestCase): body = {'os-update_snapshot_status': {'status': fields.SnapshotStatus.AVAILABLE}} - req = webob.Request.blank('/v2/%s/snapshots/%s/action' % ( + req = webob.Request.blank('/v3/%s/snapshots/%s/action' % ( fake.PROJECT_ID, fake.SNAPSHOT_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -73,7 +73,7 @@ class SnapshotActionsTest(test.TestCase): @mock.patch('cinder.db.snapshot_metadata_get', return_value=dict()) def test_update_snapshot_status_invalid_status(self, metadata_get, *args): body = {'os-update_snapshot_status': {'status': 'in-use'}} - req = webob.Request.blank('/v2/%s/snapshots/%s/action' % ( + req = webob.Request.blank('/v3/%s/snapshots/%s/action' % ( fake.PROJECT_ID, fake.SNAPSHOT_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -86,7 +86,7 @@ class SnapshotActionsTest(test.TestCase): def test_update_snapshot_status_without_status(self): self.mock_object(db, 'snapshot_get', fake_snapshot_get) body = {'os-update_snapshot_status': {}} - req = webob.Request.blank('/v2/%s/snapshots/%s/action' % ( + req = webob.Request.blank('/v3/%s/snapshots/%s/action' % ( fake.PROJECT_ID, fake.SNAPSHOT_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -104,7 +104,7 @@ class SnapshotActionsTest(test.TestCase): body = {'os-update_snapshot_status': {'status': fields.SnapshotStatus.AVAILABLE, 'progress': '50%'}} - req = webob.Request.blank('/v2/%s/snapshots/%s/action' % ( + req = webob.Request.blank('/v3/%s/snapshots/%s/action' % ( fake.PROJECT_ID, fake.SNAPSHOT_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) diff --git a/cinder/tests/unit/api/contrib/test_snapshot_manage.py b/cinder/tests/unit/api/contrib/test_snapshot_manage.py index 113241039e9..3b3980c2ecc 100644 --- a/cinder/tests/unit/api/contrib/test_snapshot_manage.py +++ b/cinder/tests/unit/api/contrib/test_snapshot_manage.py @@ -36,9 +36,9 @@ CONF = cfg.CONF def app(): # no auth, just let environ['cinder.context'] pass through - api = fakes.router.APIRouter() + api = fakes.router_v3.APIRouter() mapper = fakes.urlmap.URLMap() - mapper['/v2'] = api + mapper['/v3'] = api return mapper @@ -100,7 +100,7 @@ class SnapshotManageTest(test.TestCase): def _get_resp_post(self, body): """Helper to execute an os-snapshot-manage API call.""" - req = webob.Request.blank('/v2/%s/os-snapshot-manage' % + req = webob.Request.blank('/v3/%s/os-snapshot-manage' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -271,7 +271,7 @@ class SnapshotManageTest(test.TestCase): detail = "" if detailed: detail = "/detail" - url = "/v2/%s/os-snapshot-manage%s%s" % (fake.PROJECT_ID, detail, + url = "/v3/%s/os-snapshot-manage%s%s" % (fake.PROJECT_ID, detail, query_string) req = webob.Request.blank(url) req.method = 'GET' diff --git a/cinder/tests/unit/api/contrib/test_snapshot_unmanage.py b/cinder/tests/unit/api/contrib/test_snapshot_unmanage.py index 55ac209208f..670c8cb1535 100644 --- a/cinder/tests/unit/api/contrib/test_snapshot_unmanage.py +++ b/cinder/tests/unit/api/contrib/test_snapshot_unmanage.py @@ -34,9 +34,9 @@ bad_snp_id = fake.WILL_NOT_BE_FOUND_ID def app(): # no auth, just let environ['cinder.context'] pass through - api = fakes.router.APIRouter() + api = fakes.router_v3.APIRouter() mapper = fakes.urlmap.URLMap() - mapper['/v2'] = api + mapper['/v3'] = api return mapper @@ -76,7 +76,7 @@ class SnapshotUnmanageTest(test.TestCase): def _get_resp(self, snapshot_id): """Helper to build an os-unmanage req for the specified snapshot_id.""" - req = webob.Request.blank('/v2/%s/snapshots/%s/action' % ( + req = webob.Request.blank('/v3/%s/snapshots/%s/action' % ( fake.PROJECT_ID, snapshot_id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' diff --git a/cinder/tests/unit/api/contrib/test_types_extra_specs.py b/cinder/tests/unit/api/contrib/test_types_extra_specs.py index f36045e743c..755fce70573 100644 --- a/cinder/tests/unit/api/contrib/test_types_extra_specs.py +++ b/cinder/tests/unit/api/contrib/test_types_extra_specs.py @@ -73,7 +73,7 @@ class VolumeTypesExtraSpecsTest(test.TestCase): super(VolumeTypesExtraSpecsTest, self).setUp() self.flags(host='fake') self.mock_object(cinder.db, 'volume_type_get', return_volume_type) - self.api_path = '/v2/%s/os-volume-types/%s/extra_specs' % ( + self.api_path = '/v3/%s/types/%s/extra_specs' % ( fake.PROJECT_ID, fake.VOLUME_TYPE_ID) self.controller = types_extra_specs.VolumeTypeExtraSpecsController() @@ -379,7 +379,7 @@ class VolumeTypesExtraSpecsTest(test.TestCase): req, fake.VOLUME_ID, 'bad', body=body) def _extra_specs_empty_update(self, body): - req = fakes.HTTPRequest.blank('/v2/%s/types/%s/extra_specs' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s/extra_specs' % ( fake.PROJECT_ID, fake.VOLUME_TYPE_ID)) req.method = 'POST' @@ -394,7 +394,7 @@ class VolumeTypesExtraSpecsTest(test.TestCase): self._extra_specs_empty_update(body={}) def _extra_specs_create_bad_body(self, body): - req = fakes.HTTPRequest.blank('/v2/%s/types/%s/extra_specs' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s/extra_specs' % ( fake.PROJECT_ID, fake.VOLUME_TYPE_ID)) req.method = 'POST' @@ -431,7 +431,7 @@ class VolumeTypesExtraSpecsTest(test.TestCase): cinder.db, 'volume_get_all', return_value=['a']): - req = fakes.HTTPRequest.blank('/v2/%s/types/%s/extra_specs' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s/extra_specs' % ( fake.PROJECT_ID, fake.VOLUME_TYPE_ID)) req.method = 'POST' @@ -447,7 +447,7 @@ class VolumeTypesExtraSpecsTest(test.TestCase): {'extra_specs': {'': 'a'}}, {'extra_specs': {' ': 'a'}}) def test_create_with_invalid_extra_specs(self, body): - req = fakes.HTTPRequest.blank('/v2/%s/types/%s/extra_specs' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s/extra_specs' % ( fake.PROJECT_ID, fake.VOLUME_TYPE_ID)) req.method = 'POST' diff --git a/cinder/tests/unit/api/contrib/test_types_manage.py b/cinder/tests/unit/api/contrib/test_types_manage.py index a6180ac09ed..9ded23a57e8 100644 --- a/cinder/tests/unit/api/contrib/test_types_manage.py +++ b/cinder/tests/unit/api/contrib/test_types_manage.py @@ -150,7 +150,7 @@ class VolumeTypesManageApiTest(test.TestCase): self.mock_object(volume_types, 'destroy', return_volume_types_destroy) - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, DEFAULT_VOLUME_TYPE)) self.assertEqual(0, len(self.notifier.notifications)) self.controller._delete(req, DEFAULT_VOLUME_TYPE) @@ -163,7 +163,7 @@ class VolumeTypesManageApiTest(test.TestCase): return_volume_types_destroy) self.assertEqual(0, len(self.notifier.notifications)) - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, NOT_FOUND_VOLUME_TYPE)) self.assertRaises(exception.VolumeTypeNotFound, self.controller._delete, req, NOT_FOUND_VOLUME_TYPE) @@ -174,7 +174,7 @@ class VolumeTypesManageApiTest(test.TestCase): return_volume_types_get_volume_type) self.mock_object(volume_types, 'destroy', return_volume_types_with_volumes_destroy) - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, DEFAULT_VOLUME_TYPE)) self.assertEqual(0, len(self.notifier.notifications)) self.controller._delete(req, DEFAULT_VOLUME_TYPE) @@ -195,7 +195,7 @@ class VolumeTypesManageApiTest(test.TestCase): 'description': 'vol_type_desc_%s' % DEFAULT_VOLUME_TYPE} mock_destroy.side_effect = return_volume_types_destroy - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % (fake.PROJECT_ID, DEFAULT_VOLUME_TYPE), use_admin_context=False) self.assertEqual(0, len(self.notifier.notifications)) @@ -217,7 +217,7 @@ class VolumeTypesManageApiTest(test.TestCase): body = {"volume_type": {"name": "vol_type_1", "os-volume-type-access:is_public": True, "extra_specs": {"key1": "value1"}}} - req = fakes.HTTPRequest.blank('/v2/%s/types' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/types' % fake.PROJECT_ID) self.assertEqual(0, len(self.notifier.notifications)) res_dict = self.controller._create(req, body=body) @@ -242,7 +242,7 @@ class VolumeTypesManageApiTest(test.TestCase): body = {"volume_type": {"name": "vol_type_1", "description": type_description, "extra_specs": {"key1": "value1"}}} - req = fakes.HTTPRequest.blank('/v2/%s/types' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/types' % fake.PROJECT_ID) res_dict = self.controller._create(req, body=body) @@ -253,7 +253,7 @@ class VolumeTypesManageApiTest(test.TestCase): type_name = 'a' * 256 body = {"volume_type": {"name": type_name, "extra_specs": {"key1": "value1"}}} - req = fakes.HTTPRequest.blank('/v2/%s/types' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/types' % fake.PROJECT_ID) self.assertRaises(exception.ValidationError, self.controller._create, req, body=body) @@ -262,7 +262,7 @@ class VolumeTypesManageApiTest(test.TestCase): body = {"volume_type": {"name": "vol_type_1", "description": type_description, "extra_specs": {"key1": "value1"}}} - req = fakes.HTTPRequest.blank('/v2/%s/types' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/types' % fake.PROJECT_ID) self.assertRaises(exception.ValidationError, self.controller._create, req, body=body) @@ -274,7 +274,7 @@ class VolumeTypesManageApiTest(test.TestCase): body = {"volume_type": {"name": "vol_type_1", "extra_specs": {"key1": "value1"}}} - req = fakes.HTTPRequest.blank('/v2/%s/types' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/types' % fake.PROJECT_ID) self.assertRaises(webob.exc.HTTPConflict, self.controller._create, req, body=body) @@ -283,7 +283,7 @@ class VolumeTypesManageApiTest(test.TestCase): "os-volume-type-access:is_public": "fake", "description": "test description", "extra_specs": {"key1": "value1"}}} - req = fakes.HTTPRequest.blank('/v2/%s/types' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/types' % fake.PROJECT_ID) self.assertRaises(exception.ValidationError, self.controller._create, req, body=body) @@ -302,7 +302,7 @@ class VolumeTypesManageApiTest(test.TestCase): "os-volume-type-access:is_public": is_public, "extra_specs": {"key1": "value1"}}} - req = fakes.HTTPRequest.blank('/v2/%s/types' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/types' % fake.PROJECT_ID) req.environ['cinder.context'] = ctxt self.controller._create(req, body=body) mock_create.assert_called_once_with( @@ -310,7 +310,7 @@ class VolumeTypesManageApiTest(test.TestCase): boolean_is_public, description=None) def _create_volume_type_bad_body(self, body): - req = fakes.HTTPRequest.blank('/v2/%s/types' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/types' % fake.PROJECT_ID) req.method = 'POST' self.assertRaises(exception.ValidationError, self.controller._create, req, body=body) @@ -344,7 +344,7 @@ class VolumeTypesManageApiTest(test.TestCase): body = {"volume_type": {"name": "vol_type_1", "os-volume-type-access:is_public": True, "extra_specs": {"key1": "value1"}}} - req = fakes.HTTPRequest.blank('/v2/%s/types' % fake.PROJECT_ID, + req = fakes.HTTPRequest.blank('/v3/%s/types' % fake.PROJECT_ID, use_admin_context=False) self.assertEqual(0, len(self.notifier.notifications)) @@ -371,7 +371,7 @@ class VolumeTypesManageApiTest(test.TestCase): "os-volume-type-access:is_public": False, "description": "test description"}} body['volume_type']['extra_specs'] = value - req = fakes.HTTPRequest.blank('/v2/%s/types' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/types' % fake.PROJECT_ID) self.assertRaises(exception.ValidationError, self.controller._create, req, body=body) @@ -381,7 +381,7 @@ class VolumeTypesManageApiTest(test.TestCase): mock_get.return_value = return_volume_types_get_volume_type_updated( DEFAULT_VOLUME_TYPE, is_public=False) body = {"volume_type": {"is_public": False}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, DEFAULT_VOLUME_TYPE)) req.method = 'PUT' @@ -406,7 +406,7 @@ class VolumeTypesManageApiTest(test.TestCase): self, is_public, mock_show, mock_cache_resource, mock_get, mock_update): body = {"volume_type": {"is_public": is_public}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, DEFAULT_VOLUME_TYPE)) req.method = 'PUT' ctxt = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True) @@ -429,7 +429,7 @@ class VolumeTypesManageApiTest(test.TestCase): type_description = "" body = {"volume_type": {"description": type_description}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, DEFAULT_VOLUME_TYPE)) req.method = 'PUT' resp = self.controller._update(req, DEFAULT_VOLUME_TYPE, body=body) @@ -441,7 +441,7 @@ class VolumeTypesManageApiTest(test.TestCase): type_name = 'a' * 256 body = {"volume_type": {"name": type_name, "description": ""}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, DEFAULT_VOLUME_TYPE)) req.method = 'PUT' self.assertRaises(exception.ValidationError, @@ -451,7 +451,7 @@ class VolumeTypesManageApiTest(test.TestCase): def test_update_type_with_description_too_long(self): type_description = 'a' * 256 body = {"volume_type": {"description": type_description}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, DEFAULT_VOLUME_TYPE)) req.method = 'PUT' self.assertRaises(exception.ValidationError, @@ -465,7 +465,7 @@ class VolumeTypesManageApiTest(test.TestCase): volume_type_id=NOT_FOUND_VOLUME_TYPE) body = {"volume_type": {"name": "vol_type_1_1", "description": "vol_type_desc_1_1"}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, NOT_FOUND_VOLUME_TYPE)) req.method = 'PUT' @@ -485,7 +485,7 @@ class VolumeTypesManageApiTest(test.TestCase): body = {"volume_type": {"name": "vol_type_1_1", "description": "vol_type_desc_1_1"}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, DEFAULT_VOLUME_TYPE)) req.method = 'PUT' @@ -497,7 +497,7 @@ class VolumeTypesManageApiTest(test.TestCase): def test_update_no_name_no_description(self): body = {"volume_type": {}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, DEFAULT_VOLUME_TYPE)) req.method = 'PUT' @@ -508,7 +508,7 @@ class VolumeTypesManageApiTest(test.TestCase): def test_update_empty_name(self): body = {"volume_type": {"name": " ", "description": "something"}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, DEFAULT_VOLUME_TYPE)) req.method = 'PUT' @@ -530,7 +530,7 @@ class VolumeTypesManageApiTest(test.TestCase): updated_name = "%s_%s" % (name, UPDATE_NAME_ONLY_TYPE) desc = "vol_type_desc_%s" % UPDATE_NAME_ONLY_TYPE body = {"volume_type": {"name": name}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % (fake.PROJECT_ID, UPDATE_NAME_ONLY_TYPE)) req.method = 'PUT' req.environ['cinder.context'] = ctxt @@ -553,7 +553,7 @@ class VolumeTypesManageApiTest(test.TestCase): desc = "vol_type_desc_%s" % UPDATE_DESC_ONLY_TYPE updated_desc = "%s_%s" % (desc, UPDATE_DESC_ONLY_TYPE) body = {"volume_type": {"description": updated_desc}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, UPDATE_DESC_ONLY_TYPE)) req.method = 'PUT' @@ -576,7 +576,7 @@ class VolumeTypesManageApiTest(test.TestCase): desc = "vol_type_desc_%s" % DEFAULT_VOLUME_TYPE updated_desc = "%s_%s" % (desc, DEFAULT_VOLUME_TYPE) body = {"volume_type": {"is_public": is_public}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, DEFAULT_VOLUME_TYPE)) req.method = 'PUT' @@ -592,7 +592,7 @@ class VolumeTypesManageApiTest(test.TestCase): body = {"volume_type": {"name": "test", "description": "something", "is_public": "fake"}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, DEFAULT_VOLUME_TYPE)) req.method = 'PUT' @@ -613,7 +613,7 @@ class VolumeTypesManageApiTest(test.TestCase): UPDATE_NAME_AFTER_DELETE_TYPE) # first attempt fail body = {"volume_type": {"name": name}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, UPDATE_NAME_AFTER_DELETE_TYPE)) req.method = 'PUT' @@ -628,7 +628,7 @@ class VolumeTypesManageApiTest(test.TestCase): self.notifier.reset() self.mock_object(volume_types, 'destroy', return_volume_types_destroy) - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, UPDATE_NAME_AFTER_DELETE_TYPE)) self.assertEqual(0, len(self.notifier.notifications)) self.controller._delete(req, UPDATE_NAME_AFTER_DELETE_TYPE) @@ -637,7 +637,7 @@ class VolumeTypesManageApiTest(test.TestCase): # update again mock_update.side_effect = mock.MagicMock() body = {"volume_type": {"name": updated_name}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, UPDATE_NAME_AFTER_DELETE_TYPE)) req.method = 'PUT' @@ -667,7 +667,7 @@ class VolumeTypesManageApiTest(test.TestCase): body = {"volume_type": {"name": updated_name, "description": updated_desc, "is_public": False}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, DEFAULT_VOLUME_TYPE), use_admin_context=False) @@ -701,7 +701,7 @@ class VolumeTypesManageApiTest(test.TestCase): def test_update_with_name_null(self): body = {"volume_type": {"name": None}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, DEFAULT_VOLUME_TYPE)) req.method = 'PUT' @@ -714,7 +714,7 @@ class VolumeTypesManageApiTest(test.TestCase): {"volume_type": {"description": "description", "is_public": True}}) def test_update_volume_type(self, body): - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % ( fake.PROJECT_ID, DEFAULT_VOLUME_TYPE)) req.method = 'PUT' ctxt = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True) diff --git a/cinder/tests/unit/api/contrib/test_volume_actions.py b/cinder/tests/unit/api/contrib/test_volume_actions.py index fbd7e348b30..608f2e9d711 100644 --- a/cinder/tests/unit/api/contrib/test_volume_actions.py +++ b/cinder/tests/unit/api/contrib/test_volume_actions.py @@ -31,7 +31,7 @@ from cinder import exception from cinder.image import glance from cinder import objects from cinder.tests.unit.api import fakes -from cinder.tests.unit.api.v2 import fakes as v2_fakes +from cinder.tests.unit.api.v3 import fakes as v3_fakes from cinder.tests.unit import fake_constants as fake from cinder.tests.unit import fake_volume from cinder.tests.unit import test @@ -89,7 +89,7 @@ class VolumeActionsTest(test.TestCase): def test_simple_api_actions(self): app = fakes.wsgi_app(fake_auth_context=self.context) for _action in self._actions: - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = 'POST' req.body = jsonutils.dump_as_bytes({_action: None}) @@ -103,7 +103,7 @@ class VolumeActionsTest(test.TestCase): init_conn.return_value = {} body = {'os-initialize_connection': {'connector': { 'fake': 'fake'}}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -118,7 +118,7 @@ class VolumeActionsTest(test.TestCase): 'initialize_connection') as init_conn: init_conn.return_value = {} body = {'os-initialize_connection': {}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -133,7 +133,7 @@ class VolumeActionsTest(test.TestCase): _init_connection): _init_connection.side_effect = messaging.RemoteError('InvalidInput') body = {'os-initialize_connection': {'connector': 'w/o_initiator'}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -150,7 +150,7 @@ class VolumeActionsTest(test.TestCase): exception.VolumeBackendAPIException(data=None) body = {'os-initialize_connection': {'connector': { 'fake': 'fake'}}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -166,7 +166,7 @@ class VolumeActionsTest(test.TestCase): 'terminate_connection') as terminate_conn: terminate_conn.return_value = {} body = {'os-terminate_connection': {'connector': 'fake'}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -181,7 +181,7 @@ class VolumeActionsTest(test.TestCase): 'terminate_connection') as terminate_conn: terminate_conn.return_value = {} body = {'os-terminate_connection': {}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -197,7 +197,7 @@ class VolumeActionsTest(test.TestCase): terminate_conn.side_effect = \ exception.VolumeBackendAPIException(data=None) body = {'os-terminate_connection': {'connector': 'fake'}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -212,7 +212,7 @@ class VolumeActionsTest(test.TestCase): body = {'os-attach': {'instance_uuid': fake.INSTANCE_ID, 'mountpoint': '/dev/vdc', 'mode': 'rw'}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -225,7 +225,7 @@ class VolumeActionsTest(test.TestCase): body = {'os-attach': {'instance_uuid': fake.INSTANCE_ID, 'host_name': 'fake_host', 'mountpoint': '/dev/vdc'}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.headers["content-type"] = "application/json" @@ -238,7 +238,7 @@ class VolumeActionsTest(test.TestCase): # using 'read-write' mode attach volume by default body = {'os-attach': {'host_name': 'fake_host', 'mountpoint': '/dev/vdc'}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -258,7 +258,7 @@ class VolumeActionsTest(test.TestCase): "mountpoint": "/dev/vdc", "mode": "rw"} body = {"os-attach": vol} - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, id)) self.assertRaises(webob.exc.HTTPBadRequest, self.controller._attach, @@ -277,7 +277,7 @@ class VolumeActionsTest(test.TestCase): "mountpoint": "/dev/vdc", "mode": "rw"} body = {"os-attach": vol} - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, id)) self.assertRaises(messaging.RemoteError, self.controller._attach, @@ -287,7 +287,7 @@ class VolumeActionsTest(test.TestCase): def test_detach(self): body = {'os-detach': {'attachment_id': fake.ATTACHMENT_ID}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -299,7 +299,7 @@ class VolumeActionsTest(test.TestCase): def test_detach_null_attachment_id(self): body = {'os-detach': {'attachment_id': None}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -317,7 +317,7 @@ class VolumeActionsTest(test.TestCase): id = fake.VOLUME_ID vol = {"attachment_id": fake.ATTACHMENT_ID} body = {"os-detach": vol} - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, id)) self.assertRaises(webob.exc.HTTPBadRequest, self.controller._detach, @@ -334,7 +334,7 @@ class VolumeActionsTest(test.TestCase): id = fake.VOLUME_ID vol = {"attachment_id": fake.ATTACHMENT_ID} body = {"os-detach": vol} - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, id)) self.assertRaises(messaging.RemoteError, self.controller._detach, @@ -345,7 +345,7 @@ class VolumeActionsTest(test.TestCase): def test_attach_with_invalid_arguments(self): # Invalid request to attach volume an invalid target body = {'os-attach': {'mountpoint': '/dev/vdc'}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.headers["content-type"] = "application/json" @@ -358,7 +358,7 @@ class VolumeActionsTest(test.TestCase): body = {'os-attach': {'instance_uuid': 'fake', 'mountpoint': '/dev/vdc', 'mode': 'rr'}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.headers["content-type"] = "application/json" @@ -369,7 +369,7 @@ class VolumeActionsTest(test.TestCase): body = {'os-attach': {'host_name': 'fake_host', 'mountpoint': '/dev/vdc', 'mode': 'ww'}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.headers["content-type"] = "application/json" @@ -383,7 +383,7 @@ class VolumeActionsTest(test.TestCase): # API should fail with a 400 error. body = {'os-attach': {'instance_uuid': fake.INSTANCE_ID, 'mode': 'rw'}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -400,7 +400,7 @@ class VolumeActionsTest(test.TestCase): fake_begin_detaching) body = {'os-begin_detaching': {'fake': 'fake'}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -417,7 +417,7 @@ class VolumeActionsTest(test.TestCase): fake_roll_detaching) body = {'os-roll_detaching': {'fake': 'fake'}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -434,7 +434,7 @@ class VolumeActionsTest(test.TestCase): fake_extend_volume) body = {'os-extend': {'new_size': 5}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -452,7 +452,7 @@ class VolumeActionsTest(test.TestCase): fake_extend_volume) body = {'os-extend': {'new_size': 5}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -476,7 +476,7 @@ class VolumeActionsTest(test.TestCase): body = {"os-update_readonly_flag": {"readonly": readonly}} if readonly is None: body = {"os-update_readonly_flag": {}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -495,7 +495,7 @@ class VolumeActionsTest(test.TestCase): body = {"os-set_bootable": {"bootable": bootable}} if bootable is None: body = {"os-set_bootable": {}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -528,7 +528,7 @@ class VolumeRetypeActionsTest(test.TestCase): new_type=fake.VOLUME_TYPE2_ID, vol_id=None, exists_mock=None): vol_id = vol_id or fake.VOLUME_ID - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, vol_id)) req.method = 'POST' req.headers['content-type'] = 'application/json' @@ -542,7 +542,7 @@ class VolumeRetypeActionsTest(test.TestCase): vol = utils.create_volume(self.context, status='available', testcase_instance=self) - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, vol.id)) req.method = 'POST' req.headers['content-type'] = 'application/json' @@ -555,7 +555,7 @@ class VolumeRetypeActionsTest(test.TestCase): vol = utils.create_volume(self.context, status='available', testcase_instance=self) - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, vol.id)) req.method = 'POST' req.headers['content-type'] = 'application/json' @@ -709,7 +709,7 @@ class VolumeRetypeActionsTest(test.TestCase): name='old', qos_specs_id=qos_old).id else: - vol_type_old = v2_fakes.fake_default_type_get()['id'] + vol_type_old = v3_fakes.fake_default_type_get()['id'] vol_type_new = utils.create_volume_type(admin_ctxt, self, name='new', @@ -739,7 +739,7 @@ class VolumeRetypeActionsTest(test.TestCase): if enc_orig: utils.create_encryption(admin_ctxt, vol_type_old, self) else: - vol_type_old = v2_fakes.fake_default_type_get()['id'] + vol_type_old = v3_fakes.fake_default_type_get()['id'] vol_type_new = utils.create_volume_type(admin_ctxt, self, name='new').id @@ -755,7 +755,7 @@ class VolumeRetypeActionsTest(test.TestCase): def fake_volume_get(self, context, volume_id): - volume = v2_fakes.create_fake_volume(volume_id) + volume = v3_fakes.create_volume(volume_id) if volume_id == fake.VOLUME3_ID: volume['status'] = 'in-use' else: @@ -778,7 +778,7 @@ def fake_volume_get_obj(self, context, volume_id, **kwargs): volume.volume_type = fake_volume.fake_volume_type_obj( context, - name=v2_fakes.DEFAULT_VOL_TYPE) + name=v3_fakes.DEFAULT_VOL_TYPE) return volume @@ -867,7 +867,7 @@ class VolumeImageActionsTest(test.TestCase): "image_name": 'image_name', "force": True} body = {"os-volume_upload_image": img} - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, id)) res_dict = self.controller._volume_upload_image(req, id, body=body) expected = {'os-volume_upload_image': @@ -913,7 +913,7 @@ class VolumeImageActionsTest(test.TestCase): "image_name": 'image_name', "force": True} body = {"os-volume_upload_image": img} - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, vol_id)) res_dict = self.controller._volume_upload_image(req, vol_id, body=body) @@ -941,7 +941,7 @@ class VolumeImageActionsTest(test.TestCase): "image_name": 'image_name', "force": True} body = {"os-volume_upload_image": img} - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, id)) res_dict = self.controller._volume_upload_image(req, id, body=body) @@ -961,7 +961,7 @@ class VolumeImageActionsTest(test.TestCase): "image_name": 'image_name', "force": True} body = {"os-volume_upload_image": vol} - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, id)) self.assertRaises(exception.VolumeNotFound, self.controller._volume_upload_image, @@ -979,7 +979,7 @@ class VolumeImageActionsTest(test.TestCase): "image_name": 'image_name', "force": True} body = {"os-volume_upload_image": vol} - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) self.assertRaises(webob.exc.HTTPBadRequest, self.controller._volume_upload_image, @@ -995,7 +995,7 @@ class VolumeImageActionsTest(test.TestCase): "image_name": 'image_name', "force": True} body = {"os-volume_upload_image": vol} - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, id)) self.assertRaises(exception.ValidationError, self.controller._volume_upload_image, @@ -1033,7 +1033,7 @@ class VolumeImageActionsTest(test.TestCase): "image_name": 'image_name', "force": True} body = {"os-volume_upload_image": vol} - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, fake.VOLUME_ID)) self.assertRaises(webob.exc.HTTPBadRequest, self.controller._volume_upload_image, @@ -1051,7 +1051,7 @@ class VolumeImageActionsTest(test.TestCase): "image_name": 'image_name', "force": True} body = {"os-volume_upload_image": vol} - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, id)) self.assertRaises(webob.exc.HTTPBadRequest, self.controller._volume_upload_image, @@ -1090,7 +1090,7 @@ class VolumeImageActionsTest(test.TestCase): def test_volume_upload_image_typeerror(self): id = fake.VOLUME2_ID body = {"os-volume_upload_image_fake": "fake"} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1105,7 +1105,7 @@ class VolumeImageActionsTest(test.TestCase): "image_name": None, "force": True} body = {"": vol} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -1117,7 +1117,7 @@ class VolumeImageActionsTest(test.TestCase): def test_extend_volume_valueerror(self): id = fake.VOLUME2_ID body = {'os-extend': {'new_size': 'fake'}} - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, id)) self.assertRaises(exception.ValidationError, self.controller._extend, @@ -1157,7 +1157,7 @@ class VolumeImageActionsTest(test.TestCase): vol_id = fake.WILL_NOT_BE_FOUND_ID body = {'os-extend': {'new_size': 5}} - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, vol_id)) self.assertRaises(exception.VolumeNotFound, @@ -1173,7 +1173,7 @@ class VolumeImageActionsTest(test.TestCase): "image_name": None, "force": True} body = {"os-volume_upload_image": vol} - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, id)) self.assertRaises(exception.ValidationError, self.controller._volume_upload_image, @@ -1222,7 +1222,7 @@ class VolumeImageActionsTest(test.TestCase): mock_create.side_effect = self.fake_image_service_create req = fakes.HTTPRequest.blank( - '/v2/%s/volumes/%s/action' % (fake.PROJECT_ID, volume.id), + '/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, volume.id), use_admin_context=self.context.is_admin) body = self._get_os_volume_upload_image() @@ -1265,7 +1265,7 @@ class VolumeImageActionsTest(test.TestCase): mock_create.side_effect = self.fake_image_service_create req = fakes.HTTPRequest.blank( - '/v2/%s/volumes/%s/action' % (fake.PROJECT_ID, volume.id), + '/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, volume.id), use_admin_context=self.context.is_admin) body = self._get_os_volume_upload_image() res_dict = self.controller._volume_upload_image(req, volume.id, @@ -1291,7 +1291,7 @@ class VolumeImageActionsTest(test.TestCase): mock_create.side_effect = Exception() req = fakes.HTTPRequest.blank( - '/v2/fakeproject/volumes/%s/action' % volume.id) + '/v3/fakeproject/volumes/%s/action' % volume.id) body = self._get_os_volume_upload_image() self.assertRaises(webob.exc.HTTPBadRequest, self.controller._volume_upload_image, req, volume.id, @@ -1318,7 +1318,7 @@ class VolumeImageActionsTest(test.TestCase): mock_create.side_effect = self.fake_image_service_create req = fakes.HTTPRequest.blank( - '/v2/fakeproject/volumes/%s/action' % volume.id) + '/v3/fakeproject/volumes/%s/action' % volume.id) body = self._get_os_volume_upload_image() body['os-volume_upload_image']['force'] = False self.assertRaises(webob.exc.HTTPBadRequest, @@ -1346,7 +1346,7 @@ class VolumeImageActionsTest(test.TestCase): mock_create.side_effect = self.fake_image_service_create req = fakes.HTTPRequest.blank( - '/v2/fakeproject/volumes/%s/action' % volume.id, + '/v3/fakeproject/volumes/%s/action' % volume.id, use_admin_context=self.context.is_admin) body = self._get_os_volume_upload_image() self.assertRaises(webob.exc.HTTPBadRequest, @@ -1380,7 +1380,7 @@ class VolumeImageActionsTest(test.TestCase): mock_create.side_effect = self.fake_image_service_create req = fakes.HTTPRequest.blank( - '/v2/fakeproject/volumes/%s/action' % volume.id, + '/v3/fakeproject/volumes/%s/action' % volume.id, use_admin_context=self.context.is_admin) body = self._get_os_volume_upload_image() @@ -1403,7 +1403,7 @@ class VolumeImageActionsTest(test.TestCase): self.override_config('glance_core_properties', []) req = fakes.HTTPRequest.blank( - '/v2/fakeproject/volumes/%s/action' % volume.id, + '/v3/fakeproject/volumes/%s/action' % volume.id, use_admin_context=self.context.is_admin) body = self._get_os_volume_upload_image() @@ -1429,7 +1429,7 @@ class VolumeImageActionsTest(test.TestCase): mock_create.side_effect = self.fake_image_service_create req = fakes.HTTPRequest.blank( - '/v2/%s/volumes/%s/action' % (fake.PROJECT_ID, volume.id), + '/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, volume.id), use_admin_context=self.context.is_admin) body = self._get_os_volume_upload_image() res_dict = self.controller._volume_upload_image(req, volume.id, @@ -1483,7 +1483,7 @@ class VolumeImageActionsTest(test.TestCase): mock_get_image_metadata.return_value = {} mock_create.side_effect = self.fake_image_service_create req = fakes.HTTPRequest.blank( - '/v2/fakeproject/volumes/%s/action' % volume.id) + '/v3/fakeproject/volumes/%s/action' % volume.id) body = self._get_os_volume_upload_image() body['os-volume_upload_image']['force'] = True body['os-volume_upload_image']['container_format'] = 'bare' @@ -1507,7 +1507,7 @@ class VolumeImageActionsTest(test.TestCase): mock_get_image_metadata.return_value = {} mock_create.side_effect = self.fake_image_service_create req = fakes.HTTPRequest.blank( - '/v2/fakeproject/volumes/%s/action' % volume.id) + '/v3/fakeproject/volumes/%s/action' % volume.id) body = self._get_os_volume_upload_image() body['os-volume_upload_image']['force'] = True body['os-volume_upload_image']['container_format'] = 'bare' diff --git a/cinder/tests/unit/api/contrib/test_volume_encryption_metadata.py b/cinder/tests/unit/api/contrib/test_volume_encryption_metadata.py index 4a36446b767..7983e2a0feb 100644 --- a/cinder/tests/unit/api/contrib/test_volume_encryption_metadata.py +++ b/cinder/tests/unit/api/contrib/test_volume_encryption_metadata.py @@ -81,7 +81,7 @@ class VolumeEncryptionMetadataTest(test.TestCase): self.volume_id) def test_index(self): - req = webob.Request.blank('/v2/%s/volumes/%s/encryption' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/encryption' % ( fake.PROJECT_ID, self.volume_id)) res = req.get_response(fakes.wsgi_app(fake_auth_context=self.ctxt)) self.assertEqual(HTTPStatus.OK, res.status_code) @@ -97,7 +97,7 @@ class VolumeEncryptionMetadataTest(test.TestCase): self.assertEqual(expected, res_dict) def test_index_bad_tenant_id(self): - req = webob.Request.blank('/v2/%s/volumes/%s/encryption' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/encryption' % ( fake.WILL_NOT_BE_FOUND_ID, self.volume_id)) res = req.get_response(fakes.wsgi_app(fake_auth_context=self.ctxt)) self.assertEqual(HTTPStatus.BAD_REQUEST, res.status_code) @@ -109,7 +109,7 @@ class VolumeEncryptionMetadataTest(test.TestCase): def test_index_bad_volume_id(self): bad_volume_id = fake.WILL_NOT_BE_FOUND_ID - req = webob.Request.blank('/v2/%s/volumes/%s/encryption' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/encryption' % ( fake.PROJECT_ID, bad_volume_id)) res = req.get_response(fakes.wsgi_app(fake_auth_context=self.ctxt)) self.assertEqual(HTTPStatus.NOT_FOUND, res.status_code) @@ -121,7 +121,7 @@ class VolumeEncryptionMetadataTest(test.TestCase): self.assertEqual(expected, res_dict) def test_show_key(self): - req = webob.Request.blank('/v2/%s/volumes/%s/encryption/' + req = webob.Request.blank('/v3/%s/volumes/%s/encryption/' 'encryption_key_id' % ( fake.PROJECT_ID, self.volume_id)) res = req.get_response(fakes.wsgi_app(fake_auth_context=self.ctxt)) @@ -130,7 +130,7 @@ class VolumeEncryptionMetadataTest(test.TestCase): self.assertEqual(fake.ENCRYPTION_KEY_ID, res.body.decode()) def test_show_control(self): - req = webob.Request.blank('/v2/%s/volumes/%s/encryption/' + req = webob.Request.blank('/v3/%s/volumes/%s/encryption/' 'control_location' % ( fake.PROJECT_ID, self.volume_id)) res = req.get_response(fakes.wsgi_app(fake_auth_context=self.ctxt)) @@ -139,7 +139,7 @@ class VolumeEncryptionMetadataTest(test.TestCase): self.assertEqual(b'front-end', res.body) def test_show_provider(self): - req = webob.Request.blank('/v2/%s/volumes/%s/encryption/' + req = webob.Request.blank('/v3/%s/volumes/%s/encryption/' 'provider' % ( fake.PROJECT_ID, self.volume_id)) res = req.get_response(fakes.wsgi_app(fake_auth_context=self.ctxt)) @@ -149,7 +149,7 @@ class VolumeEncryptionMetadataTest(test.TestCase): res.body) def test_show_bad_tenant_id(self): - req = webob.Request.blank('/v2/%s/volumes/%s/encryption/' + req = webob.Request.blank('/v3/%s/volumes/%s/encryption/' 'encryption_key_id' % (fake.WILL_NOT_BE_FOUND_ID, self.volume_id)) @@ -163,7 +163,7 @@ class VolumeEncryptionMetadataTest(test.TestCase): def test_show_bad_volume_id(self): bad_volume_id = fake.WILL_NOT_BE_FOUND_ID - req = webob.Request.blank('/v2/%s/volumes/%s/encryption/' + req = webob.Request.blank('/v3/%s/volumes/%s/encryption/' 'encryption_key_id' % ( fake.PROJECT_ID, bad_volume_id)) res = req.get_response(fakes.wsgi_app(fake_auth_context=self.ctxt)) @@ -179,7 +179,7 @@ class VolumeEncryptionMetadataTest(test.TestCase): ctxt = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, is_admin=True) - req = webob.Request.blank('/v2/%s/volumes/%s/encryption/' + req = webob.Request.blank('/v3/%s/volumes/%s/encryption/' 'encryption_key_id' % ( fake.PROJECT_ID, self.volume_id)) res = req.get_response(fakes.wsgi_app(fake_auth_context=ctxt)) @@ -194,7 +194,7 @@ class VolumeEncryptionMetadataTest(test.TestCase): volume_id = self._create_volume(self.ctxt, encryption_key_id=None) self.addCleanup(db.volume_destroy, self.ctxt.elevated(), volume_id) - req = webob.Request.blank('/v2/%s/volumes/%s/encryption/' + req = webob.Request.blank('/v3/%s/volumes/%s/encryption/' 'encryption_key_id' % ( fake.PROJECT_ID, volume_id)) res = req.get_response(fakes.wsgi_app(fake_auth_context=self.ctxt)) @@ -208,7 +208,7 @@ class VolumeEncryptionMetadataTest(test.TestCase): volume_id = self._create_volume(self.ctxt, encryption_key_id=None) self.addCleanup(db.volume_destroy, self.ctxt.elevated(), volume_id) - req = webob.Request.blank('/v2/%s/volumes/%s/encryption' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/encryption' % ( fake.PROJECT_ID, volume_id)) res = req.get_response(fakes.wsgi_app(fake_auth_context=self.ctxt)) diff --git a/cinder/tests/unit/api/contrib/test_volume_host_attribute.py b/cinder/tests/unit/api/contrib/test_volume_host_attribute.py index 6355e6fb95d..5ac35cacfb3 100644 --- a/cinder/tests/unit/api/contrib/test_volume_host_attribute.py +++ b/cinder/tests/unit/api/contrib/test_volume_host_attribute.py @@ -60,9 +60,9 @@ def fake_volume_get_all(*args, **kwargs): def app(): # no auth, just let environ['cinder.context'] pass through - api = fakes.router.APIRouter() + api = fakes.router_v3.APIRouter() mapper = fakes.urlmap.URLMap() - mapper['/v2'] = api + mapper['/v3'] = api return mapper @@ -78,7 +78,7 @@ class VolumeHostAttributeTest(test.TestCase): def test_get_volume_allowed(self): ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True) - req = webob.Request.blank('/v2/%s/volumes/%s' % ( + req = webob.Request.blank('/v3/%s/volumes/%s' % ( fake.PROJECT_ID, self.UUID)) req.method = 'GET' req.environ['cinder.context'] = ctx @@ -88,7 +88,7 @@ class VolumeHostAttributeTest(test.TestCase): def test_get_volume_unallowed(self): ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, False) - req = webob.Request.blank('/v2/%s/volumes/%s' % ( + req = webob.Request.blank('/v3/%s/volumes/%s' % ( fake.PROJECT_ID, self.UUID)) req.method = 'GET' req.environ['cinder.context'] = ctx @@ -98,7 +98,7 @@ class VolumeHostAttributeTest(test.TestCase): def test_list_detail_volumes_allowed(self): ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True) - req = webob.Request.blank('/v2/%s/volumes/detail' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/volumes/detail' % fake.PROJECT_ID) req.method = 'GET' req.environ['cinder.context'] = ctx res = req.get_response(app()) @@ -107,7 +107,7 @@ class VolumeHostAttributeTest(test.TestCase): def test_list_detail_volumes_unallowed(self): ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, False) - req = webob.Request.blank('/v2/%s/volumes/detail' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/volumes/detail' % fake.PROJECT_ID) req.method = 'GET' req.environ['cinder.context'] = ctx res = req.get_response(app()) @@ -116,7 +116,7 @@ class VolumeHostAttributeTest(test.TestCase): def test_list_simple_volumes_no_host(self): ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True) - req = webob.Request.blank('/v2/%s/volumes' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/volumes' % fake.PROJECT_ID) req.method = 'GET' req.environ['cinder.context'] = ctx res = req.get_response(app()) diff --git a/cinder/tests/unit/api/contrib/test_volume_image_metadata.py b/cinder/tests/unit/api/contrib/test_volume_image_metadata.py index fc0d7e1a3aa..466e9f3f0f7 100644 --- a/cinder/tests/unit/api/contrib/test_volume_image_metadata.py +++ b/cinder/tests/unit/api/contrib/test_volume_image_metadata.py @@ -163,7 +163,7 @@ class VolumeImageMetadataTest(test.TestCase): def test_get_volume(self): self._create_volume_and_glance_metadata() - res = self._make_request('/v2/%s/volumes/%s' % ( + res = self._make_request('/v3/%s/volumes/%s' % ( fake.PROJECT_ID, self.UUID)) self.assertEqual(HTTPStatus.OK, res.status_int) self.assertEqual(fake_image_metadata, @@ -171,7 +171,7 @@ class VolumeImageMetadataTest(test.TestCase): def test_list_detail_volumes(self): self._create_volume_and_glance_metadata() - res = self._make_request('/v2/%s/volumes/detail' % fake.PROJECT_ID) + res = self._make_request('/v3/%s/volumes/detail' % fake.PROJECT_ID) self.assertEqual(HTTPStatus.OK, res.status_int) self.assertEqual(fake_image_metadata, self._get_image_metadata_list(res.body)[0]) @@ -185,7 +185,7 @@ class VolumeImageMetadataTest(test.TestCase): self.mock_object(volume.api.API, 'get_all', fake_volume_get_all_empty) - res = self._make_request('/v2/%s/volumes/detail' % fake.PROJECT_ID) + res = self._make_request('/v3/%s/volumes/detail' % fake.PROJECT_ID) self.assertEqual(HTTPStatus.OK, res.status_int) self.assertFalse(fake_dont_call_this.called) @@ -199,7 +199,7 @@ class VolumeImageMetadataTest(test.TestCase): 'key1', 'value1') db.volume_glance_metadata_create(ctxt, fake.VOLUME_ID, 'key2', 'value2') - res = self._make_request('/v2/%s/volumes/detail?limit=1' + res = self._make_request('/v3/%s/volumes/detail?limit=1' % fake.PROJECT_ID) self.assertEqual(HTTPStatus.OK, res.status_int) self.assertEqual({'key1': 'value1', 'key2': 'value2'}, @@ -213,7 +213,7 @@ class VolumeImageMetadataTest(test.TestCase): fake_create_volume_metadata) body = {"os-set_image_metadata": {"metadata": fake_image_metadata}} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, fake.VOLUME_ID)) req.method = "POST" req.body = jsonutils.dump_as_bytes(body) @@ -235,7 +235,7 @@ class VolumeImageMetadataTest(test.TestCase): self.addCleanup(policy.reset) fake_get.return_value = {} - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % ( + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, fake.VOLUME_ID), use_admin_context=False) req.method = 'POST' @@ -270,7 +270,7 @@ class VolumeImageMetadataTest(test.TestCase): }, } - req = webob.Request.blank('/v2/%s/volumes/%s/action' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, fake.VOLUME_ID)) req.method = 'POST' req.body = jsonutils.dump_as_bytes(body) @@ -284,7 +284,7 @@ class VolumeImageMetadataTest(test.TestCase): @mock.patch('cinder.objects.Volume.get_by_id') def test_create_empty_body(self, fake_get): - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % ( + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, fake.VOLUME_ID)) req.method = 'POST' req.headers["content-type"] = "application/json" @@ -297,7 +297,7 @@ class VolumeImageMetadataTest(test.TestCase): def test_create_nonexistent_volume(self): self.mock_object(volume.api.API, 'get', return_volume_nonexistent) - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % ( + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, fake.VOLUME_ID)) req.method = 'POST' req.content_type = "application/json" @@ -313,7 +313,7 @@ class VolumeImageMetadataTest(test.TestCase): def test_invalid_metadata_items_on_create(self, fake_get): self.mock_object(db, 'volume_metadata_update', fake_create_volume_metadata) - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % ( + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, fake.VOLUME_ID)) req.method = 'POST' req.headers["content-type"] = "application/json" @@ -355,7 +355,7 @@ class VolumeImageMetadataTest(test.TestCase): body = {"os-unset_image_metadata": { "key": "ramdisk_id"} } - req = webob.Request.blank('/v2/%s/volumes/%s/action' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, fake.VOLUME_ID)) req.method = 'POST' req.body = jsonutils.dump_as_bytes(body) @@ -375,7 +375,7 @@ class VolumeImageMetadataTest(test.TestCase): self.addCleanup(policy.reset) fake_get.return_value = {} - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % ( + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, fake.VOLUME_ID), use_admin_context=False) req.method = 'POST' @@ -394,7 +394,7 @@ class VolumeImageMetadataTest(test.TestCase): data = {"os-unset_image_metadata": { "key": "invalid_id"} } - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % ( + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, fake.VOLUME_ID)) req.method = 'POST' req.body = jsonutils.dump_as_bytes(data) @@ -413,7 +413,7 @@ class VolumeImageMetadataTest(test.TestCase): body = {"os-unset_image_metadata": { "key": "fake"} } - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % ( + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, fake.VOLUME_ID)) req.method = 'POST' req.body = jsonutils.dump_as_bytes(body) @@ -425,7 +425,7 @@ class VolumeImageMetadataTest(test.TestCase): body=body) def test_delete_empty_body(self): - req = fakes.HTTPRequest.blank('/v2/%s/volumes/%s/action' % ( + req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, fake.VOLUME_ID)) req.method = 'POST' req.headers["content-type"] = "application/json" @@ -436,7 +436,7 @@ class VolumeImageMetadataTest(test.TestCase): def test_show_image_metadata(self): body = {"os-show_image_metadata": None} - req = webob.Request.blank('/v2/%s/volumes/%s/action' % ( + req = webob.Request.blank('/v3/%s/volumes/%s/action' % ( fake.PROJECT_ID, fake.VOLUME_ID)) req.method = 'POST' req.body = jsonutils.dump_as_bytes(body) diff --git a/cinder/tests/unit/api/contrib/test_volume_manage.py b/cinder/tests/unit/api/contrib/test_volume_manage.py index 69eb6bb83ac..82b6b644956 100644 --- a/cinder/tests/unit/api/contrib/test_volume_manage.py +++ b/cinder/tests/unit/api/contrib/test_volume_manage.py @@ -39,15 +39,7 @@ CONF = cfg.CONF def app(): # no auth, just let environ['cinder.context'] pass through - api = fakes.router.APIRouter() - mapper = fakes.urlmap.URLMap() - mapper['/v2'] = api - return mapper - - -def app_v3(): - # no auth, just let environ['cinder.context'] pass through - api = fakes.router.APIRouter() + api = fakes.router_v3.APIRouter() mapper = fakes.urlmap.URLMap() mapper['/v3'] = api return mapper @@ -181,17 +173,7 @@ class VolumeManageTest(test.TestCase): is_admin=False) self.controller = volume_manage.VolumeManageController() - def _get_resp_post(self, body): - """Helper to execute a POST os-volume-manage API call.""" - req = webob.Request.blank('/v2/%s/os-volume-manage' % fake.PROJECT_ID) - req.method = 'POST' - req.headers['Content-Type'] = 'application/json' - req.environ['cinder.context'] = self._admin_ctxt - req.body = jsonutils.dump_as_bytes(body) - res = req.get_response(app()) - return res - - def _get_resp_post_v3(self, body, version): + def _get_resp_post(self, body, version='3.11'): """Helper to execute a POST os-volume-manage API call.""" req = webob.Request.blank('/v3/%s/os-volume-manage' % fake.PROJECT_ID) req.method = 'POST' @@ -200,7 +182,7 @@ class VolumeManageTest(test.TestCase): req.headers["OpenStack-API-Version"] = "volume " + version req.api_version_request = api_version.APIVersionRequest(version) req.body = jsonutils.dump_as_bytes(body) - res = req.get_response(app_v3()) + res = req.get_response(app()) return res @ddt.data({'host': 'host_ok'}, @@ -381,7 +363,7 @@ class VolumeManageTest(test.TestCase): detail = "" if detailed: detail = "/detail" - url = "/v2/%s/os-volume-manage%s%s" % (fake.PROJECT_ID, detail, + url = "/v3/%s/os-volume-manage%s%s" % (fake.PROJECT_ID, detail, query_string) req = webob.Request.blank(url) req.method = 'GET' @@ -486,29 +468,12 @@ class VolumeManageTest(test.TestCase): self.assertTrue(mock_is_up.called) @mock.patch('cinder.volume.api.API.manage_existing', wraps=api_manage_new) - def test_manage_volume_with_creating_status_in_v3(self, mock_api_manage): + def test_manage_volume_with_creating_status(self, mock_api_manage): """Test managing volume to return 'creating' status in V3 API.""" body = {'volume': {'host': 'host_ok', 'ref': 'fake_ref'}} - res = self._get_resp_post_v3(body, mv.ETAGS) + res = self._get_resp_post(body, mv.ETAGS) self.assertEqual(HTTPStatus.ACCEPTED, res.status_int) self.assertEqual(1, mock_api_manage.call_count) self.assertEqual('creating', jsonutils.loads(res.body)['volume']['status']) - - @mock.patch('cinder.volume.api.API.manage_existing', wraps=api_manage_new) - def test_manage_volume_with_creating_status_in_v2(self, mock_api_manage): - """Test managing volume to return 'creating' status in V2 API.""" - - body = {'volume': {'host': 'host_ok', - 'ref': 'fake_ref'}} - res = self._get_resp_post(body) - self.assertEqual(HTTPStatus.ACCEPTED, res.status_int) - self.assertEqual(1, mock_api_manage.call_count) - self.assertEqual('creating', - jsonutils.loads(res.body)['volume']['status']) - - @ddt.data({'volume': {}}, None) - def test_manage_volume_with_invalid_body(self, body): - res = self._get_resp_post(body) - self.assertEqual(HTTPStatus.BAD_REQUEST, res.status_int) diff --git a/cinder/tests/unit/api/contrib/test_volume_migration_status_attribute.py b/cinder/tests/unit/api/contrib/test_volume_migration_status_attribute.py index e3964c2dd93..dcbb95bce32 100644 --- a/cinder/tests/unit/api/contrib/test_volume_migration_status_attribute.py +++ b/cinder/tests/unit/api/contrib/test_volume_migration_status_attribute.py @@ -57,9 +57,9 @@ def fake_volume_get_all(*args, **kwargs): def app(): # no auth, just let environ['cinder.context'] pass through - api = fakes.router.APIRouter() + api = fakes.router_v3.APIRouter() mapper = fakes.urlmap.URLMap() - mapper['/v2'] = api + mapper['/v3'] = api return mapper @@ -73,7 +73,7 @@ class VolumeMigStatusAttributeTest(test.TestCase): def test_get_volume_allowed(self): ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True) - req = webob.Request.blank('/v2/%s/volumes/%s' % ( + req = webob.Request.blank('/v3/%s/volumes/%s' % ( fake.PROJECT_ID, self.UUID)) req.method = 'GET' req.environ['cinder.context'] = ctx @@ -86,7 +86,7 @@ class VolumeMigStatusAttributeTest(test.TestCase): def test_get_volume_unallowed(self): ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, False) - req = webob.Request.blank('/v2/%s/volumes/%s' % ( + req = webob.Request.blank('/v3/%s/volumes/%s' % ( fake.PROJECT_ID, self.UUID)) req.method = 'GET' req.environ['cinder.context'] = ctx @@ -97,7 +97,7 @@ class VolumeMigStatusAttributeTest(test.TestCase): def test_list_detail_volumes_allowed(self): ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True) - req = webob.Request.blank('/v2/%s/volumes/detail' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/volumes/detail' % fake.PROJECT_ID) req.method = 'GET' req.environ['cinder.context'] = ctx res = req.get_response(app()) @@ -109,7 +109,7 @@ class VolumeMigStatusAttributeTest(test.TestCase): def test_list_detail_volumes_unallowed(self): ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, False) - req = webob.Request.blank('/v2/%s/volumes/detail' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/volumes/detail' % fake.PROJECT_ID) req.method = 'GET' req.environ['cinder.context'] = ctx res = req.get_response(app()) @@ -119,7 +119,7 @@ class VolumeMigStatusAttributeTest(test.TestCase): def test_list_simple_volumes_no_migration_status(self): ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True) - req = webob.Request.blank('/v2/%s/volumes' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/volumes' % fake.PROJECT_ID) req.method = 'GET' req.environ['cinder.context'] = ctx res = req.get_response(app()) diff --git a/cinder/tests/unit/api/contrib/test_volume_tenant_attribute.py b/cinder/tests/unit/api/contrib/test_volume_tenant_attribute.py index 700152e0920..1dc58dd4ea5 100644 --- a/cinder/tests/unit/api/contrib/test_volume_tenant_attribute.py +++ b/cinder/tests/unit/api/contrib/test_volume_tenant_attribute.py @@ -47,9 +47,9 @@ def fake_volume_get_all(*args, **kwargs): def app(): # no auth, just let environ['cinder.context'] pass through - api = fakes.router.APIRouter() + api = fakes.router_v3.APIRouter() mapper = fakes.urlmap.URLMap() - mapper['/v2'] = api + mapper['/v3'] = api return mapper @@ -68,7 +68,7 @@ class VolumeTenantAttributeTest(test.TestCase): allow_all = {TENANT_ATTRIBUTE_POLICY: oslo_policy._checks.TrueCheck()} policy._ENFORCER.set_rules(allow_all, overwrite=False) ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True) - req = webob.Request.blank('/v2/%s/volumes/%s' % ( + req = webob.Request.blank('/v3/%s/volumes/%s' % ( fake.PROJECT_ID, self.UUID)) req.method = 'GET' req.environ['cinder.context'] = ctx @@ -82,7 +82,7 @@ class VolumeTenantAttributeTest(test.TestCase): oslo_policy._checks.FalseCheck()} policy._ENFORCER.set_rules(allow_none, overwrite=False) ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True) - req = webob.Request.blank('/v2/%s/volumes/%s' % ( + req = webob.Request.blank('/v3/%s/volumes/%s' % ( fake.PROJECT_ID, self.UUID)) req.method = 'GET' req.environ['cinder.context'] = ctx @@ -95,7 +95,7 @@ class VolumeTenantAttributeTest(test.TestCase): allow_all = {TENANT_ATTRIBUTE_POLICY: oslo_policy._checks.TrueCheck()} policy._ENFORCER.set_rules(allow_all, overwrite=False) ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, False) - req = webob.Request.blank('/v2/%s/volumes/detail' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/volumes/detail' % fake.PROJECT_ID) req.method = 'GET' req.environ['cinder.context'] = ctx res = req.get_response(app()) @@ -107,7 +107,7 @@ class VolumeTenantAttributeTest(test.TestCase): oslo_policy._checks.FalseCheck()} policy._ENFORCER.set_rules(allow_none, overwrite=False) ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, False) - req = webob.Request.blank('/v2/%s/volumes/detail' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/volumes/detail' % fake.PROJECT_ID) req.method = 'GET' req.environ['cinder.context'] = ctx res = req.get_response(app()) @@ -119,7 +119,7 @@ class VolumeTenantAttributeTest(test.TestCase): allow_all = {TENANT_ATTRIBUTE_POLICY: oslo_policy._checks.TrueCheck()} policy._ENFORCER.set_rules(allow_all, overwrite=False) ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True) - req = webob.Request.blank('/v2/%s/volumes' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/volumes' % fake.PROJECT_ID) req.method = 'GET' req.environ['cinder.context'] = ctx res = req.get_response(app()) @@ -131,7 +131,7 @@ class VolumeTenantAttributeTest(test.TestCase): oslo_policy._checks.FalseCheck()} policy._ENFORCER.set_rules(allow_none, overwrite=False) ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True) - req = webob.Request.blank('/v2/%s/volumes' % fake.PROJECT_ID) + req = webob.Request.blank('/v3/%s/volumes' % fake.PROJECT_ID) req.method = 'GET' req.environ['cinder.context'] = ctx res = req.get_response(app()) diff --git a/cinder/tests/unit/api/contrib/test_volume_transfer.py b/cinder/tests/unit/api/contrib/test_volume_transfer.py index 71920184a56..be3bf7f40b9 100644 --- a/cinder/tests/unit/api/contrib/test_volume_transfer.py +++ b/cinder/tests/unit/api/contrib/test_volume_transfer.py @@ -28,14 +28,14 @@ from cinder import exception from cinder.objects import fields from cinder import quota from cinder.tests.unit.api import fakes -from cinder.tests.unit.api.v2 import fakes as v2_fakes +from cinder.tests.unit.api.v3 import fakes as v3_fakes from cinder.tests.unit import fake_constants as fake from cinder.tests.unit import test import cinder.transfer class VolumeTransferAPITestCase(test.TestCase): - """Test Case for transfers API.""" + """Test Case for the "old" transfers API, still valid in 3.0.""" def setUp(self): super(VolumeTransferAPITestCase, self).setUp() @@ -75,7 +75,7 @@ class VolumeTransferAPITestCase(test.TestCase): def test_show_transfer(self): volume_id = self._create_volume(size=5) transfer = self._create_transfer(volume_id) - req = webob.Request.blank('/v2/%s/os-volume-transfer/%s' % ( + req = webob.Request.blank('/v3/%s/os-volume-transfer/%s' % ( fake.PROJECT_ID, transfer['id'])) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -91,7 +91,7 @@ class VolumeTransferAPITestCase(test.TestCase): db.volume_destroy(context.get_admin_context(), volume_id) def test_show_transfer_with_transfer_NotFound(self): - req = webob.Request.blank('/v2/%s/os-volume-transfer/%s' % ( + req = webob.Request.blank('/v3/%s/os-volume-transfer/%s' % ( fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID)) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -112,7 +112,7 @@ class VolumeTransferAPITestCase(test.TestCase): transfer1 = self._create_transfer(volume_id_1) transfer2 = self._create_transfer(volume_id_2) - req = webob.Request.blank('/v2/%s/os-volume-transfer' % + req = webob.Request.blank('/v3/%s/os-volume-transfer' % fake.PROJECT_ID) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -138,7 +138,7 @@ class VolumeTransferAPITestCase(test.TestCase): transfer1 = self._create_transfer(volume_id_1) transfer2 = self._create_transfer(volume_id_2) - req = webob.Request.blank('/v2/%s/os-volume-transfer/detail' % + req = webob.Request.blank('/v3/%s/os-volume-transfer/detail' % fake.PROJECT_ID) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -171,7 +171,7 @@ class VolumeTransferAPITestCase(test.TestCase): transfer1 = self._create_transfer(volume_id_1) transfer2 = self._create_transfer(volume_id_2) - req = fakes.HTTPRequest.blank('/v2/%s/os-volume-transfer?' + req = fakes.HTTPRequest.blank('/v3/%s/os-volume-transfer?' 'all_tenants=1' % fake.PROJECT_ID, use_admin_context=True) res_dict = self.controller.index(req) @@ -192,7 +192,7 @@ class VolumeTransferAPITestCase(test.TestCase): body = {"transfer": {"name": "transfer1", "volume_id": volume_id}} - req = webob.Request.blank('/v2/%s/os-volume-transfer' % + req = webob.Request.blank('/v3/%s/os-volume-transfer' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -212,7 +212,7 @@ class VolumeTransferAPITestCase(test.TestCase): db.volume_destroy(context.get_admin_context(), volume_id) def test_create_transfer_with_no_body(self): - req = webob.Request.blank('/v2/%s/os-volume-transfer' % + req = webob.Request.blank('/v3/%s/os-volume-transfer' % fake.PROJECT_ID) req.body = jsonutils.dump_as_bytes(None) req.method = 'POST' @@ -228,7 +228,7 @@ class VolumeTransferAPITestCase(test.TestCase): def test_create_transfer_with_body_KeyError(self): body = {"transfer": {"name": "transfer1"}} - req = webob.Request.blank('/v2/%s/os-volume-transfer' % + req = webob.Request.blank('/v3/%s/os-volume-transfer' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -245,7 +245,7 @@ class VolumeTransferAPITestCase(test.TestCase): body = {"transfer": {"name": "transfer1", "volume_id": 1234}} - req = webob.Request.blank('/v2/%s/os-volume-transfer' % + req = webob.Request.blank('/v3/%s/os-volume-transfer' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -262,7 +262,7 @@ class VolumeTransferAPITestCase(test.TestCase): volume_id = self._create_volume(status='attached') body = {"transfer": {"name": "transfer1", "volume_id": volume_id}} - req = webob.Request.blank('/v2/%s/os-volume-transfer' % + req = webob.Request.blank('/v3/%s/os-volume-transfer' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -284,7 +284,7 @@ class VolumeTransferAPITestCase(test.TestCase): body = {"transfer": {"name": " transfer1 ", "volume_id": volume_id}} - req = webob.Request.blank('/v2/%s/os-volume-transfer' % + req = webob.Request.blank('/v3/%s/os-volume-transfer' % fake.PROJECT_ID) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -302,7 +302,7 @@ class VolumeTransferAPITestCase(test.TestCase): def test_delete_transfer_awaiting_transfer(self): volume_id = self._create_volume() transfer = self._create_transfer(volume_id) - req = webob.Request.blank('/v2/%s/os-volume-transfer/%s' % ( + req = webob.Request.blank('/v3/%s/os-volume-transfer/%s' % ( fake.PROJECT_ID, transfer['id'])) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' @@ -312,7 +312,7 @@ class VolumeTransferAPITestCase(test.TestCase): self.assertEqual(HTTPStatus.ACCEPTED, res.status_int) # verify transfer has been deleted - req = webob.Request.blank('/v2/%s/os-volume-transfer/%s' % ( + req = webob.Request.blank('/v3/%s/os-volume-transfer/%s' % ( fake.PROJECT_ID, transfer['id'])) req.method = 'GET' req.headers['Content-Type'] = 'application/json' @@ -331,7 +331,7 @@ class VolumeTransferAPITestCase(test.TestCase): db.volume_destroy(context.get_admin_context(), volume_id) def test_delete_transfer_with_transfer_NotFound(self): - req = webob.Request.blank('/v2/%s/os-volume-transfer/%s' % ( + req = webob.Request.blank('/v3/%s/os-volume-transfer/%s' % ( fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID)) req.method = 'DELETE' req.headers['Content-Type'] = 'application/json' @@ -347,14 +347,14 @@ class VolumeTransferAPITestCase(test.TestCase): res_dict['itemNotFound']['message']) @mock.patch.object(quota.QUOTAS, 'reserve') - @mock.patch.object(db, 'volume_type_get', v2_fakes.fake_volume_type_get) + @mock.patch.object(db, 'volume_type_get', v3_fakes.fake_volume_type_get) def test_accept_transfer_volume_id_specified_json(self, type_get): volume_id = self._create_volume() transfer = self._create_transfer(volume_id) svc = self.start_service('volume', host='fake_host') body = {"accept": {"auth_key": transfer['auth_key']}} - req = webob.Request.blank('/v2/%s/os-volume-transfer/%s/accept' % ( + req = webob.Request.blank('/v3/%s/os-volume-transfer/%s/accept' % ( fake.PROJECT_ID, transfer['id'])) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -373,7 +373,7 @@ class VolumeTransferAPITestCase(test.TestCase): volume_id = self._create_volume(size=5) transfer = self._create_transfer(volume_id) - req = webob.Request.blank('/v2/%s/os-volume-transfer/%s/accept' % ( + req = webob.Request.blank('/v3/%s/os-volume-transfer/%s/accept' % ( fake.PROJECT_ID, transfer['id'])) req.body = jsonutils.dump_as_bytes(None) req.method = 'POST' @@ -394,7 +394,7 @@ class VolumeTransferAPITestCase(test.TestCase): volume_id = self._create_volume(size=5) transfer = self._create_transfer(volume_id) - req = webob.Request.blank('/v2/%s/os-volume-transfer/%s/accept' % ( + req = webob.Request.blank('/v3/%s/os-volume-transfer/%s/accept' % ( fake.PROJECT_ID, transfer['id'])) body = {"": {}} req.method = 'POST' @@ -418,7 +418,7 @@ class VolumeTransferAPITestCase(test.TestCase): transfer = self._create_transfer(volume_id) body = {"accept": {"auth_key": 1}} - req = webob.Request.blank('/v2/%s/os-volume-transfer/%s/accept' % ( + req = webob.Request.blank('/v3/%s/os-volume-transfer/%s/accept' % ( fake.PROJECT_ID, transfer['id'])) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -442,7 +442,7 @@ class VolumeTransferAPITestCase(test.TestCase): transfer = self._create_transfer(volume_id) body = {"accept": {"auth_key": 1}} - req = webob.Request.blank('/v2/%s/os-volume-transfer/%s/accept' % ( + req = webob.Request.blank('/v3/%s/os-volume-transfer/%s/accept' % ( fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' @@ -478,7 +478,7 @@ class VolumeTransferAPITestCase(test.TestCase): transfer = self._create_transfer(volume_id) body = {"accept": {"auth_key": transfer['auth_key']}} - req = webob.Request.blank('/v2/%s/os-volume-transfer/%s/accept' % ( + req = webob.Request.blank('/v3/%s/os-volume-transfer/%s/accept' % ( fake.PROJECT_ID, transfer['id'])) req.method = 'POST' @@ -513,7 +513,7 @@ class VolumeTransferAPITestCase(test.TestCase): transfer = self._create_transfer(volume_id) body = {"accept": {"auth_key": transfer['auth_key']}} - req = webob.Request.blank('/v2/%s/os-volume-transfer/%s/accept' % ( + req = webob.Request.blank('/v3/%s/os-volume-transfer/%s/accept' % ( fake.PROJECT_ID, transfer['id'])) req.method = 'POST' @@ -537,7 +537,7 @@ class VolumeTransferAPITestCase(test.TestCase): transfer = self._create_transfer(volume_id) body = {"accept": {"auth_key": None}} - req = webob.Request.blank('/v2/%s/os-volume-transfer/%s/accept' % ( + req = webob.Request.blank('/v3/%s/os-volume-transfer/%s/accept' % ( fake.PROJECT_ID, transfer['id'])) req.body = jsonutils.dump_as_bytes(body) req.method = 'POST' diff --git a/cinder/tests/unit/api/contrib/test_volume_type_access.py b/cinder/tests/unit/api/contrib/test_volume_type_access.py index 07e45d00584..2dc8c264793 100644 --- a/cinder/tests/unit/api/contrib/test_volume_type_access.py +++ b/cinder/tests/unit/api/contrib/test_volume_type_access.py @@ -18,7 +18,7 @@ from unittest import mock import webob from cinder.api.contrib import volume_type_access as type_access -from cinder.api.v2 import types as types_api_v2 +from cinder.api.v3 import types from cinder import context from cinder import db from cinder import exception @@ -113,7 +113,7 @@ class VolumeTypeAccessTest(test.TestCase): def setUp(self): super(VolumeTypeAccessTest, self).setUp() - self.type_controller_v2 = types_api_v2.VolumeTypesController() + self.type_controller = types.VolumeTypesController() self.type_access_controller = type_access.VolumeTypeAccessController() self.type_action_controller = type_access.VolumeTypeActionController() self.req = FakeRequest() @@ -132,7 +132,7 @@ class VolumeTypeAccessTest(test.TestCase): def test_list_type_access_public(self): """Querying os-volume-type-access on public type should return 404.""" - req = fakes.HTTPRequest.blank('/v2/%s/types/os-volume-type-access' % + req = fakes.HTTPRequest.blank('/v3/%s/types/os-volume-type-access' % fake.PROJECT_ID, use_admin_context=True) self.assertRaises(exception.VolumeTypeAccessNotFound, @@ -150,7 +150,7 @@ class VolumeTypeAccessTest(test.TestCase): self.assertEqual(expected, result) def test_list_with_no_context(self): - req = fakes.HTTPRequest.blank('/v2/flavors/%s/flavors' % + req = fakes.HTTPRequest.blank('/v3/flavors/%s/flavors' % fake.PROJECT_ID) def fake_authorize(context, target=None, action=None): @@ -164,10 +164,10 @@ class VolumeTypeAccessTest(test.TestCase): def test_list_type_with_admin_default_proj1(self): expected = {'volume_types': [{'id': fake.VOLUME_TYPE_ID}, {'id': fake.VOLUME_TYPE2_ID}]} - req = fakes.HTTPRequest.blank('/v2/%s/types' % fake.PROJECT_ID, + req = fakes.HTTPRequest.blank('/v3/%s/types' % fake.PROJECT_ID, use_admin_context=True) req.environ['cinder.context'].project_id = PROJ1_UUID - result = self.type_controller_v2.index(req) + result = self.type_controller.index(req) self.assertVolumeTypeListEqual(expected['volume_types'], result['volume_types']) @@ -175,41 +175,41 @@ class VolumeTypeAccessTest(test.TestCase): expected = {'volume_types': [{'id': fake.VOLUME_TYPE_ID}, {'id': fake.VOLUME_TYPE2_ID}, {'id': fake.VOLUME_TYPE3_ID}]} - req = fakes.HTTPRequest.blank('/v2/%s/types' % PROJ2_UUID, + req = fakes.HTTPRequest.blank('/v3/%s/types' % PROJ2_UUID, use_admin_context=True) req.environ['cinder.context'].project_id = PROJ2_UUID - result = self.type_controller_v2.index(req) + result = self.type_controller.index(req) self.assertVolumeTypeListEqual(expected['volume_types'], result['volume_types']) def test_list_type_with_admin_ispublic_true(self): expected = {'volume_types': [{'id': fake.VOLUME_TYPE_ID}, {'id': fake.VOLUME_TYPE2_ID}]} - req = fakes.HTTPRequest.blank('/v2/%s/types?is_public=true' % + req = fakes.HTTPRequest.blank('/v3/%s/types?is_public=true' % fake.PROJECT_ID, use_admin_context=True) - result = self.type_controller_v2.index(req) + result = self.type_controller.index(req) self.assertVolumeTypeListEqual(expected['volume_types'], result['volume_types']) def test_list_type_with_admin_ispublic_false(self): expected = {'volume_types': [{'id': fake.VOLUME_TYPE3_ID}, {'id': fake.VOLUME_TYPE4_ID}]} - req = fakes.HTTPRequest.blank('/v2/%s/types?is_public=false' % + req = fakes.HTTPRequest.blank('/v3/%s/types?is_public=false' % fake.PROJECT_ID, use_admin_context=True) - result = self.type_controller_v2.index(req) + result = self.type_controller.index(req) self.assertVolumeTypeListEqual(expected['volume_types'], result['volume_types']) def test_list_type_with_admin_ispublic_false_proj2(self): expected = {'volume_types': [{'id': fake.VOLUME_TYPE3_ID}, {'id': fake.VOLUME_TYPE4_ID}]} - req = fakes.HTTPRequest.blank('/v2/%s/types?is_public=false' % + req = fakes.HTTPRequest.blank('/v3/%s/types?is_public=false' % fake.PROJECT_ID, use_admin_context=True) req.environ['cinder.context'].project_id = PROJ2_UUID - result = self.type_controller_v2.index(req) + result = self.type_controller.index(req) self.assertVolumeTypeListEqual(expected['volume_types'], result['volume_types']) @@ -218,49 +218,49 @@ class VolumeTypeAccessTest(test.TestCase): {'id': fake.VOLUME_TYPE2_ID}, {'id': fake.VOLUME_TYPE3_ID}, {'id': fake.VOLUME_TYPE4_ID}]} - req = fakes.HTTPRequest.blank('/v2/%s/types?is_public=none' % + req = fakes.HTTPRequest.blank('/v3/%s/types?is_public=none' % fake.PROJECT_ID, use_admin_context=True) - result = self.type_controller_v2.index(req) + result = self.type_controller.index(req) self.assertVolumeTypeListEqual(expected['volume_types'], result['volume_types']) def test_list_type_with_no_admin_default(self): expected = {'volume_types': [{'id': fake.VOLUME_TYPE_ID}, {'id': fake.VOLUME_TYPE2_ID}]} - req = fakes.HTTPRequest.blank('/v2/%s/types' % fake.PROJECT_ID, + req = fakes.HTTPRequest.blank('/v3/%s/types' % fake.PROJECT_ID, use_admin_context=False) - result = self.type_controller_v2.index(req) + result = self.type_controller.index(req) self.assertVolumeTypeListEqual(expected['volume_types'], result['volume_types']) def test_list_type_with_no_admin_ispublic_true(self): expected = {'volume_types': [{'id': fake.VOLUME_TYPE_ID}, {'id': fake.VOLUME_TYPE2_ID}]} - req = fakes.HTTPRequest.blank('/v2/%s/types?is_public=true' % + req = fakes.HTTPRequest.blank('/v3/%s/types?is_public=true' % fake.PROJECT_ID, use_admin_context=False) - result = self.type_controller_v2.index(req) + result = self.type_controller.index(req) self.assertVolumeTypeListEqual(expected['volume_types'], result['volume_types']) def test_list_type_with_no_admin_ispublic_false(self): expected = {'volume_types': [{'id': fake.VOLUME_TYPE_ID}, {'id': fake.VOLUME_TYPE2_ID}]} - req = fakes.HTTPRequest.blank('/v2/%s/types?is_public=false' % + req = fakes.HTTPRequest.blank('/v3/%s/types?is_public=false' % fake.PROJECT_ID, use_admin_context=False) - result = self.type_controller_v2.index(req) + result = self.type_controller.index(req) self.assertVolumeTypeListEqual(expected['volume_types'], result['volume_types']) def test_list_type_with_no_admin_ispublic_none(self): expected = {'volume_types': [{'id': fake.VOLUME_TYPE_ID}, {'id': fake.VOLUME_TYPE2_ID}]} - req = fakes.HTTPRequest.blank('/v2/%s/types?is_public=none' % + req = fakes.HTTPRequest.blank('/v3/%s/types?is_public=none' % fake.PROJECT_ID, use_admin_context=False) - result = self.type_controller_v2.index(req) + result = self.type_controller.index(req) self.assertVolumeTypeListEqual(expected['volume_types'], result['volume_types']) @@ -295,7 +295,7 @@ class VolumeTypeAccessTest(test.TestCase): self.mock_object(db, 'volume_type_access_add', fake_add_volume_type_access) body = {'addProjectAccess': {'project': PROJ2_UUID}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s/action' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s/action' % ( fake.PROJECT_ID, fake.VOLUME_TYPE3_ID), use_admin_context=True) result = self.type_action_controller._addProjectAccess( @@ -303,7 +303,7 @@ class VolumeTypeAccessTest(test.TestCase): self.assertEqual(HTTPStatus.ACCEPTED, result.status_code) def test_add_project_access_with_no_admin_user(self): - req = fakes.HTTPRequest.blank('/v2/%s/types/%s/action' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s/action' % ( fake.PROJECT_ID, fake.VOLUME_TYPE3_ID), use_admin_context=False) body = {'addProjectAccess': {'project': PROJ2_UUID}} @@ -318,7 +318,7 @@ class VolumeTypeAccessTest(test.TestCase): self.mock_object(db, 'volume_type_access_add', fake_add_volume_type_access) body = {'addProjectAccess': {'project': PROJ2_UUID}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s/action' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s/action' % ( fake.PROJECT_ID, fake.VOLUME_TYPE3_ID), use_admin_context=True) self.assertRaises(webob.exc.HTTPConflict, self.type_action_controller._addProjectAccess, @@ -331,14 +331,14 @@ class VolumeTypeAccessTest(test.TestCase): self.mock_object(db, 'volume_type_access_remove', fake_remove_volume_type_access) body = {'removeProjectAccess': {'project': PROJ2_UUID}} - req = fakes.HTTPRequest.blank('/v2/%s/types/%s/action' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s/action' % ( fake.PROJECT_ID, fake.VOLUME_TYPE3_ID), use_admin_context=True) self.assertRaises(exception.VolumeTypeAccessNotFound, self.type_action_controller._removeProjectAccess, req, fake.VOLUME_TYPE4_ID, body=body) def test_remove_project_access_with_no_admin_user(self): - req = fakes.HTTPRequest.blank('/v2/%s/types/%s/action' % ( + req = fakes.HTTPRequest.blank('/v3/%s/types/%s/action' % ( fake.PROJECT_ID, fake.VOLUME_TYPE3_ID), use_admin_context=False) body = {'removeProjectAccess': {'project': PROJ2_UUID}} self.assertRaises(exception.PolicyNotAuthorized, diff --git a/cinder/tests/unit/api/contrib/test_volume_type_encryption.py b/cinder/tests/unit/api/contrib/test_volume_type_encryption.py index 8a7f35ebebe..9cbb53eaeaf 100644 --- a/cinder/tests/unit/api/contrib/test_volume_type_encryption.py +++ b/cinder/tests/unit/api/contrib/test_volume_type_encryption.py @@ -49,12 +49,12 @@ class VolumeTypeEncryptionTest(test.TestCase): def setUp(self): super(VolumeTypeEncryptionTest, self).setUp() self.flags(host='fake') - self.api_path = '/v2/%s/os-volume-types/%s/encryption' % ( + self.api_path = '/v3/%s/types/%s/encryption' % ( fake.PROJECT_ID, fake.VOLUME_TYPE_ID) """to reset notifier drivers left over from other api/contrib tests""" def _get_response(self, volume_type, admin=True, - url='/v2/%s/types/%s/encryption', + url='/v3/%s/types/%s/encryption', req_method='GET', req_body=None, req_headers=None): ctxt = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, @@ -113,7 +113,7 @@ class VolumeTypeEncryptionTest(test.TestCase): volume_type = self._default_volume_type self._create_type_and_encryption(volume_type) res = self._get_response(volume_type, - url='/v2/%s/types/%s/encryption/key_size') + url='/v3/%s/types/%s/encryption/key_size') res_dict = jsonutils.loads(res.body) self.assertEqual(HTTPStatus.OK, res.status_code) @@ -126,7 +126,7 @@ class VolumeTypeEncryptionTest(test.TestCase): self._create_type_and_encryption(volume_type) res = self._get_response(volume_type, - url='/v2/%s/types/%s/encryption/provider') + url='/v3/%s/types/%s/encryption/provider') res_dict = jsonutils.loads(res.body) self.assertEqual(HTTPStatus.OK, res.status_code) @@ -138,7 +138,7 @@ class VolumeTypeEncryptionTest(test.TestCase): self._create_type_and_encryption(volume_type) res = self._get_response(volume_type, - url='/v2/%s/types/%s/encryption/fake') + url='/v3/%s/types/%s/encryption/fake') res_dict = jsonutils.loads(res.body) self.assertEqual(HTTPStatus.NOT_FOUND, res.status_code) @@ -364,7 +364,7 @@ class VolumeTypeEncryptionTest(test.TestCase): res = self._get_response(volume_type, req_method='GET', req_headers='application/json', - url='/v2/%s/types/%s/encryption') + url='/v3/%s/types/%s/encryption') self.assertEqual(HTTPStatus.OK, res.status_code) res_dict = jsonutils.loads(res.body) self.assertEqual(volume_type['id'], res_dict['volume_type_id']) @@ -372,12 +372,12 @@ class VolumeTypeEncryptionTest(test.TestCase): # Delete, and test that get returns nothing res = self._get_response(volume_type, req_method='DELETE', req_headers='application/json', - url='/v2/%s/types/%s/encryption/provider') + url='/v3/%s/types/%s/encryption/provider') self.assertEqual(HTTPStatus.ACCEPTED, res.status_code) self.assertEqual(0, len(res.body)) res = self._get_response(volume_type, req_method='GET', req_headers='application/json', - url='/v2/%s/types/%s/encryption') + url='/v3/%s/types/%s/encryption') self.assertEqual(HTTPStatus.OK, res.status_code) res_dict = jsonutils.loads(res.body) self.assertEqual({}, res_dict) @@ -401,7 +401,7 @@ class VolumeTypeEncryptionTest(test.TestCase): req_headers='application/json') res = self._get_response(volume_type, req_method='GET', req_headers='application/json', - url='/v2/%s/types/%s/encryption') + url='/v3/%s/types/%s/encryption') self.assertEqual(HTTPStatus.OK, res.status_code) res_dict = jsonutils.loads(res.body) self.assertEqual(volume_type['id'], res_dict['volume_type_id']) @@ -428,7 +428,7 @@ class VolumeTypeEncryptionTest(test.TestCase): # Delete, and test that there is an error since volumes exist res = self._get_response(volume_type, req_method='DELETE', req_headers='application/json', - url='/v2/%s/types/%s/encryption/provider') + url='/v3/%s/types/%s/encryption/provider') self.assertEqual(HTTPStatus.BAD_REQUEST, res.status_code) res_dict = jsonutils.loads(res.body) expected = { @@ -447,12 +447,12 @@ class VolumeTypeEncryptionTest(test.TestCase): # Delete, and test that get returns nothing res = self._get_response(volume_type, req_method='DELETE', req_headers='application/json', - url='/v2/%s/types/%s/encryption/provider') + url='/v3/%s/types/%s/encryption/provider') self.assertEqual(HTTPStatus.ACCEPTED, res.status_code) self.assertEqual(0, len(res.body)) res = self._get_response(volume_type, req_method='GET', req_headers='application/json', - url='/v2/%s/types/%s/encryption') + url='/v3/%s/types/%s/encryption') self.assertEqual(HTTPStatus.OK, res.status_code) res_dict = jsonutils.loads(res.body) self.assertEqual({}, res_dict) @@ -468,7 +468,7 @@ class VolumeTypeEncryptionTest(test.TestCase): # and check if 404 is raised. res = self._get_response(volume_type, req_method='DELETE', req_headers='application/json', - url='/v2/%s/types/%s/encryption/provider') + url='/v3/%s/types/%s/encryption/provider') self.assertEqual(HTTPStatus.NOT_FOUND, res.status_code) expected = { "itemNotFound": { @@ -498,7 +498,7 @@ class VolumeTypeEncryptionTest(test.TestCase): _get_response(volume_type, req_method='PUT', req_body=jsonutils.dump_as_bytes(update_body), req_headers='application/json', - url='/v2/%s/types/%s/encryption/' + + url='/v3/%s/types/%s/encryption/' + fake.ENCRYPTION_KEY_ID) res_dict = jsonutils.loads(res.body) @@ -525,7 +525,7 @@ class VolumeTypeEncryptionTest(test.TestCase): _get_response(volume_type, req_method='PUT', req_body=jsonutils.dump_as_bytes(update_body), req_headers='application/json', - url='/v2/%s/types/%s/encryption/' + + url='/v3/%s/types/%s/encryption/' + fake.ENCRYPTION_KEY_ID) res_dict = jsonutils.loads(res.body) @@ -584,7 +584,7 @@ class VolumeTypeEncryptionTest(test.TestCase): _get_response(volume_type, req_method='PUT', req_body=jsonutils.dump_as_bytes(update_body), req_headers='application/json', - url='/v2/%s/types/%s/encryption/' + + url='/v3/%s/types/%s/encryption/' + fake.ENCRYPTION_KEY_ID) self.assertEqual(HTTPStatus.BAD_REQUEST, res.status_code) res_dict = jsonutils.loads(res.body) diff --git a/cinder/tests/unit/api/contrib/test_volume_unmanage.py b/cinder/tests/unit/api/contrib/test_volume_unmanage.py index 33efc78c997..b18f20353a4 100644 --- a/cinder/tests/unit/api/contrib/test_volume_unmanage.py +++ b/cinder/tests/unit/api/contrib/test_volume_unmanage.py @@ -46,13 +46,13 @@ class VolumeUnmanageTest(test.TestCase): super(VolumeUnmanageTest, self).setUp() self.ctxt = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True) - api = fakes.router.APIRouter() + api = fakes.router_v3.APIRouter() self.app = fakes.urlmap.URLMap() - self.app['/v2'] = api + self.app['/v3'] = api def _get_resp(self, volume_id): """Helper to build an os-unmanage req for the specified volume_id.""" - req = webob.Request.blank('/v2/%s/volumes/%s/action' % + req = webob.Request.blank('/v3/%s/volumes/%s/action' % (self.ctxt.project_id, volume_id)) req.method = 'POST' req.headers['Content-Type'] = 'application/json' diff --git a/cinder/tests/unit/api/fakes.py b/cinder/tests/unit/api/fakes.py index 0e4962e6d87..c16e75c7caa 100644 --- a/cinder/tests/unit/api/fakes.py +++ b/cinder/tests/unit/api/fakes.py @@ -27,8 +27,7 @@ from cinder.api.middleware import fault from cinder.api.openstack import api_version_request as api_version from cinder.api.openstack import wsgi as os_wsgi from cinder.api import urlmap -from cinder.api.v2 import limits -from cinder.api.v2 import router +from cinder.api.v3 import limits from cinder.api.v3 import router as router_v3 from cinder.api import versions from cinder import context @@ -63,8 +62,6 @@ def fake_wsgi(self, req): def wsgi_app(inner_app_v2=None, fake_auth=True, fake_auth_context=None, use_no_auth=False, ext_mgr=None, inner_app_v3=None): - if not inner_app_v2: - inner_app_v2 = router.APIRouter(ext_mgr) if not inner_app_v3: inner_app_v3 = router_v3.APIRouter(ext_mgr) @@ -75,23 +72,16 @@ def wsgi_app(inner_app_v2=None, fake_auth=True, fake_auth_context=None, else: ctxt = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, auth_token=True) - api_v2 = fault.FaultWrapper(auth.InjectContext(ctxt, - inner_app_v2)) api_v3 = fault.FaultWrapper(auth.InjectContext(ctxt, inner_app_v3)) elif use_no_auth: - api_v2 = fault.FaultWrapper(auth.NoAuthMiddleware( - limits.RateLimitingMiddleware(inner_app_v2))) api_v3 = fault.FaultWrapper(auth.NoAuthMiddleware( limits.RateLimitingMiddleware(inner_app_v3))) else: - api_v2 = fault.FaultWrapper(auth.AuthMiddleware( - limits.RateLimitingMiddleware(inner_app_v2))) api_v3 = fault.FaultWrapper(auth.AuthMiddleware( limits.RateLimitingMiddleware(inner_app_v3))) mapper = urlmap.URLMap() - mapper['/v2'] = api_v2 mapper['/v3'] = api_v3 mapper['/'] = fault.FaultWrapper(versions.VersionsController()) return mapper diff --git a/cinder/tests/unit/api/test_versions.py b/cinder/tests/unit/api/test_versions.py index 7af1c2efc15..df6d515a539 100644 --- a/cinder/tests/unit/api/test_versions.py +++ b/cinder/tests/unit/api/test_versions.py @@ -61,8 +61,7 @@ class VersionsControllerTestCase(test.TestCase): response.headers[VERSION_HEADER_NAME]) self.assertEqual(VERSION_HEADER_NAME, response.headers['Vary']) - @ddt.data('2.0', '3.0') - def test_versions_root(self, version): + def test_versions_root(self): req = self.build_request(base_url='http://localhost') response = req.get_response(versions.Versions()) @@ -71,11 +70,8 @@ class VersionsControllerTestCase(test.TestCase): version_list = body['versions'] ids = [v['id'] for v in version_list] - self.assertEqual({'v2.0', 'v3.0'}, set(ids)) - - v2 = [v for v in version_list if v['id'] == 'v2.0'][0] - self.assertEqual('', v2.get('min_version')) - self.assertEqual('', v2.get('version')) + self.assertEqual(1, len(ids)) + self.assertIn('v3.0', ids) v3 = [v for v in version_list if v['id'] == 'v3.0'][0] self.assertEqual(api_version_request._MAX_API_VERSION, @@ -83,53 +79,36 @@ class VersionsControllerTestCase(test.TestCase): self.assertEqual(api_version_request._MIN_API_VERSION, v3.get('min_version')) - @ddt.data('2.0', '3.0') - def test_all_versions_excludes_disabled(self, version): + def test_all_versions_excludes_disabled(self): + version = '3.0' self.fixture = self.useFixture(config_fixture.Config(CONF)) - if version == '2.0': - self.fixture.config(enable_v2_api=False) - elif version == '3.0': - self.fixture.config(enable_v3_api=False) - else: - return + self.fixture.config(enable_v3_api=False) vc = versions.VersionsController() req = self.build_request(base_url='http://localhost') resp = vc.all(req) all_versions = [x['id'] for x in resp['versions']] self.assertNotIn('v' + version, all_versions) - def test_versions_v2_no_header(self): - req = self.build_request(base_url='http://localhost/v2') - - response = req.get_response(router.APIRouter()) - self.assertEqual(HTTPStatus.OK, response.status_int) - - @ddt.data('2.0', '3.0') - def test_versions(self, version): + def test_versions(self): + version = '3.0' req = self.build_request( base_url='http://localhost/v{}'.format(version[0]), header_version=version) - if version is not None: - req.headers = {VERSION_HEADER_NAME: VOLUME_SERVICE + version} - response = req.get_response(router.APIRouter()) self.assertEqual(HTTPStatus.OK, response.status_int) body = jsonutils.loads(response.body) version_list = body['versions'] ids = [v['id'] for v in version_list] - self.assertEqual({'v{}'.format(version)}, set(ids)) + self.assertEqual(1, len(ids)) + self.assertIn('v{}'.format(version), ids) - if version == '3.0': - self.check_response(response, version) - self.assertEqual(api_version_request._MAX_API_VERSION, - version_list[0].get('version')) - self.assertEqual(api_version_request._MIN_API_VERSION, - version_list[0].get('min_version')) - else: - self.assertEqual('', version_list[0].get('min_version')) - self.assertEqual('', version_list[0].get('version')) + self.check_response(response, version) + self.assertEqual(api_version_request._MAX_API_VERSION, + version_list[0].get('version')) + self.assertEqual(api_version_request._MIN_API_VERSION, + version_list[0].get('min_version')) def test_versions_version_latest(self): req = self.build_request(header_version='latest') @@ -147,8 +126,8 @@ class VersionsControllerTestCase(test.TestCase): self.assertEqual(HTTPStatus.BAD_REQUEST, response.status_int) - @ddt.data('2.0', '3.0') - def test_versions_response_fault(self, version): + def test_versions_response_fault(self): + version = '3.0' req = self.build_request(header_version=version) req.api_version_request = ( api_version_request.APIVersionRequest(version)) @@ -157,10 +136,7 @@ class VersionsControllerTestCase(test.TestCase): response = req.get_response(app) self.assertEqual(HTTPStatus.BAD_REQUEST, response.status_int) - if version == '3.0': - self.check_response(response, '3.0') - else: - self.assertNotIn(VERSION_HEADER_NAME, response.headers) + self.check_response(response, '3.0') def test_versions_inheritance_internals_of_non_base_controller(self): """Test ControllerMetaclass works inheriting from non base class.""" diff --git a/cinder/tests/unit/api/v3/fakes.py b/cinder/tests/unit/api/v3/fakes.py index 7b931fb7035..8805dbdcbde 100644 --- a/cinder/tests/unit/api/v3/fakes.py +++ b/cinder/tests/unit/api/v3/fakes.py @@ -14,6 +14,7 @@ import datetime import iso8601 +from cinder.objects import fields from cinder.tests.unit import fake_constants as fake from cinder.tests.unit import fake_volume from cinder import utils @@ -115,3 +116,46 @@ def fake_volume_create(self, context, size, name, description, snapshot=None, if group_id: vol['group_id'] = group_id return vol + + +def fake_volume_type_get(context, id, *args, **kwargs): + return {'id': id, + 'name': 'vol_type_name', + 'description': 'A fake volume type', + 'is_public': True, + 'projects': [], + 'extra_specs': {}, + 'created_at': None, + 'deleted_at': None, + 'updated_at': None, + 'qos_specs_id': fake.QOS_SPEC_ID, + 'deleted': False} + + +def fake_default_type_get(id=fake.VOLUME_TYPE_ID): + return {'id': id, + 'name': 'vol_type_name', + 'description': 'A fake volume type', + 'is_public': True, + 'projects': [], + 'extra_specs': {}, + 'created_at': None, + 'deleted_at': None, + 'updated_at': None, + 'qos_specs_id': fake.QOS_SPEC_ID, + 'deleted': False} + + +def fake_snapshot(id, **kwargs): + snapshot = {'id': id, + 'volume_id': fake.VOLUME_ID, + 'status': fields.SnapshotStatus.AVAILABLE, + 'volume_size': 100, + 'created_at': None, + 'display_name': 'Default name', + 'display_description': 'Default description', + 'project_id': fake.PROJECT_ID, + 'snapshot_metadata': []} + + snapshot.update(kwargs) + return snapshot diff --git a/cinder/tests/unit/api/v3/test_backups.py b/cinder/tests/unit/api/v3/test_backups.py index f2c9d81f649..217232702f7 100644 --- a/cinder/tests/unit/api/v3/test_backups.py +++ b/cinder/tests/unit/api/v3/test_backups.py @@ -259,7 +259,7 @@ class BackupsControllerAPITestCase(test.TestCase): # backup update call doesn't return 'description' in response so get # the updated backup to assert name and description - req = webob.Request.blank('/v2/%s/backups/%s' % ( + req = webob.Request.blank('/v3/%s/backups/%s' % ( fake.PROJECT_ID, backup.id)) req.method = 'GET' req.headers['Content-Type'] = 'application/json' diff --git a/cinder/tests/unit/api/v2/test_snapshot_metadata.py b/cinder/tests/unit/api/v3/test_snapshot_metadata.py similarity index 98% rename from cinder/tests/unit/api/v2/test_snapshot_metadata.py rename to cinder/tests/unit/api/v3/test_snapshot_metadata.py index 13ed0d0fe17..abd9314a7b5 100644 --- a/cinder/tests/unit/api/v2/test_snapshot_metadata.py +++ b/cinder/tests/unit/api/v3/test_snapshot_metadata.py @@ -22,15 +22,15 @@ from oslo_serialization import jsonutils import webob from cinder.api import extensions -from cinder.api.v2 import snapshot_metadata from cinder.api.v2 import snapshots +from cinder.api.v3 import snapshot_metadata from cinder import context import cinder.db from cinder import exception from cinder.objects import fields from cinder.scheduler import rpcapi as scheduler_rpcapi from cinder.tests.unit.api import fakes -from cinder.tests.unit.api.v2 import fakes as v2_fakes +from cinder.tests.unit.api.v3 import fakes as v3_fakes from cinder.tests.unit import fake_constants as fake from cinder.tests.unit import fake_snapshot from cinder.tests.unit import fake_volume @@ -116,7 +116,7 @@ class SnapshotMetaDataTest(test.TestCase): self.volume_api = cinder.volume.api.API() self.mock_object(volume.api.API, 'get', fake_get) self.mock_object(cinder.db.sqlalchemy.api, 'volume_type_get', - v2_fakes.fake_volume_type_get) + v3_fakes.fake_volume_type_get) self.mock_object(scheduler_rpcapi.SchedulerAPI, 'create_snapshot') self.mock_object(cinder.db, 'snapshot_get', return_snapshot) self.mock_object(self.volume_api, 'update_snapshot_metadata') @@ -128,7 +128,7 @@ class SnapshotMetaDataTest(test.TestCase): self.snapshot_controller = snapshots.SnapshotsController(self.ext_mgr) self.controller = snapshot_metadata.Controller() self.req_id = str(uuid.uuid4()) - self.url = '/v2/%s/snapshots/%s/metadata' % ( + self.url = '/v3/%s/snapshots/%s/metadata' % ( fake.PROJECT_ID, self.req_id) snap = {"volume_id": fake.VOLUME_ID, @@ -136,7 +136,7 @@ class SnapshotMetaDataTest(test.TestCase): "description": "Volume Test Desc", "metadata": {}} body = {"snapshot": snap} - req = fakes.HTTPRequest.blank('/v2/snapshots') + req = fakes.HTTPRequest.blank('/v3/snapshots') self.snapshot_controller.create(req, body=body) @mock.patch('cinder.objects.Snapshot.get_by_id') @@ -286,7 +286,7 @@ class SnapshotMetaDataTest(test.TestCase): self.mock_object(cinder.db, 'snapshot_metadata_update', return_create_snapshot_metadata) - req = fakes.HTTPRequest.blank('/v2/snapshot_metadata') + req = fakes.HTTPRequest.blank('/v3/snapshot_metadata') req.method = 'POST' req.content_type = "application/json" body = {"metadata": {"key1": "value1", @@ -313,7 +313,7 @@ class SnapshotMetaDataTest(test.TestCase): self.mock_object(cinder.db, 'snapshot_metadata_update', return_create_snapshot_metadata_insensitive) - req = fakes.HTTPRequest.blank('/v2/snapshot_metadata') + req = fakes.HTTPRequest.blank('/v3/snapshot_metadata') req.method = 'POST' req.content_type = "application/json" body = {"metadata": {"key1": "value1", @@ -371,7 +371,7 @@ class SnapshotMetaDataTest(test.TestCase): self.mock_object(cinder.db, 'snapshot_metadata_update', return_create_snapshot_metadata) - req = fakes.HTTPRequest.blank('/v2/snapshot_metadata') + req = fakes.HTTPRequest.blank('/v3/snapshot_metadata') req.method = 'POST' req.content_type = "application/json" body = {"metadata": {"key9": "value9"}} @@ -534,7 +534,7 @@ class SnapshotMetaDataTest(test.TestCase): self.mock_object(cinder.db, 'snapshot_get', return_snapshot_nonexistent) req = fakes.HTTPRequest.blank( - '/v2/%s/snapshots/asdf/metadata/key1' % fake.PROJECT_ID) + '/v3/%s/snapshots/asdf/metadata/key1' % fake.PROJECT_ID) req.method = 'PUT' body = {"meta": {"key1": "value1"}} req.body = jsonutils.dump_as_bytes(body) diff --git a/cinder/tests/unit/api/v3/test_types.py b/cinder/tests/unit/api/v3/test_types.py index 7b654ff00b6..0fd58957787 100644 --- a/cinder/tests/unit/api/v3/test_types.py +++ b/cinder/tests/unit/api/v3/test_types.py @@ -11,7 +11,7 @@ # under the License. from cinder.api import microversions as mv -from cinder.api.v2 import types +from cinder.api.v3 import types from cinder import context from cinder import db from cinder import exception diff --git a/cinder/tests/unit/api/v2/test_types.py b/cinder/tests/unit/api/v3/test_types_orig.py similarity index 92% rename from cinder/tests/unit/api/v2/test_types.py rename to cinder/tests/unit/api/v3/test_types_orig.py index 9b6fa30b49c..1a1f4fa81b1 100644 --- a/cinder/tests/unit/api/v2/test_types.py +++ b/cinder/tests/unit/api/v3/test_types_orig.py @@ -18,8 +18,8 @@ from unittest import mock from oslo_utils import timeutils import webob -from cinder.api.v2 import types -from cinder.api.v2.views import types as views_types +from cinder.api.v3 import types +from cinder.api.v3.views import types as views_types from cinder import context from cinder import exception from cinder.policies import volume_type as type_policy @@ -109,7 +109,7 @@ class VolumeTypesApiTest(test.TestCase): self.mock_object(volume_types, 'get_all_types', return_volume_types_get_all_types) - req = fakes.HTTPRequest.blank('/v2/%s/types' % fake.PROJECT_ID, + req = fakes.HTTPRequest.blank('/v3/%s/types' % fake.PROJECT_ID, use_admin_context=True) res_dict = self.controller.index(req) @@ -126,41 +126,41 @@ class VolumeTypesApiTest(test.TestCase): self.mock_object(volume_types, 'get_all_types', return_empty_volume_types_get_all_types) - req = fakes.HTTPRequest.blank('/v2/%s/types' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/types' % fake.PROJECT_ID) res_dict = self.controller.index(req) self.assertEqual(0, len(res_dict['volume_types'])) def test_volume_types_index_with_limit(self): - req = fakes.HTTPRequest.blank('/v2/%s/types?limit=1' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/types?limit=1' % fake.PROJECT_ID) req.environ['cinder.context'] = self.ctxt res = self.controller.index(req) self.assertEqual(1, len(res['volume_types'])) self.assertEqual(self.type_id3, res['volume_types'][0]['id']) - expect_next_link = ('http://localhost/v2/%s/types?limit=1' + expect_next_link = ('http://localhost/v3/%s/types?limit=1' '&marker=%s' % (fake.PROJECT_ID, res['volume_types'][0]['id'])) self.assertEqual(expect_next_link, res['volume_type_links'][0]['href']) def test_volume_types_index_with_offset(self): req = fakes.HTTPRequest.blank( - '/v2/%s/types?offset=1' % fake.PROJECT_ID) + '/v3/%s/types?offset=1' % fake.PROJECT_ID) req.environ['cinder.context'] = self.ctxt res = self.controller.index(req) self.assertEqual(3, len(res['volume_types'])) def test_volume_types_index_with_offset_out_of_range(self): - url = '/v2/%s/types?offset=424366766556787' % fake.PROJECT_ID + url = '/v3/%s/types?offset=424366766556787' % fake.PROJECT_ID req = fakes.HTTPRequest.blank(url) self.assertRaises(webob.exc.HTTPBadRequest, self.controller.index, req) def test_volume_types_index_with_limit_and_offset(self): req = fakes.HTTPRequest.blank( - '/v2/%s/types?limit=2&offset=1' % fake.PROJECT_ID) + '/v3/%s/types?limit=2&offset=1' % fake.PROJECT_ID) req.environ['cinder.context'] = self.ctxt res = self.controller.index(req) @@ -169,7 +169,7 @@ class VolumeTypesApiTest(test.TestCase): self.assertEqual(self.type_id1, res['volume_types'][1]['id']) def test_volume_types_index_with_limit_and_marker(self): - req = fakes.HTTPRequest.blank('/v2/%s/types?limit=1' + req = fakes.HTTPRequest.blank('/v3/%s/types?limit=1' '&marker=%s' % (fake.PROJECT_ID, self.type_id2)) @@ -181,7 +181,7 @@ class VolumeTypesApiTest(test.TestCase): def test_volume_types_index_with_valid_filter(self): req = fakes.HTTPRequest.blank( - '/v2/%s/types?is_public=True' % fake.PROJECT_ID) + '/v3/%s/types?is_public=True' % fake.PROJECT_ID) req.environ['cinder.context'] = self.ctxt res = self.controller.index(req) @@ -192,7 +192,7 @@ class VolumeTypesApiTest(test.TestCase): def test_volume_types_index_with_invalid_filter(self): req = fakes.HTTPRequest.blank( - '/v2/%s/types?id=%s' % (fake.PROJECT_ID, self.type_id1)) + '/v3/%s/types?id=%s' % (fake.PROJECT_ID, self.type_id1)) req.environ['cinder.context'] = context.RequestContext( user_id=fake.USER_ID, project_id=fake.PROJECT_ID, is_admin=False) res = self.controller.index(req) @@ -200,7 +200,7 @@ class VolumeTypesApiTest(test.TestCase): self.assertEqual(4, len(res['volume_types'])) def test_volume_types_index_with_sort_keys(self): - req = fakes.HTTPRequest.blank('/v2/%s/types?sort=id' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/types?sort=id' % fake.PROJECT_ID) req.environ['cinder.context'] = self.ctxt res = self.controller.index(req) expect_result = [self.default_type, self.type_id1, @@ -215,7 +215,7 @@ class VolumeTypesApiTest(test.TestCase): def test_volume_types_index_with_sort_and_limit(self): req = fakes.HTTPRequest.blank( - '/v2/%s/types?sort=id&limit=2' % fake.PROJECT_ID) + '/v3/%s/types?sort=id&limit=2' % fake.PROJECT_ID) req.environ['cinder.context'] = self.ctxt res = self.controller.index(req) @@ -229,7 +229,7 @@ class VolumeTypesApiTest(test.TestCase): def test_volume_types_index_with_sort_keys_and_sort_dirs(self): req = fakes.HTTPRequest.blank( - '/v2/%s/types?sort=id:asc' % fake.PROJECT_ID) + '/v3/%s/types?sort=id:asc' % fake.PROJECT_ID) req.environ['cinder.context'] = self.ctxt res = self.controller.index(req) expect_result = [self.default_type, self.type_id1, @@ -247,7 +247,7 @@ class VolumeTypesApiTest(test.TestCase): return_volume_types_get_volume_type) type_id = fake.VOLUME_TYPE_ID - req = fakes.HTTPRequest.blank('/v2/%s/types/' % fake.PROJECT_ID + req = fakes.HTTPRequest.blank('/v3/%s/types/' % fake.PROJECT_ID + type_id) res_dict = self.controller.show(req, type_id) @@ -262,7 +262,7 @@ class VolumeTypesApiTest(test.TestCase): self.mock_object(volume_types, 'get_volume_type', return_volume_types_get_volume_type) - req = fakes.HTTPRequest.blank('/v2/%s/types/%s' % + req = fakes.HTTPRequest.blank('/v3/%s/types/%s' % (fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID)) self.assertRaises(exception.VolumeTypeNotFound, self.controller.show, @@ -271,7 +271,7 @@ class VolumeTypesApiTest(test.TestCase): def test_get_default(self): self.mock_object(volume_types, 'get_default_volume_type', return_volume_types_get_default) - req = fakes.HTTPRequest.blank('/v2/%s/types/default' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/types/default' % fake.PROJECT_ID) req.method = 'GET' res_dict = self.controller.show(req, 'default') self.assertEqual(1, len(res_dict)) @@ -282,7 +282,7 @@ class VolumeTypesApiTest(test.TestCase): def test_get_default_not_found(self): self.mock_object(volume_types, 'get_default_volume_type', return_value={}) - req = fakes.HTTPRequest.blank('/v2/%s/types/default' % fake.PROJECT_ID) + req = fakes.HTTPRequest.blank('/v3/%s/types/default' % fake.PROJECT_ID) req.method = 'GET' self.assertRaises(exception.VolumeTypeNotFound, @@ -305,7 +305,7 @@ class VolumeTypesApiTest(test.TestCase): id=42, ) - request = fakes.HTTPRequest.blank("/v2") + request = fakes.HTTPRequest.blank("/v3") output = view_builder.show(request, raw_volume_type) self.assertIn('volume_type', output) @@ -334,7 +334,7 @@ class VolumeTypesApiTest(test.TestCase): id=42, ) - request = fakes.HTTPRequest.blank("/v2", use_admin_context=True) + request = fakes.HTTPRequest.blank("/v3", use_admin_context=True) output = view_builder.show(request, raw_volume_type) self.assertIn('volume_type', output) @@ -366,7 +366,7 @@ class VolumeTypesApiTest(test.TestCase): id=42, ) - request = fakes.HTTPRequest.blank("/v2") + request = fakes.HTTPRequest.blank("/v3") output = view_builder.show(request, raw_volume_type) self.assertIn('volume_type', output) @@ -397,7 +397,7 @@ class VolumeTypesApiTest(test.TestCase): id=42, ) - request = fakes.HTTPRequest.blank("/v2") + request = fakes.HTTPRequest.blank("/v3") output = view_builder.show(request, raw_volume_type) self.assertIn('volume_type', output) @@ -427,7 +427,7 @@ class VolumeTypesApiTest(test.TestCase): id=42, ) - request = fakes.HTTPRequest.blank("/v2") + request = fakes.HTTPRequest.blank("/v3") output = view_builder.show(request, raw_volume_type) self.assertIn('volume_type', output) @@ -457,7 +457,7 @@ class VolumeTypesApiTest(test.TestCase): id=42, ) - request = fakes.HTTPRequest.blank("/v2") + request = fakes.HTTPRequest.blank("/v3") output = view_builder.show(request, raw_volume_type) self.assertIn('volume_type', output) @@ -492,7 +492,7 @@ class VolumeTypesApiTest(test.TestCase): ) ) - request = fakes.HTTPRequest.blank("/v2") + request = fakes.HTTPRequest.blank("/v3") output = view_builder.index(request, raw_volume_types) self.assertIn('volume_types', output) @@ -527,7 +527,7 @@ class VolumeTypesApiTest(test.TestCase): ) ) - request = fakes.HTTPRequest.blank("/v2", use_admin_context=True) + request = fakes.HTTPRequest.blank("/v3", use_admin_context=True) output = view_builder.index(request, raw_volume_types) self.assertIn('volume_types', output) diff --git a/contrib/block-box/etc/api-paste.ini b/contrib/block-box/etc/api-paste.ini index cb783b8c1ed..58bc48fd38e 100644 --- a/contrib/block-box/etc/api-paste.ini +++ b/contrib/block-box/etc/api-paste.ini @@ -5,15 +5,8 @@ [composite:osapi_volume] use = call:cinder.api:root_app_factory /: apiversions -/v2: openstack_volume_api_v2 /v3: openstack_volume_api_v3 -[composite:openstack_volume_api_v2] -use = call:cinder.api.middleware.auth:pipeline_factory -noauth = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler noauth apiv2 -keystone = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler authtoken keystonecontext apiv2 -keystone_nolimit = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler authtoken keystonecontext apiv2 - [composite:openstack_volume_api_v3] use = call:cinder.api.middleware.auth:pipeline_factory noauth = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler noauth apiv3 @@ -42,9 +35,6 @@ paste.filter_factory = cinder.api.middleware.auth:NoAuthMiddleware.factory [filter:sizelimit] paste.filter_factory = oslo_middleware.sizelimit:RequestBodySizeLimiter.factory -[app:apiv2] -paste.app_factory = cinder.api.v2.router:APIRouter.factory - [app:apiv3] paste.app_factory = cinder.api.v3.router:APIRouter.factory diff --git a/doc/source/admin/blockstorage-get-capabilities.rst b/doc/source/admin/blockstorage-get-capabilities.rst index aa12d71b99f..2bdcbf5ee47 100644 --- a/doc/source/admin/blockstorage-get-capabilities.rst +++ b/doc/source/admin/blockstorage-get-capabilities.rst @@ -120,7 +120,7 @@ API request: .. code-block:: console - GET /v2/{tenant_id}/capabilities/{hostname} + GET /v3/{tenant_id}/capabilities/{hostname} Example of return value: diff --git a/doc/source/configuration/block-storage/drivers/dell-emc-unity-driver.rst b/doc/source/configuration/block-storage/drivers/dell-emc-unity-driver.rst index a011adc4403..8a08a287333 100644 --- a/doc/source/configuration/block-storage/drivers/dell-emc-unity-driver.rst +++ b/doc/source/configuration/block-storage/drivers/dell-emc-unity-driver.rst @@ -441,7 +441,7 @@ Force detach volume from all hosts The user could use `os-force_detach` action to detach a volume from all its attached hosts. For more detail, please refer to -https://docs.openstack.org/api-ref/block-storage/v2/?expanded=force-detach-volume-detail#force-detach-volume +https://docs.openstack.org/api-ref/block-storage/v3/?expanded=force-detach-a-volume-detail#force-detach-a-volume Consistent group support ~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/source/configuration/block-storage/drivers/dell-emc-vnx-driver.rst b/doc/source/configuration/block-storage/drivers/dell-emc-vnx-driver.rst index 8e58ff697e8..d392e9f7628 100644 --- a/doc/source/configuration/block-storage/drivers/dell-emc-vnx-driver.rst +++ b/doc/source/configuration/block-storage/drivers/dell-emc-vnx-driver.rst @@ -620,7 +620,7 @@ Force detach The user could use `os-force_detach` action to detach a volume from all its attached hosts. For more detail, please refer to -https://docs.openstack.org/api-ref/block-storage/v2/?expanded=force-detach-volume-detail#force-detach-volume +https://docs.openstack.org/api-ref/block-storage/v3/?expanded=force-detach-a-volume-detail#force-detach-a-volume Advanced features diff --git a/doc/source/configuration/block-storage/samples/api-paste.ini.inc b/doc/source/configuration/block-storage/samples/api-paste.ini.inc index cb783b8c1ed..58bc48fd38e 100644 --- a/doc/source/configuration/block-storage/samples/api-paste.ini.inc +++ b/doc/source/configuration/block-storage/samples/api-paste.ini.inc @@ -5,15 +5,8 @@ [composite:osapi_volume] use = call:cinder.api:root_app_factory /: apiversions -/v2: openstack_volume_api_v2 /v3: openstack_volume_api_v3 -[composite:openstack_volume_api_v2] -use = call:cinder.api.middleware.auth:pipeline_factory -noauth = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler noauth apiv2 -keystone = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler authtoken keystonecontext apiv2 -keystone_nolimit = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler authtoken keystonecontext apiv2 - [composite:openstack_volume_api_v3] use = call:cinder.api.middleware.auth:pipeline_factory noauth = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler noauth apiv3 @@ -42,9 +35,6 @@ paste.filter_factory = cinder.api.middleware.auth:NoAuthMiddleware.factory [filter:sizelimit] paste.filter_factory = oslo_middleware.sizelimit:RequestBodySizeLimiter.factory -[app:apiv2] -paste.app_factory = cinder.api.v2.router:APIRouter.factory - [app:apiv3] paste.app_factory = cinder.api.v3.router:APIRouter.factory diff --git a/doc/source/contributor/addmethod.openstackapi.rst b/doc/source/contributor/addmethod.openstackapi.rst index 3b3e90e6d77..829c12a3052 100644 --- a/doc/source/contributor/addmethod.openstackapi.rst +++ b/doc/source/contributor/addmethod.openstackapi.rst @@ -45,7 +45,7 @@ Controllers and actions Controllers live in ``cinder/api/openstack``, and inherit from cinder.wsgi.Controller. -See ``cinder/api/v2/volumes.py`` for an example. +See ``cinder/api/v3/volumes.py`` for an example. Action methods take parameters that are sucked out of the URL by mapper.connect() or .resource(). The first two parameters are self and the diff --git a/doc/source/install/cinder-controller-install-obs.rst b/doc/source/install/cinder-controller-install-obs.rst index 08568900237..a9b0dbba7ff 100644 --- a/doc/source/install/cinder-controller-install-obs.rst +++ b/doc/source/install/cinder-controller-install-obs.rst @@ -78,22 +78,7 @@ must create a database, service credentials, and API endpoints. This command provides no output. - #. Create the ``cinderv2`` and ``cinderv3`` service entities: - - .. code-block:: console - - $ openstack service create --name cinderv2 \ - --description "OpenStack Block Storage" volumev2 - - +-------------+----------------------------------+ - | Field | Value | - +-------------+----------------------------------+ - | description | OpenStack Block Storage | - | enabled | True | - | id | eb9fd245bdbc414695952e93f29fe3ac | - | name | cinderv2 | - | type | volumev2 | - +-------------+----------------------------------+ + #. Create the ``cinderv3`` service entity: .. code-block:: console @@ -110,65 +95,14 @@ must create a database, service credentials, and API endpoints. | type | volumev3 | +-------------+----------------------------------+ -.. note:: + .. note:: - The Block Storage services require two service entities. + Beginning with the Xena release, the Block Storage services + require only one service entity. For prior releases, please + consult the documentation for that specific release. #. Create the Block Storage service API endpoints: - .. code-block:: console - - $ openstack endpoint create --region RegionOne \ - volumev2 public http://controller:8776/v2/%\(project_id\)s - - +--------------+------------------------------------------+ - | Field | Value | - +--------------+------------------------------------------+ - | enabled | True | - | id | 513e73819e14460fb904163f41ef3759 | - | interface | public | - | region | RegionOne | - | region_id | RegionOne | - | service_id | eb9fd245bdbc414695952e93f29fe3ac | - | service_name | cinderv2 | - | service_type | volumev2 | - | url | http://controller:8776/v2/%(project_id)s | - +--------------+------------------------------------------+ - - $ openstack endpoint create --region RegionOne \ - volumev2 internal http://controller:8776/v2/%\(project_id\)s - - +--------------+------------------------------------------+ - | Field | Value | - +--------------+------------------------------------------+ - | enabled | True | - | id | 6436a8a23d014cfdb69c586eff146a32 | - | interface | internal | - | region | RegionOne | - | region_id | RegionOne | - | service_id | eb9fd245bdbc414695952e93f29fe3ac | - | service_name | cinderv2 | - | service_type | volumev2 | - | url | http://controller:8776/v2/%(project_id)s | - +--------------+------------------------------------------+ - - $ openstack endpoint create --region RegionOne \ - volumev2 admin http://controller:8776/v2/%\(project_id\)s - - +--------------+------------------------------------------+ - | Field | Value | - +--------------+------------------------------------------+ - | enabled | True | - | id | e652cf84dd334f359ae9b045a2c91d96 | - | interface | admin | - | region | RegionOne | - | region_id | RegionOne | - | service_id | eb9fd245bdbc414695952e93f29fe3ac | - | service_name | cinderv2 | - | service_type | volumev2 | - | url | http://controller:8776/v2/%(project_id)s | - +--------------+------------------------------------------+ - .. code-block:: console $ openstack endpoint create --region RegionOne \ @@ -222,10 +156,6 @@ must create a database, service credentials, and API endpoints. | url | http://controller:8776/v3/%(project_id)s | +--------------+------------------------------------------+ - .. note:: - - The Block Storage services require endpoints for each service - entity. Install and configure components -------------------------------- diff --git a/doc/source/install/cinder-controller-install-rdo.rst b/doc/source/install/cinder-controller-install-rdo.rst index 8936e643fec..3130076be24 100644 --- a/doc/source/install/cinder-controller-install-rdo.rst +++ b/doc/source/install/cinder-controller-install-rdo.rst @@ -78,22 +78,7 @@ must create a database, service credentials, and API endpoints. This command provides no output. - #. Create the ``cinderv2`` and ``cinderv3`` service entities: - - .. code-block:: console - - $ openstack service create --name cinderv2 \ - --description "OpenStack Block Storage" volumev2 - - +-------------+----------------------------------+ - | Field | Value | - +-------------+----------------------------------+ - | description | OpenStack Block Storage | - | enabled | True | - | id | eb9fd245bdbc414695952e93f29fe3ac | - | name | cinderv2 | - | type | volumev2 | - +-------------+----------------------------------+ + #. Create the ``cinderv3`` service entity: .. code-block:: console @@ -112,63 +97,12 @@ must create a database, service credentials, and API endpoints. .. note:: - The Block Storage services require two service entities. + Beginning with the Xena release, the Block Storage services + require only one service entity. For prior releases, please + consult the documentation for that specific release. #. Create the Block Storage service API endpoints: - .. code-block:: console - - $ openstack endpoint create --region RegionOne \ - volumev2 public http://controller:8776/v2/%\(project_id\)s - - +--------------+------------------------------------------+ - | Field | Value | - +--------------+------------------------------------------+ - | enabled | True | - | id | 513e73819e14460fb904163f41ef3759 | - | interface | public | - | region | RegionOne | - | region_id | RegionOne | - | service_id | eb9fd245bdbc414695952e93f29fe3ac | - | service_name | cinderv2 | - | service_type | volumev2 | - | url | http://controller:8776/v2/%(project_id)s | - +--------------+------------------------------------------+ - - $ openstack endpoint create --region RegionOne \ - volumev2 internal http://controller:8776/v2/%\(project_id\)s - - +--------------+------------------------------------------+ - | Field | Value | - +--------------+------------------------------------------+ - | enabled | True | - | id | 6436a8a23d014cfdb69c586eff146a32 | - | interface | internal | - | region | RegionOne | - | region_id | RegionOne | - | service_id | eb9fd245bdbc414695952e93f29fe3ac | - | service_name | cinderv2 | - | service_type | volumev2 | - | url | http://controller:8776/v2/%(project_id)s | - +--------------+------------------------------------------+ - - $ openstack endpoint create --region RegionOne \ - volumev2 admin http://controller:8776/v2/%\(project_id\)s - - +--------------+------------------------------------------+ - | Field | Value | - +--------------+------------------------------------------+ - | enabled | True | - | id | e652cf84dd334f359ae9b045a2c91d96 | - | interface | admin | - | region | RegionOne | - | region_id | RegionOne | - | service_id | eb9fd245bdbc414695952e93f29fe3ac | - | service_name | cinderv2 | - | service_type | volumev2 | - | url | http://controller:8776/v2/%(project_id)s | - +--------------+------------------------------------------+ - .. code-block:: console $ openstack endpoint create --region RegionOne \ @@ -222,10 +156,6 @@ must create a database, service credentials, and API endpoints. | url | http://controller:8776/v3/%(project_id)s | +--------------+------------------------------------------+ - .. note:: - - The Block Storage services require endpoints for each service - entity. Install and configure components -------------------------------- diff --git a/doc/source/install/cinder-controller-install-ubuntu.rst b/doc/source/install/cinder-controller-install-ubuntu.rst index 3048256fa17..2f487c99f2a 100644 --- a/doc/source/install/cinder-controller-install-ubuntu.rst +++ b/doc/source/install/cinder-controller-install-ubuntu.rst @@ -79,22 +79,7 @@ must create a database, service credentials, and API endpoints. This command provides no output. - #. Create the ``cinderv2`` and ``cinderv3`` service entities: - - .. code-block:: console - - $ openstack service create --name cinderv2 \ - --description "OpenStack Block Storage" volumev2 - - +-------------+----------------------------------+ - | Field | Value | - +-------------+----------------------------------+ - | description | OpenStack Block Storage | - | enabled | True | - | id | eb9fd245bdbc414695952e93f29fe3ac | - | name | cinderv2 | - | type | volumev2 | - +-------------+----------------------------------+ + #. Create the ``cinderv3`` service entity: .. code-block:: console @@ -111,65 +96,14 @@ must create a database, service credentials, and API endpoints. | type | volumev3 | +-------------+----------------------------------+ - .. note:: + .. note:: - The Block Storage services require two service entities. + Beginning with the Xena release, the Block Storage services + require only one service entity. For prior releases, please + consult the documentation for that specific release. #. Create the Block Storage service API endpoints: - .. code-block:: console - - $ openstack endpoint create --region RegionOne \ - volumev2 public http://controller:8776/v2/%\(project_id\)s - - +--------------+------------------------------------------+ - | Field | Value | - +--------------+------------------------------------------+ - | enabled | True | - | id | 513e73819e14460fb904163f41ef3759 | - | interface | public | - | region | RegionOne | - | region_id | RegionOne | - | service_id | eb9fd245bdbc414695952e93f29fe3ac | - | service_name | cinderv2 | - | service_type | volumev2 | - | url | http://controller:8776/v2/%(project_id)s | - +--------------+------------------------------------------+ - - $ openstack endpoint create --region RegionOne \ - volumev2 internal http://controller:8776/v2/%\(project_id\)s - - +--------------+------------------------------------------+ - | Field | Value | - +--------------+------------------------------------------+ - | enabled | True | - | id | 6436a8a23d014cfdb69c586eff146a32 | - | interface | internal | - | region | RegionOne | - | region_id | RegionOne | - | service_id | eb9fd245bdbc414695952e93f29fe3ac | - | service_name | cinderv2 | - | service_type | volumev2 | - | url | http://controller:8776/v2/%(project_id)s | - +--------------+------------------------------------------+ - - $ openstack endpoint create --region RegionOne \ - volumev2 admin http://controller:8776/v2/%\(project_id\)s - - +--------------+------------------------------------------+ - | Field | Value | - +--------------+------------------------------------------+ - | enabled | True | - | id | e652cf84dd334f359ae9b045a2c91d96 | - | interface | admin | - | region | RegionOne | - | region_id | RegionOne | - | service_id | eb9fd245bdbc414695952e93f29fe3ac | - | service_name | cinderv2 | - | service_type | volumev2 | - | url | http://controller:8776/v2/%(project_id)s | - +--------------+------------------------------------------+ - .. code-block:: console $ openstack endpoint create --region RegionOne \ @@ -223,10 +157,6 @@ must create a database, service credentials, and API endpoints. | url | http://controller:8776/v3/%(project_id)s | +--------------+------------------------------------------+ - .. note:: - - The Block Storage services require endpoints for each service - entity. Install and configure components -------------------------------- diff --git a/etc/cinder/api-paste.ini b/etc/cinder/api-paste.ini index 93764008002..3fbe21b4ec9 100644 --- a/etc/cinder/api-paste.ini +++ b/etc/cinder/api-paste.ini @@ -6,15 +6,8 @@ use = call:cinder.api:root_app_factory /: apiversions /healthcheck: healthcheck -/v2: openstack_volume_api_v2 /v3: openstack_volume_api_v3 -[composite:openstack_volume_api_v2] -use = call:cinder.api.middleware.auth:pipeline_factory -noauth = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler noauth apiv2 -keystone = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler authtoken keystonecontext apiv2 -keystone_nolimit = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler authtoken keystonecontext apiv2 - [composite:openstack_volume_api_v3] use = call:cinder.api.middleware.auth:pipeline_factory noauth = cors http_proxy_to_wsgi request_id faultwrap sizelimit osprofiler noauth apiv3 @@ -43,9 +36,6 @@ paste.filter_factory = cinder.api.middleware.auth:NoAuthMiddleware.factory [filter:sizelimit] paste.filter_factory = oslo_middleware.sizelimit:RequestBodySizeLimiter.factory -[app:apiv2] -paste.app_factory = cinder.api.v2.router:APIRouter.factory - [app:apiv3] paste.app_factory = cinder.api.v3.router:APIRouter.factory diff --git a/rally-jobs/cinder.yaml b/rally-jobs/cinder.yaml index d93966fc6b3..5c83b8bd607 100644 --- a/rally-jobs/cinder.yaml +++ b/rally-jobs/cinder.yaml @@ -1,7 +1,7 @@ {% set image_name = "^(cirros.*-disk|TestVM)$" %} --- version: 2 - title: Rally task for gate-rally-dsvm-cinder-ubuntu-xenial-nv job + title: Rally task for cinder-rally-task check job (non-voting) subtasks: - title: Validate cinder client @@ -31,8 +31,8 @@ users_per_tenant: 2 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - title: Update cinder Quotas scenario: @@ -48,8 +48,8 @@ users_per_tenant: 2 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - title: Create and Delete Volume workloads: @@ -67,8 +67,8 @@ users_per_tenant: 2 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - scenario: CinderVolumes.create_and_delete_volume: @@ -85,8 +85,8 @@ users_per_tenant: 2 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - scenario: CinderVolumes.create_and_delete_volume: @@ -103,8 +103,8 @@ users_per_tenant: 2 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - title: Create and List Volume workloads: @@ -123,8 +123,8 @@ users_per_tenant: 1 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - scenario: CinderVolumes.create_and_list_volume: @@ -142,8 +142,8 @@ users_per_tenant: 1 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - scenario: CinderVolumes.create_and_list_volume: @@ -161,8 +161,8 @@ users_per_tenant: 1 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - title: List volumes scenario: @@ -181,8 +181,8 @@ volumes_per_tenant: 2 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - title: Create volume workloads: @@ -200,8 +200,8 @@ users_per_tenant: 2 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - scenario: CinderVolumes.create_volume: @@ -218,8 +218,8 @@ users_per_tenant: 2 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - scenario: CinderVolumes.create_volume: @@ -236,8 +236,8 @@ users_per_tenant: 2 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - title: Create and Extend volume workloads: @@ -256,8 +256,8 @@ users_per_tenant: 1 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - scenario: CinderVolumes.create_and_extend_volume: @@ -277,8 +277,8 @@ users_per_tenant: 1 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - title: Create and attach volume scenario: @@ -298,8 +298,8 @@ users_per_tenant: 2 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - title: Create volume and snapshot attach and detach volume and delete them workloads: @@ -326,8 +326,8 @@ - "test" api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - scenario: CinderVolumes.create_snapshot_and_attach_volume: @@ -351,8 +351,8 @@ - "test" api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - title: Create volume from volume and then delete it workloads: @@ -372,8 +372,8 @@ size: 1 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - scenario: CinderVolumes.create_from_volume_and_delete_volume: @@ -392,8 +392,8 @@ size: 1 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - title: Create and delete snapshot scenario: @@ -411,8 +411,8 @@ size: 1 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - title: Create and list snapshots scenario: @@ -431,8 +431,8 @@ size: 1 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 - title: Create and upload a volume to image scenario: @@ -448,5 +448,5 @@ users_per_tenant: 1 api_versions: cinder: - version: 2 - service_name: cinderv2 + version: 3 + service_name: cinderv3 diff --git a/releasenotes/notes/remove-api-v2-dadd877ee5457f79.yaml b/releasenotes/notes/remove-api-v2-dadd877ee5457f79.yaml new file mode 100644 index 00000000000..581d3ee454a --- /dev/null +++ b/releasenotes/notes/remove-api-v2-dadd877ee5457f79.yaml @@ -0,0 +1,14 @@ +--- +upgrade: + - | + The Block Storage API v2, which was deprecated in the Pike release, + has been removed. If upgrading from a previous OpenStack release, it + is recommended that you edit your ``/etc/cinder/api-paste.ini`` file + to remove all references to v2. Additionally, the deprecated + configuration option ``enable_v2_api`` has been removed. If present + in a configuration file, it will be silently ignored. +deprecations: + - | + The configuration option ``enable_v3_api`` is deprecated in this + release due to the fact that v3 is the only version of the Block + Storage API available. It will be removed in the next release.