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
This commit is contained in:
parent
d5f0e51879
commit
e05b261af7
@ -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:
|
||||
|
@ -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"
|
||||
}
|
||||
]
|
||||
|
@ -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"
|
||||
}
|
||||
]
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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'
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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']})
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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')
|
||||
|
||||
|
@ -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')
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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",
|
||||
|
@ -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'
|
||||
|
@ -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 |