Use constants for microversion values
We very often end up with merge conflicts for any patches that increment microversions due to conflicting numbers. We can't really solve that, but we can avoid the need to update version numbers throughout the code by defining a constant value in one place and using that variable instead. Change-Id: Ib3a80fee6caaabb49af097aa197f550c65d94985
This commit is contained in:
parent
b3833594da
commit
e918482674
@ -24,6 +24,7 @@ from oslo_log import log as logging
|
||||
from six.moves import urllib
|
||||
import webob
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.common import constants
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
@ -66,8 +67,6 @@ CONF.register_opts(api_common_opts)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
_FILTERS_COLLECTION = None
|
||||
FILTERING_VERSION = '3.31'
|
||||
LIKE_FILTER_VERSION = '3.34'
|
||||
|
||||
ATTRIBUTE_CONVERTERS = {'name~': 'display_name~',
|
||||
'description~': 'display_description~'}
|
||||
@ -492,9 +491,9 @@ def process_general_filtering(resource):
|
||||
req_version = kwargs.get('req_version')
|
||||
filters = kwargs.get('filters')
|
||||
context = kwargs.get('context')
|
||||
if req_version.matches(FILTERING_VERSION):
|
||||
if req_version.matches(mv.RESOURCE_FILTER):
|
||||
support_like = False
|
||||
if req_version.matches(LIKE_FILTER_VERSION):
|
||||
if req_version.matches(mv.LIKE_FILTER):
|
||||
support_like = True
|
||||
reject_invalid_filters(context, filters,
|
||||
resource, support_like)
|
||||
|
@ -20,6 +20,7 @@ from webob import exc
|
||||
|
||||
from cinder.api import common
|
||||
from cinder.api import extensions
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder import backup
|
||||
from cinder import db
|
||||
@ -245,7 +246,8 @@ class VolumeAdminController(AdminController):
|
||||
volume = self._get(context, id)
|
||||
params = body['os-migrate_volume']
|
||||
|
||||
cluster_name, host = common.get_cluster_host(req, params, '3.16')
|
||||
cluster_name, host = common.get_cluster_host(req, params,
|
||||
mv.VOLUME_MIGRATE_CLUSTER)
|
||||
force_host_copy = utils.get_bool_param('force_host_copy', params)
|
||||
lock_volume = utils.get_bool_param('lock_volume', params)
|
||||
self.volume_api.migrate_volume(context, volume, host, cluster_name,
|
||||
|
@ -23,6 +23,7 @@ from webob import exc
|
||||
|
||||
from cinder.api import common
|
||||
from cinder.api import extensions
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.api.views import backups as backup_views
|
||||
from cinder import backup as backupAPI
|
||||
@ -151,8 +152,8 @@ class BackupsController(wsgi.Controller):
|
||||
incremental = backup.get('incremental', False)
|
||||
force = backup.get('force', False)
|
||||
snapshot_id = backup.get('snapshot_id', None)
|
||||
metadata = backup.get(
|
||||
'metadata', None) if req_version.matches("3.43") else None
|
||||
metadata = backup.get('metadata', None) if req_version.matches(
|
||||
mv.BACKUP_METADATA) else None
|
||||
LOG.info("Creating backup of volume %(volume_id)s in container"
|
||||
" %(container)s",
|
||||
{'volume_id': volume_id, 'container': container},
|
||||
|
@ -15,6 +15,7 @@
|
||||
import oslo_messaging as messaging
|
||||
|
||||
from cinder.api import common
|
||||
from cinder.api import microversions as mv
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
|
||||
@ -23,7 +24,8 @@ def get_manageable_resources(req, is_detail, function_get_manageable,
|
||||
view_builder):
|
||||
context = req.environ['cinder.context']
|
||||
params = req.params.copy()
|
||||
cluster_name, host = common.get_cluster_host(req, params, '3.17')
|
||||
cluster_name, host = common.get_cluster_host(
|
||||
req, params, mv.MANAGE_EXISTING_CLUSTER)
|
||||
marker, limit, offset = common.get_pagination_params(params)
|
||||
sort_keys, sort_dirs = common.get_sort_params(params,
|
||||
default_key='reference')
|
||||
|
@ -16,14 +16,12 @@
|
||||
|
||||
from cinder.api import common
|
||||
from cinder.api import extensions
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.api.views import scheduler_stats as scheduler_stats_view
|
||||
from cinder.scheduler import rpcapi
|
||||
from cinder import utils
|
||||
|
||||
GET_POOL_NAME_FILTER_MICRO_VERSION = '3.28'
|
||||
GET_POOL_VOLUME_TYPE_FILTER_MICRO_VERSION = '3.35'
|
||||
|
||||
|
||||
def authorize(context, action_name):
|
||||
action = 'scheduler_stats:%s' % action_name
|
||||
@ -42,7 +40,7 @@ class SchedulerStatsController(wsgi.Controller):
|
||||
@common.process_general_filtering('pool')
|
||||
def _process_pool_filtering(self, context=None, filters=None,
|
||||
req_version=None):
|
||||
if not req_version.matches(GET_POOL_NAME_FILTER_MICRO_VERSION):
|
||||
if not req_version.matches(mv.POOL_FILTER):
|
||||
filters.clear()
|
||||
|
||||
def get_pools(self, req):
|
||||
@ -60,7 +58,7 @@ class SchedulerStatsController(wsgi.Controller):
|
||||
filters=filters,
|
||||
req_version=req_version)
|
||||
|
||||
if not req_version.matches(GET_POOL_VOLUME_TYPE_FILTER_MICRO_VERSION):
|
||||
if not req_version.matches(mv.POOL_TYPE_FILTER):
|
||||
filters.pop('volume_type', None)
|
||||
|
||||
pools = self.scheduler_api.get_pools(context, filters=filters)
|
||||
|
@ -22,6 +22,7 @@ import webob.exc
|
||||
|
||||
from cinder.api import common
|
||||
from cinder.api import extensions
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.backup import rpcapi as backup_rpcapi
|
||||
from cinder.common import constants
|
||||
@ -94,8 +95,8 @@ class ServiceController(wsgi.Controller):
|
||||
'status': active, 'state': art,
|
||||
'updated_at': updated_at}
|
||||
|
||||
# On V3.7 we added cluster support
|
||||
if req.api_version_request.matches('3.7'):
|
||||
# On CLUSTER_SUPPORT we added cluster support
|
||||
if req.api_version_request.matches(mv.CLUSTER_SUPPORT):
|
||||
ret_fields['cluster'] = svc.cluster_name
|
||||
|
||||
if detailed:
|
||||
@ -125,20 +126,23 @@ class ServiceController(wsgi.Controller):
|
||||
raise exception.InvalidInput(ex.msg)
|
||||
|
||||
def _freeze(self, context, req, body):
|
||||
cluster_name, host = common.get_cluster_host(req, body, '3.26')
|
||||
cluster_name, host = common.get_cluster_host(
|
||||
req, body, mv.REPLICATION_CLUSTER)
|
||||
return self._volume_api_proxy(self.volume_api.freeze_host, context,
|
||||
host, cluster_name)
|
||||
|
||||
def _thaw(self, context, req, body):
|
||||
cluster_name, host = common.get_cluster_host(req, body, '3.26')
|
||||
cluster_name, host = common.get_cluster_host(
|
||||
req, body, mv.REPLICATION_CLUSTER)
|
||||
return self._volume_api_proxy(self.volume_api.thaw_host, context,
|
||||
host, cluster_name)
|
||||
|
||||
def _failover(self, context, req, body, clustered):
|
||||
# We set version to None to always get the cluster name from the body,
|
||||
# to False when we don't want to get it, and '3.26' when we only want
|
||||
# it if the requested version is 3.26 or higher.
|
||||
version = '3.26' if clustered else False
|
||||
# to False when we don't want to get it, and REPLICATION_CLUSTER when
|
||||
# we only want it if the requested version is REPLICATION_CLUSTER or
|
||||
# higher.
|
||||
version = mv.REPLICATION_CLUSTER if clustered else False
|
||||
cluster_name, host = common.get_cluster_host(req, body, version)
|
||||
self._volume_api_proxy(self.volume_api.failover, context, host,
|
||||
cluster_name, body.get('backend_id'))
|
||||
@ -221,7 +225,7 @@ class ServiceController(wsgi.Controller):
|
||||
context = req.environ['cinder.context']
|
||||
authorize(context, action='update')
|
||||
|
||||
support_dynamic_log = req.api_version_request.matches('3.32')
|
||||
support_dynamic_log = req.api_version_request.matches(mv.LOG_LEVEL)
|
||||
|
||||
ext_loaded = self.ext_mgr.is_loaded('os-extended-services')
|
||||
ret_val = {}
|
||||
@ -240,7 +244,8 @@ class ServiceController(wsgi.Controller):
|
||||
return self._thaw(context, req, body)
|
||||
elif id == "failover_host":
|
||||
return self._failover(context, req, body, False)
|
||||
elif req.api_version_request.matches('3.26') and id == 'failover':
|
||||
elif (req.api_version_request.matches(mv.REPLICATION_CLUSTER) and
|
||||
id == 'failover'):
|
||||
return self._failover(context, req, body, True)
|
||||
elif support_dynamic_log and id == 'set-log':
|
||||
return self._set_log(context, body)
|
||||
|
@ -13,6 +13,7 @@
|
||||
# under the License.
|
||||
|
||||
from cinder.api import extensions
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder import quota
|
||||
|
||||
@ -32,7 +33,8 @@ class UsedLimitsController(wsgi.Controller):
|
||||
|
||||
# TODO(wangxiyuan): Support "tenant_id" here to keep the backwards
|
||||
# compatibility. Remove it once we drop all support for "tenant".
|
||||
if req_version.matches(None, "3.38") or not context.is_admin:
|
||||
if (req_version.matches(None, mv.GROUP_REPLICATION) or
|
||||
not context.is_admin):
|
||||
params.pop('project_id', None)
|
||||
params.pop('tenant_id', None)
|
||||
project_id = params.get(
|
||||
|
@ -22,7 +22,7 @@ from six.moves import http_client
|
||||
import webob
|
||||
|
||||
from cinder.api import extensions
|
||||
from cinder.api.openstack import api_version_request
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
@ -271,7 +271,8 @@ class VolumeActionsController(wsgi.Controller):
|
||||
|
||||
image_metadata['cinder_encryption_key_id'] = encryption_key_id
|
||||
|
||||
if req_version >= api_version_request.APIVersionRequest('3.1'):
|
||||
if req_version >= mv.get_api_version(
|
||||
mv.UPLOAD_IMAGE_PARAMS):
|
||||
|
||||
image_metadata['visibility'] = params.get('visibility', 'private')
|
||||
image_metadata['protected'] = params.get('protected', 'False')
|
||||
@ -321,7 +322,8 @@ class VolumeActionsController(wsgi.Controller):
|
||||
raise webob.exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
try:
|
||||
if req_version.matches("3.42") and volume.status in ['in-use']:
|
||||
if (req_version.matches(mv.VOLUME_EXTEND_INUSE) and
|
||||
volume.status in ['in-use']):
|
||||
self.volume_api.extend_attached_volume(context, volume, size)
|
||||
else:
|
||||
self.volume_api.extend(context, volume, size)
|
||||
|
@ -18,6 +18,7 @@ from six.moves import http_client
|
||||
from cinder.api import common
|
||||
from cinder.api.contrib import resource_common_manage
|
||||
from cinder.api import extensions
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.api.v2.views import volumes as volume_views
|
||||
from cinder.api.views import manageable_volumes as list_manageable_view
|
||||
@ -110,7 +111,8 @@ class VolumeManageController(wsgi.Controller):
|
||||
if 'ref' not in volume:
|
||||
raise exception.MissingRequired(element='ref')
|
||||
|
||||
cluster_name, host = common.get_cluster_host(req, volume, '3.16')
|
||||
cluster_name, host = common.get_cluster_host(
|
||||
req, volume, mv.VOLUME_MIGRATE_CLUSTER)
|
||||
|
||||
LOG.debug('Manage volume request body: %s', body)
|
||||
|
||||
|
172
cinder/api/microversions.py
Normal file
172
cinder/api/microversions.py
Normal file
@ -0,0 +1,172 @@
|
||||
# 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.
|
||||
|
||||
"""API Microversion definitions.
|
||||
|
||||
All new microversions should have a constant added here to be used throughout
|
||||
the code instead of the specific version number. Until patches land, it's
|
||||
common to end up with merge conflicts with other microversion changes. Merge
|
||||
conflicts will be easier to handle via the microversion constants defined here
|
||||
as the version number will only need to be changed in a single location.
|
||||
|
||||
Actual version numbers should be used:
|
||||
|
||||
* In this file
|
||||
* In cinder/api/openstack/rest_api_version_history.rst
|
||||
* In cinder/api/openstack/api_version_request.py
|
||||
* In release notes describing the new functionality
|
||||
* In updates to api-ref
|
||||
|
||||
Nearly all microversion changes should include changes to all of those
|
||||
locations. Make sure to add relevant documentation, and make sure that
|
||||
documentation includes the final version number used.
|
||||
"""
|
||||
|
||||
from cinder.api.openstack import api_version_request as api_version
|
||||
from cinder import exception
|
||||
|
||||
|
||||
# Add new constants here for each new microversion.
|
||||
|
||||
BASE_VERSION = '3.0'
|
||||
|
||||
UPLOAD_IMAGE_PARAMS = '3.1'
|
||||
|
||||
VOLUME_LIST_BOOTABLE = '3.2'
|
||||
|
||||
MESSAGES = '3.3'
|
||||
|
||||
VOLUME_LIST_GLANCE_METADATA = '3.4'
|
||||
|
||||
MESSAGES_PAGINATION = '3.5'
|
||||
|
||||
CG_UPDATE_BLANK_PROPERTIES = '3.6'
|
||||
|
||||
CLUSTER_SUPPORT = '3.7'
|
||||
|
||||
MANAGE_EXISTING_LIST = '3.8'
|
||||
|
||||
BACKUP_UPDATE = '3.9'
|
||||
|
||||
VOLUME_LIST_GROUP = '3.10'
|
||||
|
||||
GROUP_TYPE = '3.11'
|
||||
|
||||
VOLUME_SUMMARY = '3.12'
|
||||
|
||||
GROUP_VOLUME = '3.13'
|
||||
|
||||
GROUP_SNAPSHOTS = '3.14'
|
||||
|
||||
ETAGS = '3.15'
|
||||
|
||||
VOLUME_MIGRATE_CLUSTER = '3.16'
|
||||
|
||||
MANAGE_EXISTING_CLUSTER = '3.17'
|
||||
|
||||
BACKUP_PROJECT = '3.18'
|
||||
|
||||
GROUP_SNAPSHOT_RESET_STATUS = '3.19'
|
||||
|
||||
GROUP_VOLUME_RESET_STATUS = '3.20'
|
||||
|
||||
VOLUME_DETAIL_PROVIDER_ID = '3.21'
|
||||
|
||||
SNAPSHOT_LIST_METADATA_FILTER = '3.22'
|
||||
|
||||
VOLUME_DELETE_FORCE = '3.23'
|
||||
|
||||
WORKERS_CLEANUP = '3.24'
|
||||
|
||||
GROUP_VOLUME_LIST = '3.25'
|
||||
|
||||
REPLICATION_CLUSTER = '3.26'
|
||||
|
||||
NEW_ATTACH = '3.27'
|
||||
|
||||
POOL_FILTER = '3.28'
|
||||
|
||||
GROUP_SNAPSHOT_PAGINATION = '3.29'
|
||||
|
||||
SNAPSHOT_SORT = '3.30'
|
||||
|
||||
RESOURCE_FILTER = '3.31'
|
||||
|
||||
LOG_LEVEL = '3.32'
|
||||
|
||||
RESOURCE_FILTER_CONFIG = '3.33'
|
||||
|
||||
LIKE_FILTER = '3.34'
|
||||
|
||||
POOL_TYPE_FILTER = '3.35'
|
||||
|
||||
VOLUME_SUMMARY_METADATA = '3.36'
|
||||
|
||||
BACKUP_SORT_NAME = '3.37'
|
||||
|
||||
GROUP_REPLICATION = '3.38'
|
||||
|
||||
LIMITS_ADMIN_FILTER = '3.39'
|
||||
|
||||
VOLUME_REVERT = '3.40'
|
||||
|
||||
SNAPSHOT_LIST_USER_ID = '3.41'
|
||||
|
||||
VOLUME_EXTEND_INUSE = '3.42'
|
||||
|
||||
BACKUP_METADATA = '3.43'
|
||||
|
||||
NEW_ATTACH_COMPLETION = '3.44'
|
||||
|
||||
|
||||
def get_mv_header(version):
|
||||
"""Gets a formatted HTTP microversion header.
|
||||
|
||||
:param version: The microversion needed.
|
||||
:return: A tuple containing the microversion header with the
|
||||
requested version value.
|
||||
"""
|
||||
return {'OpenStack-API-Version':
|
||||
'volume %s' % version}
|
||||
|
||||
|
||||
def get_api_version(version):
|
||||
"""Gets a ``APIVersionRequest`` instance.
|
||||
|
||||
:param version: The microversion needed.
|
||||
:return: The ``APIVersionRequest`` instance.
|
||||
"""
|
||||
return api_version.APIVersionRequest(version)
|
||||
|
||||
|
||||
def get_prior_version(version):
|
||||
"""Gets the microversion before the given version.
|
||||
|
||||
Mostly useful for testing boundaries. This gets the microversion defined
|
||||
just prior to the given version.
|
||||
|
||||
:param version: The version of interest.
|
||||
:return: The version just prior to the given version.
|
||||
"""
|
||||
parts = version.split('.')
|
||||
|
||||
if len(parts) != 2 or parts[0] != '3':
|
||||
raise exception.InvalidInput(reason='Version %s is not a valid '
|
||||
'microversion format.' % version)
|
||||
|
||||
minor = int(parts[1]) - 1
|
||||
|
||||
if minor < 0:
|
||||
# What's your problem? Are you trying to be difficult?
|
||||
minor = 0
|
||||
|
||||
return '%s.%s' % (parts[0], minor)
|
@ -116,6 +116,7 @@ REST_API_VERSION_HISTORY = """
|
||||
_MIN_API_VERSION = "3.0"
|
||||
_MAX_API_VERSION = "3.44"
|
||||
_LEGACY_API_VERSION2 = "2.0"
|
||||
UPDATED = "2017-09-19T20:18:14Z"
|
||||
|
||||
|
||||
# NOTE(cyeoh): min and max versions declared as functions so we can
|
||||
|
@ -95,7 +95,7 @@ class VolumeController(wsgi.Controller):
|
||||
filters = params
|
||||
|
||||
# NOTE(wanghao): Always removing glance_metadata since we support it
|
||||
# only in API version >= 3.4.
|
||||
# only in API version >= VOLUME_LIST_GLANCE_METADATA.
|
||||
filters.pop('glance_metadata', None)
|
||||
utils.remove_invalid_filter_options(context,
|
||||
filters,
|
||||
|
@ -16,6 +16,7 @@ from oslo_log import log as logging
|
||||
import webob
|
||||
|
||||
from cinder.api import common
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.api.v3.views import attachments as attachment_views
|
||||
from cinder import exception
|
||||
@ -26,8 +27,6 @@ from cinder.volume import api as volume_api
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
API_VERSION = '3.27'
|
||||
ATTACHMENT_COMPLETION_VERSION = '3.44'
|
||||
|
||||
|
||||
class AttachmentsController(wsgi.Controller):
|
||||
@ -43,20 +42,20 @@ class AttachmentsController(wsgi.Controller):
|
||||
self.ext_mgr = ext_mgr
|
||||
super(AttachmentsController, self).__init__()
|
||||
|
||||
@wsgi.Controller.api_version(API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.NEW_ATTACH)
|
||||
def show(self, req, id):
|
||||
"""Return data about the given attachment."""
|
||||
context = req.environ['cinder.context']
|
||||
attachment = objects.VolumeAttachment.get_by_id(context, id)
|
||||
return attachment_views.ViewBuilder.detail(attachment)
|
||||
|
||||
@wsgi.Controller.api_version(API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.NEW_ATTACH)
|
||||
def index(self, req):
|
||||
"""Return a summary list of attachments."""
|
||||
attachments = self._items(req)
|
||||
return attachment_views.ViewBuilder.list(attachments)
|
||||
|
||||
@wsgi.Controller.api_version(API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.NEW_ATTACH)
|
||||
def detail(self, req):
|
||||
"""Return a detailed list of attachments."""
|
||||
attachments = self._items(req)
|
||||
@ -94,7 +93,7 @@ class AttachmentsController(wsgi.Controller):
|
||||
marker=marker, limit=limit, offset=offset, sort_keys=sort_keys,
|
||||
sort_direction=sort_dirs)
|
||||
|
||||
@wsgi.Controller.api_version(API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.NEW_ATTACH)
|
||||
@wsgi.response(202)
|
||||
def create(self, req, body):
|
||||
"""Create an attachment.
|
||||
@ -192,7 +191,7 @@ class AttachmentsController(wsgi.Controller):
|
||||
raise webob.exc.HTTPInternalServerError(explanation=err_msg)
|
||||
return attachment_views.ViewBuilder.detail(attachment_ref)
|
||||
|
||||
@wsgi.Controller.api_version(API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.NEW_ATTACH)
|
||||
def update(self, req, id, body):
|
||||
"""Update an attachment record.
|
||||
|
||||
@ -252,7 +251,7 @@ class AttachmentsController(wsgi.Controller):
|
||||
# or a dict?
|
||||
return attachment_views.ViewBuilder.detail(attachment_ref)
|
||||
|
||||
@wsgi.Controller.api_version(API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.NEW_ATTACH)
|
||||
def delete(self, req, id):
|
||||
"""Delete an attachment.
|
||||
|
||||
@ -268,7 +267,7 @@ class AttachmentsController(wsgi.Controller):
|
||||
return attachment_views.ViewBuilder.list(attachments)
|
||||
|
||||
@wsgi.response(202)
|
||||
@wsgi.Controller.api_version(ATTACHMENT_COMPLETION_VERSION)
|
||||
@wsgi.Controller.api_version(mv.NEW_ATTACH_COMPLETION)
|
||||
@wsgi.action('os-complete')
|
||||
def complete(self, req, id, body):
|
||||
"""Mark a volume attachment process as completed (in-use)."""
|
||||
|
@ -19,22 +19,20 @@ from oslo_log import log as logging
|
||||
from webob import exc
|
||||
|
||||
from cinder.api.contrib import backups as backups_v2
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.backup import api as backup_api
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
|
||||
|
||||
BACKUP_UPDATE_MICRO_VERSION = '3.9'
|
||||
BACKUP_TENANT_MICRO_VERSION = '3.18'
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BackupsController(backups_v2.BackupsController):
|
||||
"""The backups API controller for the OpenStack API V3."""
|
||||
|
||||
@wsgi.Controller.api_version(BACKUP_UPDATE_MICRO_VERSION)
|
||||
@wsgi.Controller.api_version(mv.BACKUP_UPDATE)
|
||||
def update(self, req, id, body):
|
||||
"""Update a backup."""
|
||||
context = req.environ['cinder.context']
|
||||
@ -50,7 +48,8 @@ class BackupsController(backups_v2.BackupsController):
|
||||
if 'description' in backup_update:
|
||||
update_dict['display_description'] = (
|
||||
backup_update.pop('description'))
|
||||
if req_version.matches('3.43') and 'metadata' in backup_update:
|
||||
if (req_version.matches(
|
||||
mv.BACKUP_METADATA) and 'metadata' in backup_update):
|
||||
update_dict['metadata'] = backup_update.pop('metadata')
|
||||
# Check no unsupported fields.
|
||||
if backup_update:
|
||||
@ -77,7 +76,7 @@ class BackupsController(backups_v2.BackupsController):
|
||||
req.cache_db_backup(backup)
|
||||
|
||||
resp_backup = self._view_builder.detail(req, backup)
|
||||
if req_version.matches(BACKUP_TENANT_MICRO_VERSION):
|
||||
if req_version.matches(mv.BACKUP_PROJECT):
|
||||
try:
|
||||
backup_api.check_policy(context, 'backup_project_attribute')
|
||||
self._add_backup_project_attribute(req, resp_backup['backup'])
|
||||
@ -90,7 +89,7 @@ class BackupsController(backups_v2.BackupsController):
|
||||
context = req.environ['cinder.context']
|
||||
req_version = req.api_version_request
|
||||
|
||||
if req_version.matches(BACKUP_TENANT_MICRO_VERSION):
|
||||
if req_version.matches(mv.BACKUP_PROJECT):
|
||||
try:
|
||||
backup_api.check_policy(context, 'backup_project_attribute')
|
||||
for bak in resp_backup['backups']:
|
||||
@ -100,7 +99,7 @@ class BackupsController(backups_v2.BackupsController):
|
||||
return resp_backup
|
||||
|
||||
def _convert_sort_name(self, req_version, sort_keys):
|
||||
if req_version.matches("3.37") and 'name' in sort_keys:
|
||||
if req_version.matches(mv.BACKUP_SORT_NAME) and 'name' in sort_keys:
|
||||
sort_keys[sort_keys.index('name')] = 'display_name'
|
||||
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.api.v3.views import clusters as clusters_view
|
||||
from cinder import exception
|
||||
@ -21,10 +22,6 @@ from cinder import objects
|
||||
from cinder import utils
|
||||
|
||||
|
||||
CLUSTER_MICRO_VERSION = '3.7'
|
||||
REPLICATION_DATA_MICRO_VERSION = '3.26'
|
||||
|
||||
|
||||
class ClusterController(wsgi.Controller):
|
||||
allowed_list_keys = {'name', 'binary', 'is_up', 'disabled', 'num_hosts',
|
||||
'num_down_hosts', 'binary', 'replication_status',
|
||||
@ -33,7 +30,7 @@ class ClusterController(wsgi.Controller):
|
||||
|
||||
policy_checker = wsgi.Controller.get_policy_checker('clusters')
|
||||
|
||||
@wsgi.Controller.api_version(CLUSTER_MICRO_VERSION)
|
||||
@wsgi.Controller.api_version(mv.CLUSTER_SUPPORT)
|
||||
def show(self, req, id, binary='cinder-volume'):
|
||||
"""Return data for a given cluster name with optional binary."""
|
||||
# Let the wsgi middleware convert NotAuthorized exceptions
|
||||
@ -42,10 +39,10 @@ class ClusterController(wsgi.Controller):
|
||||
cluster = objects.Cluster.get_by_id(context, None, binary=binary,
|
||||
name=id, services_summary=True)
|
||||
replication_data = req.api_version_request.matches(
|
||||
REPLICATION_DATA_MICRO_VERSION)
|
||||
mv.REPLICATION_CLUSTER)
|
||||
return clusters_view.ViewBuilder.detail(cluster, replication_data)
|
||||
|
||||
@wsgi.Controller.api_version(CLUSTER_MICRO_VERSION)
|
||||
@wsgi.Controller.api_version(mv.CLUSTER_SUPPORT)
|
||||
def index(self, req):
|
||||
"""Return a non detailed list of all existing clusters.
|
||||
|
||||
@ -53,7 +50,7 @@ class ClusterController(wsgi.Controller):
|
||||
"""
|
||||
return self._get_clusters(req, detail=False)
|
||||
|
||||
@wsgi.Controller.api_version(CLUSTER_MICRO_VERSION)
|
||||
@wsgi.Controller.api_version(mv.CLUSTER_SUPPORT)
|
||||
def detail(self, req):
|
||||
"""Return a detailed list of all existing clusters.
|
||||
|
||||
@ -65,7 +62,7 @@ class ClusterController(wsgi.Controller):
|
||||
# Let the wsgi middleware convert NotAuthorized exceptions
|
||||
context = self.policy_checker(req, 'get_all')
|
||||
replication_data = req.api_version_request.matches(
|
||||
REPLICATION_DATA_MICRO_VERSION)
|
||||
mv.REPLICATION_CLUSTER)
|
||||
filters = dict(req.GET)
|
||||
allowed = self.allowed_list_keys
|
||||
if not replication_data:
|
||||
@ -89,7 +86,7 @@ class ClusterController(wsgi.Controller):
|
||||
return clusters_view.ViewBuilder.list(clusters, detail,
|
||||
replication_data)
|
||||
|
||||
@wsgi.Controller.api_version(CLUSTER_MICRO_VERSION)
|
||||
@wsgi.Controller.api_version(mv.CLUSTER_SUPPORT)
|
||||
def update(self, req, id, body):
|
||||
"""Enable/Disable scheduling for a cluster."""
|
||||
# NOTE(geguileo): This method tries to be consistent with services
|
||||
@ -123,7 +120,7 @@ class ClusterController(wsgi.Controller):
|
||||
|
||||
# We return summary data plus the disabled reason
|
||||
replication_data = req.api_version_request.matches(
|
||||
REPLICATION_DATA_MICRO_VERSION)
|
||||
mv.REPLICATION_CLUSTER)
|
||||
ret_val = clusters_view.ViewBuilder.summary(cluster, replication_data)
|
||||
ret_val['cluster']['disabled_reason'] = disabled_reason
|
||||
|
||||
|
@ -19,6 +19,7 @@ import webob
|
||||
from webob import exc
|
||||
|
||||
from cinder.api.contrib import consistencygroups as cg_v2
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.i18n import _
|
||||
|
||||
@ -30,7 +31,8 @@ class ConsistencyGroupsController(cg_v2.ConsistencyGroupsController):
|
||||
|
||||
def _check_update_parameters_v3(self, req, name, description, add_volumes,
|
||||
remove_volumes):
|
||||
allow_empty = req.api_version_request.matches('3.6', None)
|
||||
allow_empty = req.api_version_request.matches(
|
||||
mv.CG_UPDATE_BLANK_PROPERTIES, None)
|
||||
if allow_empty:
|
||||
if (name is None and description is None
|
||||
and not add_volumes and not remove_volumes):
|
||||
|
@ -22,6 +22,7 @@ import webob
|
||||
from webob import exc
|
||||
|
||||
from cinder.api import common
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.api.v3.views import group_snapshots as group_snapshot_views
|
||||
from cinder import exception
|
||||
@ -32,8 +33,6 @@ from cinder.volume import group_types
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
GROUP_SNAPSHOT_API_VERSION = '3.14'
|
||||
|
||||
|
||||
class GroupSnapshotsController(wsgi.Controller):
|
||||
"""The group_snapshots API controller for the OpenStack API."""
|
||||
@ -52,7 +51,7 @@ class GroupSnapshotsController(wsgi.Controller):
|
||||
% {'group_type': group_type_id})
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
@wsgi.Controller.api_version(GROUP_SNAPSHOT_API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.GROUP_SNAPSHOTS)
|
||||
def show(self, req, id):
|
||||
"""Return data about the given group_snapshot."""
|
||||
LOG.debug('show called for member %s', id)
|
||||
@ -66,7 +65,7 @@ class GroupSnapshotsController(wsgi.Controller):
|
||||
|
||||
return self._view_builder.detail(req, group_snapshot)
|
||||
|
||||
@wsgi.Controller.api_version(GROUP_SNAPSHOT_API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.GROUP_SNAPSHOTS)
|
||||
def delete(self, req, id):
|
||||
"""Delete a group_snapshot."""
|
||||
LOG.debug('delete called for member %s', id)
|
||||
@ -93,12 +92,12 @@ class GroupSnapshotsController(wsgi.Controller):
|
||||
|
||||
return webob.Response(status_int=http_client.ACCEPTED)
|
||||
|
||||
@wsgi.Controller.api_version(GROUP_SNAPSHOT_API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.GROUP_SNAPSHOTS)
|
||||
def index(self, req):
|
||||
"""Returns a summary list of group_snapshots."""
|
||||
return self._get_group_snapshots(req, is_detail=False)
|
||||
|
||||
@wsgi.Controller.api_version(GROUP_SNAPSHOT_API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.GROUP_SNAPSHOTS)
|
||||
def detail(self, req):
|
||||
"""Returns a detailed list of group_snapshots."""
|
||||
return self._get_group_snapshots(req, is_detail=True)
|
||||
@ -109,14 +108,14 @@ class GroupSnapshotsController(wsgi.Controller):
|
||||
context = req.environ['cinder.context']
|
||||
req_version = req.api_version_request
|
||||
filters = marker = limit = offset = sort_keys = sort_dirs = None
|
||||
if req_version.matches("3.29"):
|
||||
if req_version.matches(mv.GROUP_SNAPSHOT_PAGINATION):
|
||||
filters = req.params.copy()
|
||||
marker, limit, offset = common.get_pagination_params(filters)
|
||||
sort_keys, sort_dirs = common.get_sort_params(filters)
|
||||
|
||||
if req_version.matches(common.FILTERING_VERSION):
|
||||
if req_version.matches(mv.RESOURCE_FILTER):
|
||||
support_like = (True if req_version.matches(
|
||||
common.LIKE_FILTER_VERSION) else False)
|
||||
mv.LIKE_FILTER) else False)
|
||||
common.reject_invalid_filters(context, filters, 'group_snapshot',
|
||||
support_like)
|
||||
|
||||
@ -145,7 +144,7 @@ class GroupSnapshotsController(wsgi.Controller):
|
||||
group_snapshots['group_snapshots'] = new_group_snapshots
|
||||
return group_snapshots
|
||||
|
||||
@wsgi.Controller.api_version(GROUP_SNAPSHOT_API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.GROUP_SNAPSHOTS)
|
||||
@wsgi.response(http_client.ACCEPTED)
|
||||
def create(self, req, body):
|
||||
"""Create a new group_snapshot."""
|
||||
@ -183,7 +182,7 @@ class GroupSnapshotsController(wsgi.Controller):
|
||||
|
||||
return retval
|
||||
|
||||
@wsgi.Controller.api_version('3.19')
|
||||
@wsgi.Controller.api_version(mv.GROUP_SNAPSHOT_RESET_STATUS)
|
||||
@wsgi.action("reset_status")
|
||||
def reset_status(self, req, id, body):
|
||||
return self._reset_status(req, id, body)
|
||||
|
@ -18,6 +18,7 @@ from six.moves import http_client
|
||||
import webob
|
||||
|
||||
from cinder.api import common
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder import db
|
||||
from cinder import exception
|
||||
@ -51,7 +52,7 @@ class GroupTypeSpecsController(wsgi.Controller):
|
||||
except exception.GroupTypeNotFound as ex:
|
||||
raise webob.exc.HTTPNotFound(explanation=ex.msg)
|
||||
|
||||
@wsgi.Controller.api_version('3.11')
|
||||
@wsgi.Controller.api_version(mv.GROUP_TYPE)
|
||||
def index(self, req, group_type_id):
|
||||
"""Returns the list of group specs for a given group type."""
|
||||
context = req.environ['cinder.context']
|
||||
@ -59,7 +60,7 @@ class GroupTypeSpecsController(wsgi.Controller):
|
||||
self._check_type(context, group_type_id)
|
||||
return self._get_group_specs(context, group_type_id)
|
||||
|
||||
@wsgi.Controller.api_version('3.11')
|
||||
@wsgi.Controller.api_version(mv.GROUP_TYPE)
|
||||
@wsgi.response(http_client.ACCEPTED)
|
||||
def create(self, req, group_type_id, body=None):
|
||||
context = req.environ['cinder.context']
|
||||
@ -80,7 +81,7 @@ class GroupTypeSpecsController(wsgi.Controller):
|
||||
notifier_info)
|
||||
return body
|
||||
|
||||
@wsgi.Controller.api_version('3.11')
|
||||
@wsgi.Controller.api_version(mv.GROUP_TYPE)
|
||||
def update(self, req, group_type_id, id, body=None):
|
||||
context = req.environ['cinder.context']
|
||||
self._check_policy(context)
|
||||
@ -108,7 +109,7 @@ class GroupTypeSpecsController(wsgi.Controller):
|
||||
notifier_info)
|
||||
return body
|
||||
|
||||
@wsgi.Controller.api_version('3.11')
|
||||
@wsgi.Controller.api_version(mv.GROUP_TYPE)
|
||||
def show(self, req, group_type_id, id):
|
||||
"""Return a single extra spec item."""
|
||||
context = req.environ['cinder.context']
|
||||
@ -123,7 +124,7 @@ class GroupTypeSpecsController(wsgi.Controller):
|
||||
"%(id)s.") % ({'type_id': group_type_id, 'id': id})
|
||||
raise webob.exc.HTTPNotFound(explanation=msg)
|
||||
|
||||
@wsgi.Controller.api_version('3.11')
|
||||
@wsgi.Controller.api_version(mv.GROUP_TYPE)
|
||||
def delete(self, req, group_type_id, id):
|
||||
"""Deletes an existing group spec."""
|
||||
context = req.environ['cinder.context']
|
||||
|
@ -21,6 +21,7 @@ import webob
|
||||
from webob import exc
|
||||
|
||||
from cinder.api import common
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.api.v3.views import group_types as views_types
|
||||
from cinder import exception
|
||||
@ -55,7 +56,7 @@ class GroupTypesController(wsgi.Controller):
|
||||
payload = dict(group_types=group_type)
|
||||
rpc.get_notifier('groupType').info(context, method, payload)
|
||||
|
||||
@wsgi.Controller.api_version('3.11')
|
||||
@wsgi.Controller.api_version(mv.GROUP_TYPE)
|
||||
@wsgi.response(http_client.ACCEPTED)
|
||||
def create(self, req, body):
|
||||
"""Creates a new group type."""
|
||||
@ -103,7 +104,7 @@ class GroupTypesController(wsgi.Controller):
|
||||
|
||||
return self._view_builder.show(req, grp_type)
|
||||
|
||||
@wsgi.Controller.api_version('3.11')
|
||||
@wsgi.Controller.api_version(mv.GROUP_TYPE)
|
||||
def update(self, req, id, body):
|
||||
# Update description for a given group type.
|
||||
context = req.environ['cinder.context']
|
||||
@ -163,7 +164,7 @@ class GroupTypesController(wsgi.Controller):
|
||||
|
||||
return self._view_builder.show(req, grp_type)
|
||||
|
||||
@wsgi.Controller.api_version('3.11')
|
||||
@wsgi.Controller.api_version(mv.GROUP_TYPE)
|
||||
def delete(self, req, id):
|
||||
"""Deletes an existing group type."""
|
||||
context = req.environ['cinder.context']
|
||||
@ -186,14 +187,14 @@ class GroupTypesController(wsgi.Controller):
|
||||
|
||||
return webob.Response(status_int=http_client.ACCEPTED)
|
||||
|
||||
@wsgi.Controller.api_version('3.11')
|
||||
@wsgi.Controller.api_version(mv.GROUP_TYPE)
|
||||
def index(self, req):
|
||||
"""Returns the list of group types."""
|
||||
limited_types = self._get_group_types(req)
|
||||
req.cache_resource(limited_types, name='group_types')
|
||||
return self._view_builder.index(req, limited_types)
|
||||
|
||||
@wsgi.Controller.api_version('3.11')
|
||||
@wsgi.Controller.api_version(mv.GROUP_TYPE)
|
||||
def show(self, req, id):
|
||||
"""Return a single group type item."""
|
||||
context = req.environ['cinder.context']
|
||||
|
@ -22,6 +22,7 @@ import webob
|
||||
from webob import exc
|
||||
|
||||
from cinder.api import common
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.api.v3.views import groups as views_groups
|
||||
from cinder import exception
|
||||
@ -32,10 +33,6 @@ from cinder.volume import group_types
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
GROUP_API_VERSION = '3.13'
|
||||
GROUP_CREATE_FROM_SRC_API_VERSION = '3.14'
|
||||
GROUP_REPLICATION_API_VERSION = '3.38'
|
||||
|
||||
|
||||
class GroupsController(wsgi.Controller):
|
||||
"""The groups API controller for the OpenStack API."""
|
||||
@ -53,7 +50,7 @@ class GroupsController(wsgi.Controller):
|
||||
"CG APIs.") % {'group_type': group_type_id}
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
@wsgi.Controller.api_version(GROUP_API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.GROUP_VOLUME)
|
||||
def show(self, req, id):
|
||||
"""Return data about the given group."""
|
||||
LOG.debug('show called for member %s', id)
|
||||
@ -68,7 +65,7 @@ class GroupsController(wsgi.Controller):
|
||||
|
||||
return self._view_builder.detail(req, group)
|
||||
|
||||
@wsgi.Controller.api_version('3.20')
|
||||
@wsgi.Controller.api_version(mv.GROUP_VOLUME_RESET_STATUS)
|
||||
@wsgi.action("reset_status")
|
||||
def reset_status(self, req, id, body):
|
||||
return self._reset_status(req, id, body)
|
||||
@ -109,7 +106,7 @@ class GroupsController(wsgi.Controller):
|
||||
raise exc.HTTPBadRequest(explanation=error.msg)
|
||||
return webob.Response(status_int=http_client.ACCEPTED)
|
||||
|
||||
@wsgi.Controller.api_version(GROUP_API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.GROUP_VOLUME)
|
||||
@wsgi.action("delete")
|
||||
def delete_group(self, req, id, body):
|
||||
return self._delete(req, id, body)
|
||||
@ -150,12 +147,12 @@ class GroupsController(wsgi.Controller):
|
||||
|
||||
return webob.Response(status_int=http_client.ACCEPTED)
|
||||
|
||||
@wsgi.Controller.api_version(GROUP_API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.GROUP_VOLUME)
|
||||
def index(self, req):
|
||||
"""Returns a summary list of groups."""
|
||||
return self._get_groups(req, is_detail=False)
|
||||
|
||||
@wsgi.Controller.api_version(GROUP_API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.GROUP_VOLUME)
|
||||
def detail(self, req):
|
||||
"""Returns a detailed list of groups."""
|
||||
return self._get_groups(req, is_detail=True)
|
||||
@ -169,9 +166,9 @@ class GroupsController(wsgi.Controller):
|
||||
sort_keys, sort_dirs = common.get_sort_params(filters)
|
||||
|
||||
filters.pop('list_volume', None)
|
||||
if api_version.matches(common.FILTERING_VERSION):
|
||||
if api_version.matches(mv.RESOURCE_FILTER):
|
||||
support_like = (True if api_version.matches(
|
||||
common.LIKE_FILTER_VERSION) else False)
|
||||
mv.LIKE_FILTER) else False)
|
||||
common.reject_invalid_filters(context, filters, 'group',
|
||||
support_like)
|
||||
|
||||
@ -197,7 +194,7 @@ class GroupsController(wsgi.Controller):
|
||||
req, new_groups)
|
||||
return groups
|
||||
|
||||
@wsgi.Controller.api_version(GROUP_API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.GROUP_VOLUME)
|
||||
@wsgi.response(http_client.ACCEPTED)
|
||||
def create(self, req, body):
|
||||
"""Create a new group."""
|
||||
@ -243,7 +240,7 @@ class GroupsController(wsgi.Controller):
|
||||
retval = self._view_builder.summary(req, new_group)
|
||||
return retval
|
||||
|
||||
@wsgi.Controller.api_version(GROUP_CREATE_FROM_SRC_API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.GROUP_SNAPSHOTS)
|
||||
@wsgi.action("create-from-src")
|
||||
@wsgi.response(http_client.ACCEPTED)
|
||||
def create_from_src(self, req, body):
|
||||
@ -308,7 +305,7 @@ class GroupsController(wsgi.Controller):
|
||||
retval = self._view_builder.summary(req, new_group)
|
||||
return retval
|
||||
|
||||
@wsgi.Controller.api_version(GROUP_API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.GROUP_VOLUME)
|
||||
def update(self, req, id, body):
|
||||
"""Update the group.
|
||||
|
||||
@ -373,7 +370,7 @@ class GroupsController(wsgi.Controller):
|
||||
|
||||
return webob.Response(status_int=http_client.ACCEPTED)
|
||||
|
||||
@wsgi.Controller.api_version(GROUP_REPLICATION_API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.GROUP_REPLICATION)
|
||||
@wsgi.action("enable_replication")
|
||||
def enable_replication(self, req, id, body):
|
||||
"""Enables replications for a group."""
|
||||
@ -397,7 +394,7 @@ class GroupsController(wsgi.Controller):
|
||||
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.Controller.api_version(GROUP_REPLICATION_API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.GROUP_REPLICATION)
|
||||
@wsgi.action("disable_replication")
|
||||
def disable_replication(self, req, id, body):
|
||||
"""Disables replications for a group."""
|
||||
@ -421,7 +418,7 @@ class GroupsController(wsgi.Controller):
|
||||
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.Controller.api_version(GROUP_REPLICATION_API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.GROUP_REPLICATION)
|
||||
@wsgi.action("failover_replication")
|
||||
def failover_replication(self, req, id, body):
|
||||
"""Fails over replications for a group."""
|
||||
@ -457,7 +454,7 @@ class GroupsController(wsgi.Controller):
|
||||
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@wsgi.Controller.api_version(GROUP_REPLICATION_API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.GROUP_REPLICATION)
|
||||
@wsgi.action("list_replication_targets")
|
||||
def list_replication_targets(self, req, id, body):
|
||||
"""List replication targets for a group."""
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
"""The limits V3 api."""
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.api.v2 import limits as limits_v2
|
||||
from cinder.api.views import limits as limits_views
|
||||
@ -32,7 +33,8 @@ class LimitsController(limits_v2.LimitsController):
|
||||
|
||||
# TODO(wangxiyuan): Support "tenant_id" here to keep the backwards
|
||||
# compatibility. Remove it once we drop all support for "tenant".
|
||||
if req_version.matches(None, "3.38") or not context.is_admin:
|
||||
if req_version.matches(None,
|
||||
mv.GROUP_REPLICATION) or not context.is_admin:
|
||||
params.pop('project_id', None)
|
||||
params.pop('tenant_id', None)
|
||||
project_id = params.get(
|
||||
|
@ -17,6 +17,7 @@ from six.moves import http_client
|
||||
import webob
|
||||
|
||||
from cinder.api import common
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.api.v3.views import messages as messages_view
|
||||
from cinder.message import api as message_api
|
||||
@ -25,9 +26,6 @@ from cinder.message import message_field
|
||||
import cinder.policy
|
||||
|
||||
|
||||
MESSAGES_BASE_MICRO_VERSION = '3.3'
|
||||
|
||||
|
||||
def check_policy(context, action, target_obj=None):
|
||||
target = {
|
||||
'project_id': context.project_id,
|
||||
@ -62,7 +60,7 @@ class MessagesController(wsgi.Controller):
|
||||
message_field.translate_action(message['action_id']),
|
||||
message_field.translate_detail(message['detail_id']))
|
||||
|
||||
@wsgi.Controller.api_version(MESSAGES_BASE_MICRO_VERSION)
|
||||
@wsgi.Controller.api_version(mv.MESSAGES)
|
||||
def show(self, req, id):
|
||||
"""Return the given message."""
|
||||
context = req.environ['cinder.context']
|
||||
@ -75,7 +73,7 @@ class MessagesController(wsgi.Controller):
|
||||
self._build_user_message(message)
|
||||
return self._view_builder.detail(req, message)
|
||||
|
||||
@wsgi.Controller.api_version(MESSAGES_BASE_MICRO_VERSION)
|
||||
@wsgi.Controller.api_version(mv.MESSAGES)
|
||||
def delete(self, req, id):
|
||||
"""Delete a message."""
|
||||
context = req.environ['cinder.context']
|
||||
@ -87,7 +85,7 @@ class MessagesController(wsgi.Controller):
|
||||
|
||||
return webob.Response(status_int=http_client.NO_CONTENT)
|
||||
|
||||
@wsgi.Controller.api_version(MESSAGES_BASE_MICRO_VERSION)
|
||||
@wsgi.Controller.api_version(mv.MESSAGES)
|
||||
def index(self, req):
|
||||
"""Returns a list of messages, transformed through view builder."""
|
||||
context = req.environ['cinder.context']
|
||||
@ -100,14 +98,14 @@ class MessagesController(wsgi.Controller):
|
||||
sort_keys = None
|
||||
sort_dirs = None
|
||||
|
||||
if api_version.matches("3.5"):
|
||||
if api_version.matches(mv.MESSAGES_PAGINATION):
|
||||
filters = req.params.copy()
|
||||
marker, limit, offset = common.get_pagination_params(filters)
|
||||
sort_keys, sort_dirs = common.get_sort_params(filters)
|
||||
|
||||
if api_version.matches(common.FILTERING_VERSION):
|
||||
if api_version.matches(mv.RESOURCE_FILTER):
|
||||
support_like = (True if api_version.matches(
|
||||
common.LIKE_FILTER_VERSION) else False)
|
||||
mv.LIKE_FILTER) else False)
|
||||
common.reject_invalid_filters(context, filters, 'message',
|
||||
support_like)
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
from cinder.api import common
|
||||
from cinder.api import extensions
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder import exception
|
||||
from cinder.i18n import _
|
||||
@ -41,13 +42,14 @@ class ManageResource(object):
|
||||
raise exception.VersionNotFoundForAPIMethod(version=version)
|
||||
|
||||
def _get_resources(self, req, is_detail):
|
||||
self._ensure_min_version(req, '3.8')
|
||||
self._ensure_min_version(req, mv.MANAGE_EXISTING_LIST)
|
||||
|
||||
context = req.environ['cinder.context']
|
||||
self._authorizer(context)
|
||||
|
||||
params = req.params.copy()
|
||||
cluster_name, host = common.get_cluster_host(req, params, '3.17')
|
||||
cluster_name, host = common.get_cluster_host(
|
||||
req, params, mv.MANAGE_EXISTING_CLUSTER)
|
||||
marker, limit, offset = common.get_pagination_params(params)
|
||||
sort_keys, sort_dirs = common.get_sort_params(params,
|
||||
default_key='reference')
|
||||
|
@ -13,13 +13,11 @@
|
||||
"""The resource filters api."""
|
||||
|
||||
from cinder.api import common
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.api.v3.views import resource_filters as filter_views
|
||||
|
||||
|
||||
FILTER_API_VERSION = '3.33'
|
||||
|
||||
|
||||
class ResourceFiltersController(wsgi.Controller):
|
||||
"""The resource filter API controller for the OpenStack API."""
|
||||
|
||||
@ -30,7 +28,7 @@ class ResourceFiltersController(wsgi.Controller):
|
||||
self.ext_mgr = ext_mgr
|
||||
super(ResourceFiltersController, self).__init__()
|
||||
|
||||
@wsgi.Controller.api_version(FILTER_API_VERSION)
|
||||
@wsgi.Controller.api_version(mv.RESOURCE_FILTER_CONFIG)
|
||||
def index(self, req):
|
||||
"""Return a list of resource filters."""
|
||||
resource = req.params.get('resource', None)
|
||||
|
@ -15,6 +15,7 @@
|
||||
from six.moves import http_client
|
||||
|
||||
from cinder.api.contrib import snapshot_manage as snapshot_manage_v2
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.api.v3 import resource_common_manage as common
|
||||
|
||||
@ -27,7 +28,7 @@ class SnapshotManageController(common.ManageResource,
|
||||
|
||||
@wsgi.response(http_client.ACCEPTED)
|
||||
def create(self, req, body):
|
||||
self._ensure_min_version(req, "3.8")
|
||||
self._ensure_min_version(req, mv.MANAGE_EXISTING_LIST)
|
||||
return super(SnapshotManageController, self).create(req, body)
|
||||
|
||||
|
||||
|
@ -20,6 +20,7 @@ import ast
|
||||
from oslo_log import log as logging
|
||||
|
||||
from cinder.api import common
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.api.v2 import snapshots as snapshots_v2
|
||||
from cinder.api.v3.views import snapshots as snapshot_views
|
||||
@ -56,9 +57,10 @@ class SnapshotsController(snapshots_v2.SnapshotsController):
|
||||
req_version=None):
|
||||
"""Formats allowed filters"""
|
||||
|
||||
# if the max version is less than or same as 3.21
|
||||
# if the max version is less than SNAPSHOT_LIST_METADATA_FILTER
|
||||
# metadata based filtering is not supported
|
||||
if req_version.matches(None, "3.21"):
|
||||
if req_version.matches(
|
||||
None, mv.get_prior_version(mv.SNAPSHOT_LIST_METADATA_FILTER)):
|
||||
filters.pop('metadata', None)
|
||||
|
||||
# Filter out invalid options
|
||||
@ -84,7 +86,7 @@ class SnapshotsController(snapshots_v2.SnapshotsController):
|
||||
self._format_snapshot_filter_options(search_opts)
|
||||
|
||||
req_version = req.api_version_request
|
||||
if req_version.matches("3.30", None) and 'name' in sort_keys:
|
||||
if req_version.matches(mv.SNAPSHOT_SORT, None) and 'name' in sort_keys:
|
||||
sort_keys[sort_keys.index('name')] = 'display_name'
|
||||
|
||||
# NOTE(thingee): v3 API allows name instead of display_name
|
||||
|
@ -14,6 +14,7 @@
|
||||
# under the License.
|
||||
|
||||
from cinder.api import common
|
||||
from cinder.api import microversions as mv
|
||||
from cinder import utils
|
||||
|
||||
|
||||
@ -60,20 +61,21 @@ class ViewBuilder(common.ViewBuilder):
|
||||
|
||||
req_version = request.api_version_request
|
||||
# Add group_snapshot_id and source_group_id if min version is greater
|
||||
# than or equal to 3.14.
|
||||
if req_version.matches("3.14", None):
|
||||
# than or equal to GROUP_SNAPSHOTS.
|
||||
if req_version.matches(mv.GROUP_SNAPSHOTS, None):
|
||||
group_ref['group']['group_snapshot_id'] = group.group_snapshot_id
|
||||
group_ref['group']['source_group_id'] = group.source_group_id
|
||||
|
||||
# Add volumes if min version is greater than or equal to 3.25.
|
||||
if req_version.matches("3.25", None):
|
||||
# Add volumes if min version is greater than or equal to
|
||||
# GROUP_VOLUME_LIST.
|
||||
if req_version.matches(mv.GROUP_VOLUME_LIST, None):
|
||||
if utils.get_bool_param('list_volume', request.params):
|
||||
group_ref['group']['volumes'] = [volume.id
|
||||
for volume in group.volumes]
|
||||
|
||||
# Add replication_status if min version is greater than or equal
|
||||
# to 3.38.
|
||||
if req_version.matches("3.38", None):
|
||||
# to GROUP_REPLICATION.
|
||||
if req_version.matches(mv.GROUP_REPLICATION, None):
|
||||
group_ref['group']['replication_status'] = group.replication_status
|
||||
|
||||
return group_ref
|
||||
|
@ -13,6 +13,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.views import snapshots as views_v2
|
||||
|
||||
|
||||
@ -25,10 +26,10 @@ class ViewBuilder(views_v2.ViewBuilder):
|
||||
|
||||
req_version = request.api_version_request
|
||||
# Add group_snapshot_id if min version is greater than or equal
|
||||
# to 3.14.
|
||||
if req_version.matches("3.14", None):
|
||||
# to GROUP_SNAPSHOTS.
|
||||
if req_version.matches(mv.GROUP_SNAPSHOTS, None):
|
||||
snapshot_ref['snapshot']['group_snapshot_id'] = (
|
||||
snapshot.get('group_snapshot_id'))
|
||||
if req_version.matches("3.41", None):
|
||||
if req_version.matches(mv.SNAPSHOT_LIST_USER_ID, None):
|
||||
snapshot_ref['snapshot']['user_id'] = snapshot.get('user_id')
|
||||
return snapshot_ref
|
||||
|
@ -13,6 +13,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.v2.views import volumes as views_v2
|
||||
|
||||
|
||||
@ -41,14 +42,14 @@ class ViewBuilder(views_v2.ViewBuilder):
|
||||
volume_ref = super(ViewBuilder, self).detail(request, volume)
|
||||
|
||||
req_version = request.api_version_request
|
||||
# Add group_id if min version is greater than or equal to 3.13.
|
||||
if req_version.matches("3.13", None):
|
||||
# Add group_id if min version is greater than or equal to GROUP_VOLUME.
|
||||
if req_version.matches(mv.GROUP_VOLUME, None):
|
||||
volume_ref['volume']['group_id'] = volume.get('group_id')
|
||||
|
||||
# Add provider_id if min version is greater than or equal to 3.21
|
||||
# for admin.
|
||||
# Add provider_id if min version is greater than or equal to
|
||||
# VOLUME_DETAIL_PROVIDER_ID for admin.
|
||||
if (request.environ['cinder.context'].is_admin and
|
||||
req_version.matches("3.21", None)):
|
||||
req_version.matches(mv.VOLUME_DETAIL_PROVIDER_ID, None)):
|
||||
volume_ref['volume']['provider_id'] = volume.get('provider_id')
|
||||
|
||||
return volume_ref
|
||||
|
@ -15,6 +15,7 @@
|
||||
from six.moves import http_client
|
||||
|
||||
from cinder.api.contrib import volume_manage as volume_manage_v2
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.api.v3 import resource_common_manage as common
|
||||
|
||||
@ -27,7 +28,7 @@ class VolumeManageController(common.ManageResource,
|
||||
|
||||
@wsgi.response(http_client.ACCEPTED)
|
||||
def create(self, req, body):
|
||||
self._ensure_min_version(req, "3.8")
|
||||
self._ensure_min_version(req, mv.MANAGE_EXISTING_LIST)
|
||||
return super(VolumeManageController, self).create(req, body)
|
||||
|
||||
|
||||
|
@ -22,13 +22,11 @@ import six
|
||||
from six.moves import http_client
|
||||
import webob
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.api.v2 import volume_metadata as volume_meta_v2
|
||||
|
||||
|
||||
METADATA_MICRO_VERSION = '3.15'
|
||||
|
||||
|
||||
class Controller(volume_meta_v2.Controller):
|
||||
"""The volume metadata API controller for the OpenStack API."""
|
||||
def _validate_etag(self, req, volume_id):
|
||||
@ -46,7 +44,7 @@ class Controller(volume_meta_v2.Controller):
|
||||
def index(self, req, volume_id):
|
||||
req_version = req.api_version_request
|
||||
metadata = super(Controller, self).index(req, volume_id)
|
||||
if req_version.matches(METADATA_MICRO_VERSION):
|
||||
if req_version.matches(mv.ETAGS):
|
||||
data = jsonutils.dumps(metadata)
|
||||
if six.PY3:
|
||||
data = data.encode('utf-8')
|
||||
@ -59,7 +57,7 @@ class Controller(volume_meta_v2.Controller):
|
||||
@wsgi.extends
|
||||
def update(self, req, volume_id, id, body):
|
||||
req_version = req.api_version_request
|
||||
if req_version.matches(METADATA_MICRO_VERSION):
|
||||
if req_version.matches(mv.ETAGS):
|
||||
if not self._validate_etag(req, volume_id):
|
||||
return webob.Response(
|
||||
status_int=http_client.PRECONDITION_FAILED)
|
||||
@ -69,7 +67,7 @@ class Controller(volume_meta_v2.Controller):
|
||||
@wsgi.extends
|
||||
def update_all(self, req, volume_id, body):
|
||||
req_version = req.api_version_request
|
||||
if req_version.matches(METADATA_MICRO_VERSION):
|
||||
if req_version.matches(mv.ETAGS):
|
||||
if not self._validate_etag(req, volume_id):
|
||||
return webob.Response(
|
||||
status_int=http_client.PRECONDITION_FAILED)
|
||||
|
@ -21,6 +21,7 @@ import webob
|
||||
from webob import exc
|
||||
|
||||
from cinder.api import common
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.api.v2 import volumes as volumes_v2
|
||||
from cinder.api.v3.views import volumes as volume_views_v3
|
||||
@ -33,8 +34,6 @@ from cinder import utils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
SUMMARY_BASE_MICRO_VERSION = '3.12'
|
||||
|
||||
|
||||
def check_policy(context, action, target_obj=None):
|
||||
target = {
|
||||
@ -65,7 +64,7 @@ class VolumeController(volumes_v2.VolumeController):
|
||||
force = False
|
||||
|
||||
params = ""
|
||||
if req_version.matches('3.23'):
|
||||
if req_version.matches(mv.VOLUME_LIST_BOOTABLE):
|
||||
force = utils.get_bool_param('force', req.params)
|
||||
if cascade or force:
|
||||
params = "(cascade: %(c)s, force: %(f)s)" % {'c': cascade,
|
||||
@ -88,10 +87,10 @@ class VolumeController(volumes_v2.VolumeController):
|
||||
@common.process_general_filtering('volume')
|
||||
def _process_volume_filtering(self, context=None, filters=None,
|
||||
req_version=None):
|
||||
if req_version.matches(None, "3.3"):
|
||||
if req_version.matches(None, mv.MESSAGES):
|
||||
filters.pop('glance_metadata', None)
|
||||
|
||||
if req_version.matches(None, "3.9"):
|
||||
if req_version.matches(None, mv.BACKUP_UPDATE):
|
||||
filters.pop('group_id', None)
|
||||
|
||||
utils.remove_invalid_filter_options(
|
||||
@ -119,7 +118,8 @@ class VolumeController(volumes_v2.VolumeController):
|
||||
if 'name' in filters:
|
||||
filters['display_name'] = filters.pop('name')
|
||||
|
||||
strict = req.api_version_request.matches("3.2", None)
|
||||
strict = req.api_version_request.matches(
|
||||
mv.VOLUME_LIST_BOOTABLE, None)
|
||||
self.volume_api.check_volume_filters(filters, strict)
|
||||
|
||||
volumes = self.volume_api.get_all(context, marker, limit,
|
||||
@ -140,7 +140,7 @@ class VolumeController(volumes_v2.VolumeController):
|
||||
volumes = self._view_builder.summary_list(req, volumes)
|
||||
return volumes
|
||||
|
||||
@wsgi.Controller.api_version(SUMMARY_BASE_MICRO_VERSION)
|
||||
@wsgi.Controller.api_version(mv.VOLUME_SUMMARY)
|
||||
def summary(self, req):
|
||||
"""Return summary of volumes."""
|
||||
view_builder_v3 = volume_views_v3.ViewBuilder()
|
||||
@ -154,7 +154,7 @@ class VolumeController(volumes_v2.VolumeController):
|
||||
context, filters=filters)
|
||||
|
||||
req_version = req.api_version_request
|
||||
if req_version.matches("3.36"):
|
||||
if req_version.matches(mv.VOLUME_SUMMARY_METADATA):
|
||||
all_distinct_metadata = metadata
|
||||
else:
|
||||
all_distinct_metadata = None
|
||||
@ -163,7 +163,7 @@ class VolumeController(volumes_v2.VolumeController):
|
||||
all_distinct_metadata)
|
||||
|
||||
@wsgi.response(http_client.ACCEPTED)
|
||||
@wsgi.Controller.api_version('3.40')
|
||||
@wsgi.Controller.api_version(mv.VOLUME_REVERT)
|
||||
@wsgi.action('revert')
|
||||
def revert(self, req, id, body):
|
||||
"""revert a volume to a snapshot"""
|
||||
@ -208,8 +208,8 @@ class VolumeController(volumes_v2.VolumeController):
|
||||
context = req.environ['cinder.context']
|
||||
|
||||
req_version = req.api_version_request
|
||||
# Remove group_id from body if max version is less than 3.13.
|
||||
if req_version.matches(None, "3.12"):
|
||||
# Remove group_id from body if max version is less than GROUP_VOLUME.
|
||||
if req_version.matches(None, mv.get_prior_version(mv.GROUP_VOLUME)):
|
||||
# NOTE(xyang): The group_id is from a group created with a
|
||||
# group_type. So with this group_id, we've got a group_type
|
||||
# for this volume. Also if group_id is passed in, that means
|
||||
|
@ -16,6 +16,7 @@
|
||||
from oslo_utils import timeutils
|
||||
from oslo_utils import uuidutils
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder.api.v3.views import workers as workers_view
|
||||
from cinder import db
|
||||
@ -98,7 +99,7 @@ class WorkerController(wsgi.Controller):
|
||||
|
||||
return params
|
||||
|
||||
@wsgi.Controller.api_version('3.24')
|
||||
@wsgi.Controller.api_version(mv.WORKERS_CLEANUP)
|
||||
@wsgi.response(202)
|
||||
def cleanup(self, req, body=None):
|
||||
"""Do the cleanup on resources from a specific service/host/node."""
|
||||
|
@ -51,7 +51,7 @@ _KNOWN_VERSIONS = {
|
||||
"status": "CURRENT",
|
||||
"version": api_version_request._MAX_API_VERSION,
|
||||
"min_version": api_version_request._MIN_API_VERSION,
|
||||
"updated": "2016-02-08T12:20:21Z",
|
||||
"updated": api_version_request.UPDATED,
|
||||
"links": _LINKS,
|
||||
"media-types": [{
|
||||
"base": "application/json",
|
||||
|
@ -14,6 +14,7 @@
|
||||
# under the License.
|
||||
|
||||
from cinder.api import common
|
||||
from cinder.api import microversions as mv
|
||||
|
||||
|
||||
class ViewBuilder(common.ViewBuilder):
|
||||
@ -78,7 +79,7 @@ class ViewBuilder(common.ViewBuilder):
|
||||
}
|
||||
}
|
||||
req_version = request.api_version_request
|
||||
if req_version.matches("3.43"):
|
||||
if req_version.matches(mv.BACKUP_METADATA):
|
||||
backup_dict['backup']['metadata'] = backup.metadata
|
||||
return backup_dict
|
||||
|
||||
|
@ -24,7 +24,6 @@ CONF = config.CONF
|
||||
|
||||
|
||||
class VolumeRevertTests(volume_base.BaseVolumeTest):
|
||||
min_microversion = '3.40'
|
||||
|
||||
@classmethod
|
||||
def setup_clients(cls):
|
||||
|
@ -23,7 +23,7 @@ import webob
|
||||
from webob import exc
|
||||
|
||||
from cinder.api.contrib import admin_actions
|
||||
from cinder.api.openstack import api_version_request as api_version
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.backup import api as backup_api
|
||||
from cinder.backup import rpcapi as backup_rpcapi
|
||||
from cinder.common import constants
|
||||
@ -525,18 +525,16 @@ class AdminActionsTest(BaseAdminTest):
|
||||
force_host_copy=False, version=None,
|
||||
cluster=None):
|
||||
# build request to migrate to host
|
||||
# req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' % (
|
||||
# fake.PROJECT_ID, volume['id']))
|
||||
req = webob.Request.blank('/v3/%s/volumes/%s/action' % (
|
||||
fake.PROJECT_ID, volume['id']))
|
||||
req.method = 'POST'
|
||||
req.headers['content-type'] = 'application/json'
|
||||
body = {'os-migrate_volume': {'host': host,
|
||||
'force_host_copy': force_host_copy}}
|
||||
version = version or '3.0'
|
||||
req.headers = {'OpenStack-API-Version': 'volume %s' % version}
|
||||
req.api_version_request = api_version.APIVersionRequest(version)
|
||||
if version == '3.16':
|
||||
version = version or mv.BASE_VERSION
|
||||
req.headers = mv.get_mv_header(version)
|
||||
req.api_version_request = mv.get_api_version(version)
|
||||
if version == mv.VOLUME_MIGRATE_CLUSTER:
|
||||
body['os-migrate_volume']['cluster'] = cluster
|
||||
req.body = jsonutils.dump_as_bytes(body)
|
||||
req.environ['cinder.context'] = ctx
|
||||
@ -547,7 +545,9 @@ class AdminActionsTest(BaseAdminTest):
|
||||
volume = db.volume_get(self.ctx, volume['id'])
|
||||
return volume
|
||||
|
||||
@ddt.data('3.0', '3.15', '3.16')
|
||||
@ddt.data(mv.BASE_VERSION,
|
||||
mv.get_prior_version(mv.VOLUME_MIGRATE_CLUSTER),
|
||||
mv.VOLUME_MIGRATE_CLUSTER)
|
||||
def test_migrate_volume_success_3(self, version):
|
||||
expected_status = http_client.ACCEPTED
|
||||
host = 'test2'
|
||||
@ -563,7 +563,8 @@ class AdminActionsTest(BaseAdminTest):
|
||||
cluster = 'cluster'
|
||||
volume = self._migrate_volume_prep()
|
||||
volume = self._migrate_volume_3_exec(self.ctx, volume, host,
|
||||
expected_status, version='3.16',
|
||||
expected_status,
|
||||
version=mv.VOLUME_MIGRATE_CLUSTER,
|
||||
cluster=cluster)
|
||||
self.assertEqual('starting', volume['migration_status'])
|
||||
|
||||
@ -574,7 +575,8 @@ class AdminActionsTest(BaseAdminTest):
|
||||
volume = self._migrate_volume_prep()
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
self._migrate_volume_3_exec, self.ctx, volume, host,
|
||||
None, version='3.16', cluster=cluster)
|
||||
None, version=mv.VOLUME_MIGRATE_CLUSTER,
|
||||
cluster=cluster)
|
||||
|
||||
def _migrate_volume_exec(self, ctx, volume, host, expected_status,
|
||||
force_host_copy=False):
|
||||
|
@ -17,7 +17,7 @@ import ddt
|
||||
from oslo_serialization import jsonutils
|
||||
import webob
|
||||
|
||||
from cinder.api.openstack import api_version_request as api_version
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.v3 import router as router_v3
|
||||
from cinder.backup import api as backup_api
|
||||
from cinder import context
|
||||
@ -57,7 +57,8 @@ class BackupProjectAttributeTest(test.TestCase):
|
||||
self.stubs.Set(backup_api.API, 'get', fake_backup_get)
|
||||
self.stubs.Set(backup_api.API, 'get_all', fake_backup_get_all)
|
||||
|
||||
def _send_backup_request(self, ctx, detail=False, version='3.18'):
|
||||
def _send_backup_request(self, ctx, detail=False,
|
||||
version=mv.BACKUP_PROJECT):
|
||||
req = None
|
||||
if detail:
|
||||
req = webob.Request.blank(('/v3/%s/backups/detail'
|
||||
@ -67,8 +68,8 @@ class BackupProjectAttributeTest(test.TestCase):
|
||||
fake.BACKUP_ID))
|
||||
req.method = 'GET'
|
||||
req.environ['cinder.context'] = ctx
|
||||
req.headers['OpenStack-API-Version'] = 'volume ' + version
|
||||
req.api_version_request = api_version.APIVersionRequest(version)
|
||||
req.headers = mv.get_mv_header(version)
|
||||
req.api_version_request = mv.get_api_version(version)
|
||||
res = req.get_response(app())
|
||||
|
||||
if detail:
|
||||
@ -97,5 +98,6 @@ class BackupProjectAttributeTest(test.TestCase):
|
||||
|
||||
def test_get_backup_under_allowed_api_version(self):
|
||||
ctx = context.RequestContext(fake.USER2_ID, fake.PROJECT_ID, True)
|
||||
bak = self._send_backup_request(ctx, version='3.17')
|
||||
bak = self._send_backup_request(
|
||||
ctx, version=mv.get_prior_version(mv.BACKUP_PROJECT))
|
||||
self.assertNotIn('os-backup-project-attr:project_id', bak)
|
||||
|
@ -25,6 +25,7 @@ from six.moves import http_client
|
||||
import webob
|
||||
|
||||
from cinder.api.contrib import backups
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import api_version_request as api_version
|
||||
# needed for stubs to work
|
||||
import cinder.backup
|
||||
@ -117,8 +118,8 @@ class BackupsAPITestCase(test.TestCase):
|
||||
req = webob.Request.blank('/v3/%s/backups/%s' % (
|
||||
fake.PROJECT_ID, backup.id))
|
||||
req.method = 'GET'
|
||||
req.headers = mv.get_mv_header(mv.BACKUP_METADATA)
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.headers['OpenStack-API-Version'] = 'volume 3.43'
|
||||
res = req.get_response(fakes.wsgi_app(
|
||||
fake_auth_context=self.user_context))
|
||||
res_dict = jsonutils.loads(res.body)
|
||||
@ -131,6 +132,7 @@ class BackupsAPITestCase(test.TestCase):
|
||||
req = webob.Request.blank('/v2/%s/backups/%s' % (
|
||||
fake.PROJECT_ID, fake.WILL_NOT_BE_FOUND_ID))
|
||||
req.method = 'GET'
|
||||
req.headers = mv.get_mv_header(mv.BACKUP_METADATA)
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
res = req.get_response(fakes.wsgi_app(
|
||||
fake_auth_context=self.user_context))
|
||||
@ -330,9 +332,9 @@ class BackupsAPITestCase(test.TestCase):
|
||||
|
||||
req = webob.Request.blank('/v3/%s/backups/detail' % fake.PROJECT_ID)
|
||||
req.method = 'GET'
|
||||
req.headers = mv.get_mv_header(mv.BACKUP_METADATA)
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.headers['Accept'] = 'application/json'
|
||||
req.headers['OpenStack-API-Version'] = 'volume 3.43'
|
||||
res = req.get_response(fakes.wsgi_app(
|
||||
fake_auth_context=self.user_context))
|
||||
res_dict = jsonutils.loads(res.body)
|
||||
@ -536,8 +538,8 @@ class BackupsAPITestCase(test.TestCase):
|
||||
}
|
||||
req = webob.Request.blank('/v3/%s/backups' % fake.PROJECT_ID)
|
||||
req.method = 'POST'
|
||||
req.headers = mv.get_mv_header(mv.BACKUP_METADATA)
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.headers['OpenStack-API-Version'] = 'volume 3.43'
|
||||
req.body = jsonutils.dump_as_bytes(body)
|
||||
res = req.get_response(fakes.wsgi_app(
|
||||
fake_auth_context=self.user_context))
|
||||
@ -546,8 +548,8 @@ class BackupsAPITestCase(test.TestCase):
|
||||
req = webob.Request.blank('/v3/%s/backups/%s' % (
|
||||
fake.PROJECT_ID, res_dict['backup']['id']))
|
||||
req.method = 'GET'
|
||||
req.headers = mv.get_mv_header(mv.BACKUP_METADATA)
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.headers['OpenStack-API-Version'] = 'volume 3.43'
|
||||
res = req.get_response(fakes.wsgi_app(
|
||||
fake_auth_context=self.user_context))
|
||||
res_dict = jsonutils.loads(res.body)
|
||||
|
@ -19,6 +19,7 @@ import mock
|
||||
import webob
|
||||
|
||||
from cinder.api.contrib import scheduler_stats
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import api_version_request as api_version
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
@ -84,7 +85,7 @@ class SchedulerStatsAPITest(test.TestCase):
|
||||
fake.PROJECT_ID)
|
||||
mock_rpcapi.return_value = [dict(name='pool1',
|
||||
capabilities=dict(foo='bar'))]
|
||||
req.api_version_request = api_version.APIVersionRequest('3.28')
|
||||
req.api_version_request = mv.get_api_version(mv.POOL_FILTER)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
res = self.controller.get_pools(req)
|
||||
|
||||
@ -106,7 +107,7 @@ class SchedulerStatsAPITest(test.TestCase):
|
||||
'&foo=bar' % fake.PROJECT_ID)
|
||||
mock_rpcapi.return_value = [dict(name='pool1',
|
||||
capabilities=dict(foo='bar'))]
|
||||
req.api_version_request = api_version.APIVersionRequest('3.28')
|
||||
req.api_version_request = mv.get_api_version(mv.POOL_FILTER)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
res = self.controller.get_pools(req)
|
||||
|
||||
@ -175,8 +176,8 @@ class SchedulerStatsAPITest(test.TestCase):
|
||||
self.controller.get_pools,
|
||||
req)
|
||||
|
||||
@ddt.data(('3.34', False),
|
||||
('3.35', True))
|
||||
@ddt.data((mv.get_prior_version(mv.POOL_TYPE_FILTER), False),
|
||||
(mv.POOL_TYPE_FILTER, True))
|
||||
@ddt.unpack
|
||||
@mock.patch('cinder.scheduler.rpcapi.SchedulerAPI.get_pools')
|
||||
@mock.patch('cinder.api.common.reject_invalid_filters')
|
||||
|
@ -25,7 +25,7 @@ import webob.exc
|
||||
|
||||
from cinder.api.contrib import services
|
||||
from cinder.api import extensions
|
||||
from cinder.api.openstack import api_version_request as api_version
|
||||
from cinder.api import microversions as mv
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
from cinder import objects
|
||||
@ -114,10 +114,10 @@ fake_services_list = [
|
||||
class FakeRequest(object):
|
||||
environ = {"cinder.context": context.get_admin_context()}
|
||||
|
||||
def __init__(self, version='3.0', **kwargs):
|
||||
def __init__(self, version=mv.BASE_VERSION, **kwargs):
|
||||
self.GET = kwargs
|
||||
self.headers = {'OpenStack-API-Version': 'volume ' + version}
|
||||
self.api_version_request = api_version.APIVersionRequest(version)
|
||||
self.headers = mv.get_mv_header(version)
|
||||
self.api_version_request = mv.get_api_version(version)
|
||||
|
||||
|
||||
class FakeRequestWithBinary(FakeRequest):
|
||||
@ -246,19 +246,19 @@ class ServicesTest(test.TestCase):
|
||||
self.assertEqual(response, res_dict)
|
||||
|
||||
def test_failover_old_version(self):
|
||||
req = FakeRequest(version='3.18')
|
||||
req = FakeRequest(version=mv.BACKUP_PROJECT)
|
||||
self.assertRaises(exception.InvalidInput, self.controller.update, req,
|
||||
'failover', {'cluster': 'cluster1'})
|
||||
|
||||
def test_failover_no_values(self):
|
||||
req = FakeRequest(version='3.26')
|
||||
req = FakeRequest(version=mv.REPLICATION_CLUSTER)
|
||||
self.assertRaises(exception.InvalidInput, self.controller.update, req,
|
||||
'failover', {'backend_id': 'replica1'})
|
||||
|
||||
@ddt.data({'host': 'hostname'}, {'cluster': 'mycluster'})
|
||||
@mock.patch('cinder.volume.api.API.failover')
|
||||
def test_failover(self, body, failover_mock):
|
||||
req = FakeRequest(version='3.26')
|
||||
req = FakeRequest(version=mv.REPLICATION_CLUSTER)
|
||||
body['backend_id'] = 'replica1'
|
||||
res = self.controller.update(req, 'failover', body)
|
||||
self.assertEqual(202, res.status_code)
|
||||
@ -269,14 +269,14 @@ class ServicesTest(test.TestCase):
|
||||
@ddt.data({}, {'host': 'hostname', 'cluster': 'mycluster'})
|
||||
@mock.patch('cinder.volume.api.API.failover')
|
||||
def test_failover_invalid_input(self, body, failover_mock):
|
||||
req = FakeRequest(version='3.26')
|
||||
req = FakeRequest(version=mv.REPLICATION_CLUSTER)
|
||||
body['backend_id'] = 'replica1'
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
self.controller.update, req, 'failover', body)
|
||||
failover_mock.assert_not_called()
|
||||
|
||||
def test_services_list_with_cluster_name(self):
|
||||
req = FakeRequest(version='3.7')
|
||||
req = FakeRequest(version=mv.CLUSTER_SUPPORT)
|
||||
res_dict = self.controller.index(req)
|
||||
|
||||
response = {'services': [{'binary': 'cinder-scheduler',
|
||||
@ -689,7 +689,7 @@ class ServicesTest(test.TestCase):
|
||||
def test_services_action_cluster_not_found(self, method, body,
|
||||
mock_get_all_services):
|
||||
url = '/v3/%s/os-services/%s' % (fake.PROJECT_ID, method)
|
||||
req = fakes.HTTPRequest.blank(url, version='3.26')
|
||||
req = fakes.HTTPRequest.blank(url, version=mv.REPLICATION_CLUSTER)
|
||||
mock_get_all_services.return_value = []
|
||||
msg = 'No service found with cluster=%s' % mock.sentinel.cluster
|
||||
result = self.assertRaises(exception.InvalidInput,
|
||||
@ -729,7 +729,7 @@ class ServicesTest(test.TestCase):
|
||||
@mock.patch('cinder.api.contrib.services.ServiceController._set_log')
|
||||
def test_set_log(self, set_log_mock):
|
||||
set_log_mock.return_value = None
|
||||
req = FakeRequest(version='3.32')
|
||||
req = FakeRequest(version=mv.LOG_LEVEL)
|
||||
body = mock.sentinel.body
|
||||
res = self.controller.update(req, 'set-log', body)
|
||||
self.assertEqual(set_log_mock.return_value, res)
|
||||
@ -738,7 +738,7 @@ class ServicesTest(test.TestCase):
|
||||
@mock.patch('cinder.api.contrib.services.ServiceController._get_log')
|
||||
def test_get_log(self, get_log_mock):
|
||||
get_log_mock.return_value = None
|
||||
req = FakeRequest(version='3.32')
|
||||
req = FakeRequest(version=mv.LOG_LEVEL)
|
||||
body = mock.sentinel.body
|
||||
res = self.controller.update(req, 'get-log', body)
|
||||
self.assertEqual(get_log_mock.return_value, res)
|
||||
|
@ -17,6 +17,7 @@ import ddt
|
||||
import mock
|
||||
|
||||
from cinder.api.contrib import used_limits
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import api_version_request
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder import exception
|
||||
@ -40,8 +41,11 @@ class UsedLimitsTestCase(test.TestCase):
|
||||
super(UsedLimitsTestCase, self).setUp()
|
||||
self.controller = used_limits.UsedLimitsController()
|
||||
|
||||
@ddt.data(('2.0', False), ('3.38', True), ('3.38', False), ('3.39', True),
|
||||
('3.39', False))
|
||||
@ddt.data(('2.0', False),
|
||||
(mv.get_prior_version(mv.LIMITS_ADMIN_FILTER), True),
|
||||
(mv.get_prior_version(mv.LIMITS_ADMIN_FILTER), False),
|
||||
(mv.LIMITS_ADMIN_FILTER, True),
|
||||
(mv.LIMITS_ADMIN_FILTER, False))
|
||||
@mock.patch('cinder.quota.QUOTAS.get_project_quotas')
|
||||
@mock.patch('cinder.policy.enforce')
|
||||
def test_used_limits(self, ver_project, _mock_policy_enforce,
|
||||
@ -78,9 +82,9 @@ class UsedLimitsTestCase(test.TestCase):
|
||||
self.controller.index(fake_req, res)
|
||||
abs_limits = res.obj['limits']['absolute']
|
||||
|
||||
# if admin, only 3.39 and req contains project_id filter, cinder
|
||||
# returns the specified project's quota.
|
||||
if version == '3.39' and has_project:
|
||||
# if admin, only LIMITS_ADMIN_FILTER and req contains project_id
|
||||
# filter, cinder returns the specified project's quota.
|
||||
if version == mv.LIMITS_ADMIN_FILTER and has_project:
|
||||
self.assertEqual(1, abs_limits['totalGigabytesUsed'])
|
||||
else:
|
||||
self.assertEqual(2, abs_limits['totalGigabytesUsed'])
|
||||
|
@ -24,7 +24,7 @@ from six.moves import http_client
|
||||
import webob
|
||||
|
||||
from cinder.api.contrib import volume_actions
|
||||
from cinder.api.openstack import api_version_request as api_version
|
||||
from cinder.api import microversions as mv
|
||||
from cinder import context
|
||||
from cinder import db
|
||||
from cinder import exception
|
||||
@ -818,7 +818,7 @@ class VolumeImageActionsTest(test.TestCase):
|
||||
'size': 0}
|
||||
return ret
|
||||
|
||||
def fake_image_service_create_3_1(self, *args):
|
||||
def fake_image_service_create_with_params(self, *args):
|
||||
ret = {
|
||||
'status': u'queued',
|
||||
'name': u'image_name',
|
||||
@ -1017,13 +1017,13 @@ class VolumeImageActionsTest(test.TestCase):
|
||||
id,
|
||||
body)
|
||||
|
||||
@ddt.data({'version': '3.41',
|
||||
@ddt.data({'version': mv.get_prior_version(mv.VOLUME_EXTEND_INUSE),
|
||||
'status': 'available'},
|
||||
{'version': '3.41',
|
||||
{'version': mv.get_prior_version(mv.VOLUME_EXTEND_INUSE),
|
||||
'status': 'in-use'},
|
||||
{'version': '3.42',
|
||||
{'version': mv.VOLUME_EXTEND_INUSE,
|
||||
'status': 'available'},
|
||||
{'version': '3.42',
|
||||
{'version': mv.VOLUME_EXTEND_INUSE,
|
||||
'status': 'in-use'})
|
||||
@ddt.unpack
|
||||
def test_extend_attached_volume(self, version, status):
|
||||
@ -1035,9 +1035,9 @@ class VolumeImageActionsTest(test.TestCase):
|
||||
body = {"os-extend": {"new_size": 2}}
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/volumes/%s/action' %
|
||||
(fake.PROJECT_ID, vol['id']))
|
||||
req.api_version_request = api_version.APIVersionRequest(version)
|
||||
req.api_version_request = mv.get_api_version(version)
|
||||
self.controller._extend(req, vol['id'], body)
|
||||
if version == '3.42' and status == 'in-use':
|
||||
if version == mv.VOLUME_EXTEND_INUSE and status == 'in-use':
|
||||
mock_extend.assert_called_with(req.environ['cinder.context'],
|
||||
vol, 2, attached=True)
|
||||
else:
|
||||
@ -1117,8 +1117,8 @@ class VolumeImageActionsTest(test.TestCase):
|
||||
id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
|
||||
req = fakes.HTTPRequest.blank('/v3/tenant1/volumes/%s/action' % id)
|
||||
req.environ['cinder.context'].is_admin = False
|
||||
req.headers = {'OpenStack-API-Version': 'volume 3.1'}
|
||||
req.api_version_request = api_version.APIVersionRequest('3.1')
|
||||
req.headers = mv.get_mv_header(mv.UPLOAD_IMAGE_PARAMS)
|
||||
req.api_version_request = mv.get_api_version(mv.UPLOAD_IMAGE_PARAMS)
|
||||
body = self._get_os_volume_upload_image()
|
||||
body['os-volume_upload_image']['visibility'] = 'public'
|
||||
self.assertRaises(exception.PolicyNotAuthorized,
|
||||
@ -1311,7 +1311,7 @@ class VolumeImageActionsTest(test.TestCase):
|
||||
@mock.patch.object(volume_api.API, "get_volume_image_metadata")
|
||||
@mock.patch.object(glance.GlanceImageService, "create")
|
||||
@mock.patch.object(volume_rpcapi.VolumeAPI, "copy_volume_to_image")
|
||||
def test_copy_volume_to_image_version_3_1(
|
||||
def test_copy_volume_to_image_version_with_params(
|
||||
self,
|
||||
mock_copy_volume_to_image,
|
||||
mock_create,
|
||||
@ -1323,7 +1323,7 @@ class VolumeImageActionsTest(test.TestCase):
|
||||
"volume_id": volume.id,
|
||||
"key": "x_billing_code_license",
|
||||
"value": "246254365"}
|
||||
mock_create.side_effect = self.fake_image_service_create_3_1
|
||||
mock_create.side_effect = self.fake_image_service_create_with_params
|
||||
mock_copy_volume_to_image.side_effect = \
|
||||
self.fake_rpc_copy_volume_to_image
|
||||
|
||||
@ -1333,8 +1333,8 @@ class VolumeImageActionsTest(test.TestCase):
|
||||
'/v3/%s/volumes/%s/action' % (fake.PROJECT_ID, volume.id),
|
||||
use_admin_context=self.context.is_admin)
|
||||
req.environ['cinder.context'].is_admin = True
|
||||
req.headers = {'OpenStack-API-Version': 'volume 3.1'}
|
||||
req.api_version_request = api_version.APIVersionRequest('3.1')
|
||||
req.headers = mv.get_mv_header(mv.UPLOAD_IMAGE_PARAMS)
|
||||
req.api_version_request = mv.get_api_version(mv.UPLOAD_IMAGE_PARAMS)
|
||||
body = self._get_os_volume_upload_image()
|
||||
body['os-volume_upload_image']['visibility'] = 'public'
|
||||
body['os-volume_upload_image']['protected'] = True
|
||||
|
@ -23,6 +23,7 @@ from six.moves.urllib.parse import urlencode
|
||||
import webob
|
||||
|
||||
from cinder.api.contrib import volume_manage
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import api_version_request as api_version
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
@ -226,15 +227,15 @@ class VolumeManageTest(test.TestCase):
|
||||
self.assertEqual(body['volume']['ref'], args[3])
|
||||
self.assertTrue(mock_validate.called)
|
||||
|
||||
def _get_resp_create(self, body, version='3.0'):
|
||||
def _get_resp_create(self, body, version=mv.BASE_VERSION):
|
||||
url = '/v3/%s/os-volume-manage' % fake.PROJECT_ID
|
||||
req = webob.Request.blank(url, base_url='http://localhost.com' + url)
|
||||
req.method = 'POST'
|
||||
req.headers = mv.get_mv_header(version)
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.environ['cinder.context'] = self._admin_ctxt
|
||||
req.body = jsonutils.dump_as_bytes(body)
|
||||
req.headers = {'OpenStack-API-Version': 'volume %s' % version}
|
||||
req.api_version_request = api_version.APIVersionRequest(version)
|
||||
req.api_version_request = mv.get_api_version(version)
|
||||
res = self.controller.create(req, body)
|
||||
return res
|
||||
|
||||
@ -244,7 +245,7 @@ class VolumeManageTest(test.TestCase):
|
||||
def test_manage_volume_ok_cluster(self, mock_validate, mock_api_manage):
|
||||
body = {'volume': {'cluster': 'cluster',
|
||||
'ref': 'fake_ref'}}
|
||||
res = self._get_resp_create(body, '3.16')
|
||||
res = self._get_resp_create(body, mv.VOLUME_MIGRATE_CLUSTER)
|
||||
self.assertEqual(['volume'], list(res.keys()))
|
||||
|
||||
# Check that the manage API was called with the correct arguments.
|
||||
@ -262,7 +263,8 @@ class VolumeManageTest(test.TestCase):
|
||||
'cluster': 'cluster',
|
||||
'ref': 'fake_ref'}}
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
self._get_resp_create, body, '3.16')
|
||||
self._get_resp_create, body,
|
||||
mv.VOLUME_MIGRATE_CLUSTER)
|
||||
|
||||
def test_manage_volume_missing_host(self):
|
||||
"""Test correct failure when host is not specified."""
|
||||
@ -485,7 +487,7 @@ class VolumeManageTest(test.TestCase):
|
||||
"""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, '3.15')
|
||||
res = self._get_resp_post_v3(body, mv.ETAGS)
|
||||
self.assertEqual(http_client.ACCEPTED, res.status_int)
|
||||
self.assertEqual(1, mock_api_manage.call_count)
|
||||
self.assertEqual('creating',
|
||||
|
@ -21,6 +21,7 @@ import ddt
|
||||
import mock
|
||||
import webob
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.v3 import attachments as v3_attachments
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
@ -31,8 +32,6 @@ from cinder.tests.unit import fake_constants as fake
|
||||
from cinder.volume import api as volume_api
|
||||
from cinder.volume import rpcapi as volume_rpcapi
|
||||
|
||||
ATTACHMENTS_MICRO_VERSION = '3.27'
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class AttachmentsAPITestCase(test.TestCase):
|
||||
@ -81,7 +80,7 @@ class AttachmentsAPITestCase(test.TestCase):
|
||||
def test_create_attachment(self):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/attachments' %
|
||||
fake.PROJECT_ID,
|
||||
version=ATTACHMENTS_MICRO_VERSION)
|
||||
version=mv.NEW_ATTACH)
|
||||
body = {
|
||||
"attachment":
|
||||
{
|
||||
@ -104,7 +103,7 @@ class AttachmentsAPITestCase(test.TestCase):
|
||||
mock_update.return_value = fake_connector
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/attachments/%s' %
|
||||
(fake.PROJECT_ID, self.attachment1.id),
|
||||
version=ATTACHMENTS_MICRO_VERSION,
|
||||
version=mv.NEW_ATTACH,
|
||||
use_admin_context=True)
|
||||
body = {
|
||||
"attachment":
|
||||
@ -124,7 +123,7 @@ class AttachmentsAPITestCase(test.TestCase):
|
||||
mock_get.return_value = {'project_id': fake.PROJECT2_ID}
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/attachments/%s' %
|
||||
(fake.PROJECT_ID, self.attachment1.id),
|
||||
version=ATTACHMENTS_MICRO_VERSION,
|
||||
version=mv.NEW_ATTACH,
|
||||
use_admin_context=False)
|
||||
body = {
|
||||
"attachment":
|
||||
@ -139,7 +138,8 @@ class AttachmentsAPITestCase(test.TestCase):
|
||||
self.controller.delete, req,
|
||||
self.attachment1.id)
|
||||
|
||||
@ddt.data('3.30', '3.31', '3.34')
|
||||
@ddt.data(mv.get_prior_version(mv.RESOURCE_FILTER),
|
||||
mv.RESOURCE_FILTER, mv.LIKE_FILTER)
|
||||
@mock.patch('cinder.api.common.reject_invalid_filters')
|
||||
def test_attachment_list_with_general_filter(self, version, mock_update):
|
||||
url = '/v3/%s/attachments' % fake.PROJECT_ID
|
||||
@ -148,8 +148,8 @@ class AttachmentsAPITestCase(test.TestCase):
|
||||
use_admin_context=False)
|
||||
self.controller.index(req)
|
||||
|
||||
if version != '3.30':
|
||||
support_like = True if version == '3.34' else False
|
||||
if version != mv.get_prior_version(mv.RESOURCE_FILTER):
|
||||
support_like = True if version == mv.LIKE_FILTER else False
|
||||
mock_update.assert_called_once_with(req.environ['cinder.context'],
|
||||
mock.ANY, 'attachment',
|
||||
support_like)
|
||||
@ -164,7 +164,7 @@ class AttachmentsAPITestCase(test.TestCase):
|
||||
attach_status=status)
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/attachments/%s' %
|
||||
(fake.PROJECT_ID, attachment.id),
|
||||
version=ATTACHMENTS_MICRO_VERSION,
|
||||
version=mv.NEW_ATTACH,
|
||||
use_admin_context=True)
|
||||
|
||||
self.controller.delete(req, attachment.id)
|
||||
@ -201,7 +201,7 @@ class AttachmentsAPITestCase(test.TestCase):
|
||||
def test_create_attachment_without_resource_uuid(self, resource_uuid):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/attachments' %
|
||||
fake.PROJECT_ID,
|
||||
version=ATTACHMENTS_MICRO_VERSION)
|
||||
version=mv.NEW_ATTACH)
|
||||
body = {
|
||||
"attachment":
|
||||
{
|
||||
@ -220,7 +220,7 @@ class AttachmentsAPITestCase(test.TestCase):
|
||||
if is_detail:
|
||||
url = '/v3/%s/groups/detail' % fake.PROJECT_ID
|
||||
list_func = self.controller.detail
|
||||
req = fakes.HTTPRequest.blank(url, version=ATTACHMENTS_MICRO_VERSION,
|
||||
req = fakes.HTTPRequest.blank(url, version=mv.NEW_ATTACH,
|
||||
use_admin_context=True)
|
||||
res_dict = list_func(req)
|
||||
|
||||
@ -231,7 +231,7 @@ class AttachmentsAPITestCase(test.TestCase):
|
||||
|
||||
def test_list_attachments_with_limit(self):
|
||||
url = '/v3/%s/attachments?limit=1' % fake.PROJECT_ID
|
||||
req = fakes.HTTPRequest.blank(url, version=ATTACHMENTS_MICRO_VERSION,
|
||||
req = fakes.HTTPRequest.blank(url, version=mv.NEW_ATTACH,
|
||||
use_admin_context=True)
|
||||
res_dict = self.controller.index(req)
|
||||
|
||||
@ -241,7 +241,7 @@ class AttachmentsAPITestCase(test.TestCase):
|
||||
def test_list_attachments_with_marker(self):
|
||||
url = '/v3/%s/attachments?marker=%s' % (fake.PROJECT_ID,
|
||||
self.attachment3.id)
|
||||
req = fakes.HTTPRequest.blank(url, version=ATTACHMENTS_MICRO_VERSION,
|
||||
req = fakes.HTTPRequest.blank(url, version=mv.NEW_ATTACH,
|
||||
use_admin_context=True)
|
||||
res_dict = self.controller.index(req)
|
||||
|
||||
@ -254,7 +254,7 @@ class AttachmentsAPITestCase(test.TestCase):
|
||||
def test_list_attachments_with_sort(self, sort_dir):
|
||||
url = '/v3/%s/attachments?sort_key=id&sort_dir=%s' % (fake.PROJECT_ID,
|
||||
sort_dir)
|
||||
req = fakes.HTTPRequest.blank(url, version=ATTACHMENTS_MICRO_VERSION,
|
||||
req = fakes.HTTPRequest.blank(url, version=mv.NEW_ATTACH,
|
||||
use_admin_context=True)
|
||||
res_dict = self.controller.index(req)
|
||||
|
||||
@ -280,7 +280,7 @@ class AttachmentsAPITestCase(test.TestCase):
|
||||
@ddt.unpack
|
||||
def test_list_attachment_with_tenants(self, admin, request_url, count):
|
||||
url = '/v3/%s/attachments%s' % (fake.PROJECT_ID, request_url)
|
||||
req = fakes.HTTPRequest.blank(url, version=ATTACHMENTS_MICRO_VERSION,
|
||||
req = fakes.HTTPRequest.blank(url, version=mv.NEW_ATTACH,
|
||||
use_admin_context=admin)
|
||||
res_dict = self.controller.index(req)
|
||||
|
||||
|
@ -19,6 +19,7 @@ import ddt
|
||||
import mock
|
||||
import webob
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import api_version_request as api_version
|
||||
from cinder.api.v3 import backups
|
||||
from cinder.api.views import backups as backup_view
|
||||
@ -44,7 +45,7 @@ class BackupsControllerAPITestCase(test.TestCase):
|
||||
is_admin=True)
|
||||
self.controller = backups.BackupsController()
|
||||
|
||||
def _fake_update_request(self, backup_id, version='3.9'):
|
||||
def _fake_update_request(self, backup_id, version=mv.BACKUP_UPDATE):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/backups/%s/update' %
|
||||
(fake.PROJECT_ID, backup_id))
|
||||
req.environ['cinder.context'].is_admin = True
|
||||
@ -54,7 +55,8 @@ class BackupsControllerAPITestCase(test.TestCase):
|
||||
return req
|
||||
|
||||
def test_update_wrong_version(self):
|
||||
req = self._fake_update_request(fake.BACKUP_ID, version='3.6')
|
||||
req = self._fake_update_request(
|
||||
fake.BACKUP_ID, version=mv.get_prior_version(mv.BACKUP_UPDATE))
|
||||
body = {"backup": {"name": "Updated Test Name", }}
|
||||
self.assertRaises(exception.VersionNotFoundForAPIMethod,
|
||||
self.controller.update, req, fake.BACKUP_ID,
|
||||
@ -86,7 +88,9 @@ class BackupsControllerAPITestCase(test.TestCase):
|
||||
self.controller.update,
|
||||
req, fake.BACKUP_ID, body)
|
||||
|
||||
@ddt.data('3.30', '3.31', '3.34')
|
||||
@ddt.data(mv.get_prior_version(mv.RESOURCE_FILTER),
|
||||
mv.RESOURCE_FILTER,
|
||||
mv.LIKE_FILTER)
|
||||
@mock.patch('cinder.api.common.reject_invalid_filters')
|
||||
def test_backup_list_with_general_filter(self, version, mock_update):
|
||||
url = '/v3/%s/backups' % fake.PROJECT_ID
|
||||
@ -95,13 +99,14 @@ class BackupsControllerAPITestCase(test.TestCase):
|
||||
use_admin_context=False)
|
||||
self.controller.index(req)
|
||||
|
||||
if version != '3.30':
|
||||
support_like = True if version == '3.34' else False
|
||||
if version != mv.get_prior_version(mv.RESOURCE_FILTER):
|
||||
support_like = True if version == mv.LIKE_FILTER else False
|
||||
mock_update.assert_called_once_with(req.environ['cinder.context'],
|
||||
mock.ANY, 'backup',
|
||||
support_like)
|
||||
|
||||
@ddt.data('3.36', '3.37')
|
||||
@ddt.data(mv.get_prior_version(mv.BACKUP_SORT_NAME),
|
||||
mv.BACKUP_SORT_NAME)
|
||||
def test_backup_list_with_name(self, version):
|
||||
backup1 = test_utils.create_backup(
|
||||
self.ctxt, display_name='b_test_name',
|
||||
@ -111,7 +116,7 @@ class BackupsControllerAPITestCase(test.TestCase):
|
||||
status=fields.BackupStatus.AVAILABLE)
|
||||
url = '/v3/%s/backups?sort_key=name' % fake.PROJECT_ID
|
||||
req = fakes.HTTPRequest.blank(url, version=version)
|
||||
if version == '3.36':
|
||||
if version == mv.get_prior_version(mv.BACKUP_SORT_NAME):
|
||||
self.assertRaises(exception.InvalidInput,
|
||||
self.controller.index,
|
||||
req)
|
||||
|
@ -21,6 +21,7 @@ import mock
|
||||
from oslo_utils import versionutils
|
||||
|
||||
from cinder.api import extensions
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import api_version_request as api_version
|
||||
from cinder.api.v3 import clusters
|
||||
from cinder import context
|
||||
@ -78,7 +79,7 @@ EXPECTED = [{'created_at': datetime.datetime(2016, 6, 1, 2, 46, 28),
|
||||
|
||||
|
||||
class FakeRequest(object):
|
||||
def __init__(self, is_admin=True, version='3.7', **kwargs):
|
||||
def __init__(self, is_admin=True, version=mv.CLUSTER_SUPPORT, **kwargs):
|
||||
self.GET = kwargs
|
||||
self.headers = {'OpenStack-API-Version': 'volume ' + version}
|
||||
self.api_version_request = api_version.APIVersionRequest(version)
|
||||
@ -108,8 +109,10 @@ class ClustersTestCase(test.TestCase):
|
||||
REPLICATION_FILTERS = ({'replication_status': 'error'}, {'frozen': True},
|
||||
{'active_backend_id': 'replication'})
|
||||
|
||||
def _get_expected(self, version='3.8'):
|
||||
if versionutils.convert_version_to_tuple(version) >= (3, 19):
|
||||
def _get_expected(self,
|
||||
version=mv.get_prior_version(mv.REPLICATION_CLUSTER)):
|
||||
if (versionutils.convert_version_to_tuple(version) >=
|
||||
versionutils.convert_version_to_tuple(mv.REPLICATION_CLUSTER)):
|
||||
return EXPECTED
|
||||
|
||||
expect = []
|
||||
@ -130,7 +133,7 @@ class ClustersTestCase(test.TestCase):
|
||||
|
||||
@mock.patch('cinder.db.cluster_get_all', return_value=CLUSTERS_ORM)
|
||||
def _test_list(self, get_all_mock, detailed, filters=None, expected=None,
|
||||
version='3.8'):
|
||||
version=mv.get_prior_version(mv.REPLICATION_CLUSTER)):
|
||||
filters = filters or {}
|
||||
req = FakeRequest(version=version, **filters)
|
||||
method = getattr(self.controller, 'detail' if detailed else 'index')
|
||||
@ -187,14 +190,13 @@ class ClustersTestCase(test.TestCase):
|
||||
"""Verify the wrong version so that user can't list clusters."""
|
||||
self.assertRaises(exception.VersionNotFoundForAPIMethod,
|
||||
self._test_list, detailed=detailed,
|
||||
version='3.6')
|
||||
version=mv.get_prior_version(mv.CLUSTER_SUPPORT))
|
||||
|
||||
@ddt.data(*REPLICATION_FILTERS)
|
||||
def test_index_detail_replication_new_fields(self, filters):
|
||||
version = '3.26'
|
||||
expected = {'clusters': self._get_expected(version)}
|
||||
expected = {'clusters': self._get_expected(mv.REPLICATION_CLUSTER)}
|
||||
self._test_list(detailed=True, filters=filters, expected=expected,
|
||||
version=version)
|
||||
version=mv.REPLICATION_CLUSTER)
|
||||
|
||||
@ddt.data(*REPLICATION_FILTERS)
|
||||
def test_index_summary_replication_new_fields(self, filters):
|
||||
@ -209,7 +211,7 @@ class ClustersTestCase(test.TestCase):
|
||||
'replication_status': 'error',
|
||||
'status': 'disabled'}]}
|
||||
self._test_list(detailed=False, filters=filters, expected=expected,
|
||||
version='3.26')
|
||||
version=mv.REPLICATION_CLUSTER)
|
||||
|
||||
@mock.patch('cinder.db.sqlalchemy.api.cluster_get',
|
||||
return_value=CLUSTERS_ORM[0])
|
||||
@ -232,7 +234,7 @@ class ClustersTestCase(test.TestCase):
|
||||
self.controller.show, req, 'name')
|
||||
|
||||
def test_show_wrong_version(self):
|
||||
req = FakeRequest(version='3.5')
|
||||
req = FakeRequest(version=mv.get_prior_version(mv.CLUSTER_SUPPORT))
|
||||
self.assertRaises(exception.VersionNotFoundForAPIMethod,
|
||||
self.controller.show, req, 'name')
|
||||
|
||||
@ -307,6 +309,6 @@ class ClustersTestCase(test.TestCase):
|
||||
|
||||
@ddt.data('enable', 'disable')
|
||||
def test_update_wrong_version(self, action):
|
||||
req = FakeRequest(version='3.5')
|
||||
req = FakeRequest(version=mv.get_prior_version(mv.CLUSTER_SUPPORT))
|
||||
self.assertRaises(exception.VersionNotFoundForAPIMethod,
|
||||
self.controller.update, req, action, {})
|
||||
|
@ -15,6 +15,7 @@ import ddt
|
||||
from six.moves import http_client
|
||||
import webob
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import api_version_request as api_version
|
||||
from cinder.api.v3 import consistencygroups
|
||||
from cinder import context
|
||||
@ -72,9 +73,10 @@ class ConsistencyGroupsAPITestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/consistencygroups/%s/update' %
|
||||
(fake.PROJECT_ID, consistencygroup.id))
|
||||
req.environ['cinder.context'].is_admin = True
|
||||
req.headers = mv.get_mv_header(mv.CG_UPDATE_BLANK_PROPERTIES)
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.headers['OpenStack-API-Version'] = 'volume 3.6'
|
||||
req.api_version_request = api_version.APIVersionRequest('3.6')
|
||||
req.api_version_request = mv.get_api_version(
|
||||
mv.CG_UPDATE_BLANK_PROPERTIES)
|
||||
body = {"consistencygroup": {"name": "",
|
||||
"description": "",
|
||||
"add_volumes": None,
|
||||
@ -118,9 +120,10 @@ class ConsistencyGroupsAPITestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/consistencygroups/%s/update' %
|
||||
(fake.PROJECT_ID, consistencygroup.id))
|
||||
req.environ['cinder.context'].is_admin = True
|
||||
req.headers = mv.get_mv_header(mv.CG_UPDATE_BLANK_PROPERTIES)
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.headers['OpenStack-API-Version'] = 'volume 3.6'
|
||||
req.api_version_request = api_version.APIVersionRequest('3.6')
|
||||
req.api_version_request = mv.get_api_version(
|
||||
mv.CG_UPDATE_BLANK_PROPERTIES)
|
||||
body = {"consistencygroup": {"name": None,
|
||||
"description": None,
|
||||
"add_volumes": None,
|
||||
@ -132,16 +135,20 @@ class ConsistencyGroupsAPITestCase(test.TestCase):
|
||||
req, consistencygroup.id, body)
|
||||
consistencygroup.destroy()
|
||||
|
||||
def test_update_consistencygroup_all_empty_parameters_not_version_36(self):
|
||||
def test_update_consistencygroup_all_empty_parameters_not_version_ok(self):
|
||||
consistencygroup = self._create_consistencygroup(
|
||||
ctxt=self.ctxt,
|
||||
status=fields.ConsistencyGroupStatus.AVAILABLE)
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/consistencygroups/%s/update' %
|
||||
(fake.PROJECT_ID, consistencygroup.id))
|
||||
req.environ['cinder.context'].is_admin = True
|
||||
|
||||
non_supported_version = mv.get_prior_version(
|
||||
mv.CG_UPDATE_BLANK_PROPERTIES)
|
||||
req.headers = mv.get_mv_header(non_supported_version)
|
||||
req.api_version_request = mv.get_api_version(non_supported_version)
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.headers['OpenStack-API-Version'] = 'volume 3.5'
|
||||
req.api_version_request = api_version.APIVersionRequest('3.5')
|
||||
|
||||
body = {"consistencygroup": {"name": None,
|
||||
"description": None,
|
||||
"add_volumes": None,
|
||||
@ -160,9 +167,13 @@ class ConsistencyGroupsAPITestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/consistencygroups/%s/update' %
|
||||
(fake.PROJECT_ID, consistencygroup.id))
|
||||
req.environ['cinder.context'].is_admin = True
|
||||
|
||||
non_supported_version = mv.get_prior_version(
|
||||
mv.CG_UPDATE_BLANK_PROPERTIES)
|
||||
req.headers = mv.get_mv_header(non_supported_version)
|
||||
req.api_version_request = mv.get_api_version(non_supported_version)
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.headers['OpenStack-API-Version'] = 'volume 3.5'
|
||||
req.api_version_request = api_version.APIVersionRequest('3.5')
|
||||
|
||||
body = None
|
||||
self.assertRaisesRegexp(webob.exc.HTTPBadRequest,
|
||||
"Missing request body",
|
||||
@ -177,9 +188,13 @@ class ConsistencyGroupsAPITestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/consistencygroups/%s/update' %
|
||||
(fake.PROJECT_ID, consistencygroup.id))
|
||||
req.environ['cinder.context'].is_admin = True
|
||||
|
||||
non_supported_version = mv.get_prior_version(
|
||||
mv.CG_UPDATE_BLANK_PROPERTIES)
|
||||
req.headers = mv.get_mv_header(non_supported_version)
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.headers['OpenStack-API-Version'] = 'volume 3.5'
|
||||
req.api_version_request = api_version.APIVersionRequest('3.5')
|
||||
|
||||
req.api_version_request = mv.get_api_version(non_supported_version)
|
||||
body = {"consistencygroup": {"name": "my_fake_cg",
|
||||
"description": "fake consistency group",
|
||||
"add_volumes": "volume-uuid-1",
|
||||
|
@ -22,6 +22,7 @@ import mock
|
||||
from six.moves import http_client
|
||||
import webob
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.v3 import group_snapshots as v3_group_snapshots
|
||||
from cinder import context
|
||||
from cinder import db
|
||||
@ -35,9 +36,6 @@ from cinder.tests.unit import fake_constants as fake
|
||||
from cinder.tests.unit import utils
|
||||
import cinder.volume
|
||||
|
||||
GROUP_MICRO_VERSION = '3.14'
|
||||
SUPPORT_FILTER_VERSION = '3.29'
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
@ -76,7 +74,7 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
self.context, group_id=self.group.id)
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots/%s' %
|
||||
(fake.PROJECT_ID, group_snapshot.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_SNAPSHOTS)
|
||||
res_dict = self.controller.show(req, group_snapshot.id)
|
||||
|
||||
self.assertEqual(1, len(res_dict))
|
||||
@ -95,7 +93,8 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
url = '/v3/%s/group_snapshots?limit=1' % fake.PROJECT_ID
|
||||
if is_detail:
|
||||
url = '/v3/%s/group_snapshots/detail?limit=1' % fake.PROJECT_ID
|
||||
req = fakes.HTTPRequest.blank(url, version=SUPPORT_FILTER_VERSION)
|
||||
req = fakes.HTTPRequest.blank(url,
|
||||
version=mv.GROUP_SNAPSHOT_PAGINATION)
|
||||
if is_detail:
|
||||
res_dict = self.controller.detail(req)
|
||||
else:
|
||||
@ -122,7 +121,8 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
url = '/v3/%s/group_snapshots?offset=1' % fake.PROJECT_ID
|
||||
if is_detail:
|
||||
url = '/v3/%s/group_snapshots/detail?offset=1' % fake.PROJECT_ID
|
||||
req = fakes.HTTPRequest.blank(url, version=SUPPORT_FILTER_VERSION)
|
||||
req = fakes.HTTPRequest.blank(url,
|
||||
version=mv.GROUP_SNAPSHOT_PAGINATION)
|
||||
if is_detail:
|
||||
res_dict = self.controller.detail(req)
|
||||
else:
|
||||
@ -146,7 +146,8 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
if is_detail:
|
||||
url = ('/v3/%s/group_snapshots/detail?offset=234523423455454' %
|
||||
fake.PROJECT_ID)
|
||||
req = fakes.HTTPRequest.blank(url, version=SUPPORT_FILTER_VERSION)
|
||||
req = fakes.HTTPRequest.blank(url,
|
||||
version=mv.GROUP_SNAPSHOT_PAGINATION)
|
||||
if is_detail:
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.detail,
|
||||
req)
|
||||
@ -164,7 +165,8 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
if is_detail:
|
||||
url = ('/v3/%s/group_snapshots/detail?limit=2&offset=1' %
|
||||
fake.PROJECT_ID)
|
||||
req = fakes.HTTPRequest.blank(url, version=SUPPORT_FILTER_VERSION)
|
||||
req = fakes.HTTPRequest.blank(url,
|
||||
version=mv.GROUP_SNAPSHOT_PAGINATION)
|
||||
if is_detail:
|
||||
res_dict = self.controller.detail(req)
|
||||
else:
|
||||
@ -184,7 +186,9 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
res_dict['group_snapshots'][0].keys())
|
||||
group_snapshot.destroy()
|
||||
|
||||
@ddt.data('3.30', '3.31', '3.34')
|
||||
@ddt.data(mv.get_prior_version(mv.RESOURCE_FILTER),
|
||||
mv.RESOURCE_FILTER,
|
||||
mv.LIKE_FILTER)
|
||||
@mock.patch('cinder.api.common.reject_invalid_filters')
|
||||
def test_group_snapshot_list_with_general_filter(self,
|
||||
version, mock_update):
|
||||
@ -194,8 +198,8 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
use_admin_context=False)
|
||||
self.controller.index(req)
|
||||
|
||||
if version != '3.30':
|
||||
support_like = True if version == '3.34' else False
|
||||
if version != mv.get_prior_version(mv.RESOURCE_FILTER):
|
||||
support_like = True if version == mv.LIKE_FILTER else False
|
||||
mock_update.assert_called_once_with(req.environ['cinder.context'],
|
||||
mock.ANY, 'group_snapshot',
|
||||
support_like)
|
||||
@ -209,7 +213,8 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
url = ('/v3/%s/group_snapshots/detail?'
|
||||
'all_tenants=True&id=%s') % (fake.PROJECT_ID,
|
||||
self.g_snapshots_array[0].id)
|
||||
req = fakes.HTTPRequest.blank(url, version=SUPPORT_FILTER_VERSION,
|
||||
req = fakes.HTTPRequest.blank(url,
|
||||
version=mv.GROUP_SNAPSHOT_PAGINATION,
|
||||
use_admin_context=True)
|
||||
if is_detail:
|
||||
res_dict = self.controller.detail(req)
|
||||
@ -226,10 +231,10 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
self.assertNotIn('description',
|
||||
res_dict['group_snapshots'][0].keys())
|
||||
|
||||
@ddt.data({'is_detail': True, 'version': GROUP_MICRO_VERSION},
|
||||
{'is_detail': False, 'version': GROUP_MICRO_VERSION},
|
||||
{'is_detail': True, 'version': '3.28'},
|
||||
{'is_detail': False, 'version': '3.28'},)
|
||||
@ddt.data({'is_detail': True, 'version': mv.GROUP_SNAPSHOTS},
|
||||
{'is_detail': False, 'version': mv.GROUP_SNAPSHOTS},
|
||||
{'is_detail': True, 'version': mv.POOL_FILTER},
|
||||
{'is_detail': False, 'version': mv.POOL_FILTER},)
|
||||
@ddt.unpack
|
||||
def test_list_group_snapshot_with_filter_previous_version(self, is_detail,
|
||||
version):
|
||||
@ -257,7 +262,8 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
if is_detail:
|
||||
url = ('/v3/%s/group_snapshots/detail?sort=id:asc' %
|
||||
fake.PROJECT_ID)
|
||||
req = fakes.HTTPRequest.blank(url, version=SUPPORT_FILTER_VERSION)
|
||||
req = fakes.HTTPRequest.blank(url,
|
||||
version=mv.GROUP_SNAPSHOT_PAGINATION)
|
||||
expect_result = [snapshot.id for snapshot in self.g_snapshots_array]
|
||||
expect_result.sort()
|
||||
if is_detail:
|
||||
@ -282,7 +288,7 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots/%s' %
|
||||
(fake.PROJECT_ID,
|
||||
fake.WILL_NOT_BE_FOUND_ID),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_SNAPSHOTS)
|
||||
self.assertRaises(exception.GroupSnapshotNotFound,
|
||||
self.controller.show,
|
||||
req, fake.WILL_NOT_BE_FOUND_ID)
|
||||
@ -294,7 +300,7 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
else:
|
||||
request_url = '/v3/%s/group_snapshots'
|
||||
req = fakes.HTTPRequest.blank(request_url % fake.PROJECT_ID,
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_SNAPSHOTS)
|
||||
if is_detail:
|
||||
res_dict = self.controller.detail(req)
|
||||
else:
|
||||
@ -326,7 +332,7 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
"group_id": self.group.id}}
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots' %
|
||||
fake.PROJECT_ID,
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_SNAPSHOTS)
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
self.assertEqual(1, len(res_dict))
|
||||
@ -356,7 +362,7 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
"group_id": group.id}}
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots' %
|
||||
fake.PROJECT_ID,
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_SNAPSHOTS)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, body)
|
||||
self.assertTrue(mock_validate.called)
|
||||
@ -369,7 +375,7 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
# omit body from the request
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots' %
|
||||
fake.PROJECT_ID,
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_SNAPSHOTS)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, None)
|
||||
|
||||
@ -383,7 +389,7 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
"group_id": self.group.id}}
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots' %
|
||||
fake.PROJECT_ID,
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_SNAPSHOTS)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, body)
|
||||
|
||||
@ -397,7 +403,7 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
"group_id": self.group.id}}
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots' %
|
||||
fake.PROJECT_ID,
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_SNAPSHOTS)
|
||||
self.assertRaises(exception.GroupSnapshotNotFound,
|
||||
self.controller.create,
|
||||
req, body)
|
||||
@ -413,7 +419,7 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
"group_id": empty_group.id}}
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots' %
|
||||
fake.PROJECT_ID,
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_SNAPSHOTS)
|
||||
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, body)
|
||||
@ -426,7 +432,7 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
status=fields.GroupSnapshotStatus.AVAILABLE)
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots/%s' %
|
||||
(fake.PROJECT_ID, group_snapshot.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_SNAPSHOTS)
|
||||
res_dict = self.controller.delete(req, group_snapshot.id)
|
||||
|
||||
group_snapshot = objects.GroupSnapshot.get_by_id(self.context,
|
||||
@ -450,7 +456,7 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
volume_type_ids=[fake.VOLUME_TYPE_ID],)
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots/%s' %
|
||||
(fake.PROJECT_ID, group_snapshot.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_SNAPSHOTS)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.delete,
|
||||
req, group_snapshot.id)
|
||||
|
||||
@ -461,7 +467,7 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots/%s' %
|
||||
(fake.PROJECT_ID,
|
||||
fake.WILL_NOT_BE_FOUND_ID),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_SNAPSHOTS)
|
||||
self.assertRaises(exception.GroupSnapshotNotFound,
|
||||
self.controller.delete,
|
||||
req, fake.WILL_NOT_BE_FOUND_ID)
|
||||
@ -473,19 +479,20 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
status='invalid')
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots/%s' %
|
||||
(fake.PROJECT_ID, group_snapshot.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_SNAPSHOTS)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.delete,
|
||||
req, group_snapshot.id)
|
||||
|
||||
group_snapshot.destroy()
|
||||
|
||||
@ddt.data(('3.11', 'fake_snapshot_001',
|
||||
@ddt.data((mv.GROUP_TYPE, 'fake_snapshot_001',
|
||||
fields.GroupSnapshotStatus.AVAILABLE,
|
||||
exception.VersionNotFoundForAPIMethod),
|
||||
('3.18', 'fake_snapshot_001',
|
||||
(mv.get_prior_version(mv.GROUP_SNAPSHOT_RESET_STATUS),
|
||||
'fake_snapshot_001',
|
||||
fields.GroupSnapshotStatus.AVAILABLE,
|
||||
exception.VersionNotFoundForAPIMethod),
|
||||
('3.19', 'fake_snapshot_001',
|
||||
(mv.GROUP_SNAPSHOT_RESET_STATUS, 'fake_snapshot_001',
|
||||
fields.GroupSnapshotStatus.AVAILABLE,
|
||||
exception.GroupSnapshotNotFound))
|
||||
@ddt.unpack
|
||||
@ -509,7 +516,7 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
status=fields.GroupSnapshotStatus.CREATING)
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots/%s/action' %
|
||||
(fake.PROJECT_ID, group_snapshot.id),
|
||||
version='3.19')
|
||||
version=mv.GROUP_SNAPSHOT_RESET_STATUS)
|
||||
body = {"reset_status": {
|
||||
"status": "invalid_test_status"
|
||||
}}
|
||||
@ -525,7 +532,7 @@ class GroupSnapshotsAPITestCase(test.TestCase):
|
||||
status=fields.GroupSnapshotStatus.CREATING)
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_snapshots/%s/action' %
|
||||
(fake.PROJECT_ID, group_snapshot.id),
|
||||
version='3.19')
|
||||
version=mv.GROUP_SNAPSHOT_RESET_STATUS)
|
||||
body = {"reset_status": {
|
||||
"status": fields.GroupSnapshotStatus.AVAILABLE
|
||||
}}
|
||||
|
@ -21,12 +21,11 @@ from cinder import db
|
||||
from cinder import rpc
|
||||
from cinder import test
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.v3 import group_specs as v3_group_specs
|
||||
from cinder.tests.unit.api import fakes
|
||||
from cinder.tests.unit import fake_constants as fake
|
||||
|
||||
GROUP_TYPE_MICRO_VERSION = '3.11'
|
||||
|
||||
fake_group_specs = {
|
||||
'key1': 'value1',
|
||||
'key2': 'value2'
|
||||
@ -71,7 +70,7 @@ class GroupSpecsTestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('v3/%s/group_specs' %
|
||||
fake.PROJECT_ID,
|
||||
use_admin_context=True,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
res_dict = self.controller.index(req, fake.GROUP_ID)
|
||||
group_specs_dict = res_dict['group_specs']
|
||||
@ -90,7 +89,7 @@ class GroupSpecsTestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('v3/%s/group_specs' %
|
||||
fake.PROJECT_ID,
|
||||
use_admin_context=True,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
self.controller.create(req, fake.GROUP_ID, create_fake_group_specs)
|
||||
self.assertTrue(mock_rpc_notifier.called)
|
||||
|
||||
@ -108,7 +107,7 @@ class GroupSpecsTestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('v3/%s/group_specs' %
|
||||
fake.PROJECT_ID,
|
||||
use_admin_context=True,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
self.controller.update(req,
|
||||
fake.GROUP_TYPE_ID,
|
||||
'id',
|
||||
@ -124,7 +123,7 @@ class GroupSpecsTestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('v3/%s/group_specs' %
|
||||
fake.PROJECT_ID,
|
||||
use_admin_context=True,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
res_dict = self.controller.show(req, fake.GROUP_TYPE_ID, 'key1')
|
||||
self.assertEqual('value1', res_dict['key1'])
|
||||
|
||||
@ -138,7 +137,7 @@ class GroupSpecsTestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('v3/%s/group_specs' %
|
||||
fake.PROJECT_ID,
|
||||
use_admin_context=True,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
self.controller.delete(req, fake.GROUP_TYPE_ID, 'key1')
|
||||
self.assertTrue(rpc_notifier_mock.called)
|
||||
|
||||
@ -151,7 +150,7 @@ class GroupSpecsTestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('v3/%s/group_specs' %
|
||||
fake.PROJECT_ID,
|
||||
use_admin_context=True,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.create,
|
||||
req,
|
||||
@ -166,7 +165,7 @@ class GroupSpecsTestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('v3/%s/group_specs' %
|
||||
fake.PROJECT_ID,
|
||||
use_admin_context=True,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.delete,
|
||||
req,
|
||||
@ -178,7 +177,7 @@ class GroupSpecsTestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('v3/%s/group_specs' %
|
||||
fake.PROJECT_ID,
|
||||
use_admin_context=True,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.update,
|
||||
req,
|
||||
@ -198,7 +197,7 @@ class GroupSpecsTestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('v3/%s/group_specs' %
|
||||
fake.PROJECT_ID,
|
||||
use_admin_context=True,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
self.controller.show,
|
||||
req,
|
||||
@ -216,6 +215,6 @@ class GroupSpecsTestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('v3/%s/group_specs' %
|
||||
fake.PROJECT_ID,
|
||||
use_admin_context=True,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, fake.GROUP_ID, incorrect_fake_group_specs)
|
||||
|
@ -23,6 +23,7 @@ import six
|
||||
import webob
|
||||
|
||||
import cinder.api.common as common
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.v3 import group_specs as v3_group_specs
|
||||
from cinder.api.v3 import group_types as v3_group_types
|
||||
from cinder.api.v3.views import group_types as views_types
|
||||
@ -33,7 +34,6 @@ from cinder.tests.unit.api import fakes
|
||||
from cinder.tests.unit import fake_constants as fake
|
||||
from cinder.volume import group_types
|
||||
|
||||
GROUP_TYPE_MICRO_VERSION = '3.11'
|
||||
IN_USE_GROUP_TYPE = fake.GROUP_TYPE3_ID
|
||||
|
||||
|
||||
@ -132,7 +132,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
mock_create, mock_get):
|
||||
boolean_is_public = strutils.bool_from_string(is_public)
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/types' % fake.PROJECT_ID,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
|
||||
body = {"group_type": {"is_public": is_public, "name": "group_type1",
|
||||
@ -157,7 +157,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
'_notify_group_type_error')
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_types/%s' % (
|
||||
fake.PROJECT_ID, grp_type_id),
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
if grp_type_id == IN_USE_GROUP_TYPE:
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
@ -177,7 +177,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_types' % fake.PROJECT_ID,
|
||||
use_admin_context=True,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
res_dict = self.controller.index(req)
|
||||
|
||||
self.assertEqual(3, len(res_dict['group_types']))
|
||||
@ -193,7 +193,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
return_empty_group_types_get_all_types)
|
||||
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_types' % fake.PROJECT_ID,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
res_dict = self.controller.index(req)
|
||||
|
||||
self.assertEqual(0, len(res_dict['group_types']))
|
||||
@ -201,7 +201,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
def test_group_types_index_with_limit(self):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_types?limit=1' %
|
||||
fake.PROJECT_ID,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
res = self.controller.index(req)
|
||||
|
||||
@ -216,7 +216,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
def test_group_types_index_with_offset(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v3/%s/group_types?offset=1' % fake.PROJECT_ID,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
res = self.controller.index(req)
|
||||
|
||||
@ -224,14 +224,14 @@ class GroupTypesApiTest(test.TestCase):
|
||||
|
||||
def test_group_types_index_with_offset_out_of_range(self):
|
||||
url = '/v3/%s/group_types?offset=424366766556787' % fake.PROJECT_ID
|
||||
req = fakes.HTTPRequest.blank(url, version=GROUP_TYPE_MICRO_VERSION)
|
||||
req = fakes.HTTPRequest.blank(url, version=mv.GROUP_TYPE)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.index, req)
|
||||
|
||||
def test_group_types_index_with_limit_and_offset(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v3/%s/group_types?limit=2&offset=1' % fake.PROJECT_ID,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
res = self.controller.index(req)
|
||||
|
||||
@ -244,7 +244,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
'&marker=%s' %
|
||||
(fake.PROJECT_ID,
|
||||
self.type_id2),
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
res = self.controller.index(req)
|
||||
|
||||
@ -254,7 +254,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
def test_group_types_index_with_valid_filter(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v3/%s/group_types?is_public=True' % fake.PROJECT_ID,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
res = self.controller.index(req)
|
||||
|
||||
@ -267,7 +267,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
def test_group_types_index_with_invalid_filter(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v3/%s/group_types?id=%s' % (fake.PROJECT_ID, self.type_id1),
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
res = self.controller.index(req)
|
||||
|
||||
@ -276,7 +276,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
def test_group_types_index_with_sort_keys(self):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_types?sort=id' %
|
||||
fake.PROJECT_ID,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
res = self.controller.index(req)
|
||||
expect_result = [self.type_id0, self.type_id1, self.type_id2,
|
||||
@ -292,7 +292,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
def test_group_types_index_with_sort_and_limit(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v3/%s/group_types?sort=id&limit=2' % fake.PROJECT_ID,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
res = self.controller.index(req)
|
||||
expect_result = [self.type_id0, self.type_id1, self.type_id2,
|
||||
@ -306,7 +306,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
def test_group_types_index_with_sort_keys_and_sort_dirs(self):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v3/%s/group_types?sort=id:asc' % fake.PROJECT_ID,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
res = self.controller.index(req)
|
||||
expect_result = [self.type_id0, self.type_id1, self.type_id2,
|
||||
@ -332,7 +332,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
type_id = six.text_type(uuid.uuid4())
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v3/%s/types/%s' % (fake.PROJECT_ID, type_id),
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
body = {"group_type": {"is_public": is_public, "name": "group_type1"}}
|
||||
self.controller.update(req, type_id, body)
|
||||
@ -347,7 +347,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
type_id = six.text_type(uuid.uuid4())
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_types/' % fake.PROJECT_ID
|
||||
+ type_id,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
res_dict = self.controller.show(req, type_id)
|
||||
|
||||
self.assertEqual(1, len(res_dict))
|
||||
@ -359,10 +359,10 @@ class GroupTypesApiTest(test.TestCase):
|
||||
self.mock_object(group_types, 'get_group_type',
|
||||
return_group_types_get_group_type)
|
||||
|
||||
type_id = six.text_type(uuid.uuid4())
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_types/' % fake.PROJECT_ID
|
||||
+ type_id,
|
||||
version='3.5')
|
||||
type_id = uuid.uuid4()
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v3/%s/group_types/%s' % (fake.PROJECT_ID, type_id),
|
||||
version=mv.get_prior_version(mv.GROUP_TYPE))
|
||||
|
||||
self.assertRaises(exception.VersionNotFoundForAPIMethod,
|
||||
self.controller.show, req, type_id)
|
||||
@ -374,7 +374,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_types/%s' %
|
||||
(fake.PROJECT_ID,
|
||||
fake.WILL_NOT_BE_FOUND_ID),
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
self.assertRaises(webob.exc.HTTPNotFound, self.controller.show,
|
||||
req, fake.WILL_NOT_BE_FOUND_ID)
|
||||
|
||||
@ -383,7 +383,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
return_group_types_get_default)
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_types/default' %
|
||||
fake.PROJECT_ID,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
req.method = 'GET'
|
||||
res_dict = self.controller.show(req, 'default')
|
||||
self.assertEqual(1, len(res_dict))
|
||||
@ -396,7 +396,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
return_group_types_get_default_not_found)
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/group_types/default' %
|
||||
fake.PROJECT_ID,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
req.method = 'GET'
|
||||
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
@ -419,7 +419,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
)
|
||||
|
||||
request = fakes.HTTPRequest.blank("/v3",
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
output = view_builder.show(request, raw_group_type)
|
||||
|
||||
self.assertIn('group_type', output)
|
||||
@ -448,7 +448,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
)
|
||||
|
||||
request = fakes.HTTPRequest.blank("/v3", use_admin_context=True,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
output = view_builder.show(request, raw_group_type)
|
||||
|
||||
self.assertIn('group_type', output)
|
||||
@ -479,7 +479,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
)
|
||||
|
||||
request = fakes.HTTPRequest.blank("/v3",
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
output = view_builder.show(request, raw_group_type)
|
||||
|
||||
self.assertIn('group_type', output)
|
||||
@ -510,7 +510,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
)
|
||||
|
||||
request = fakes.HTTPRequest.blank("/v3",
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
output = view_builder.show(request, raw_group_type)
|
||||
|
||||
self.assertIn('group_type', output)
|
||||
@ -542,7 +542,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
)
|
||||
|
||||
request = fakes.HTTPRequest.blank("/v3",
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
output = view_builder.show(request, raw_group_type)
|
||||
|
||||
self.assertIn('group_type', output)
|
||||
@ -576,7 +576,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
)
|
||||
|
||||
request = fakes.HTTPRequest.blank("/v3",
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
output = view_builder.index(request, raw_group_types)
|
||||
|
||||
self.assertIn('group_types', output)
|
||||
@ -611,7 +611,7 @@ class GroupTypesApiTest(test.TestCase):
|
||||
)
|
||||
|
||||
request = fakes.HTTPRequest.blank("/v3", use_admin_context=True,
|
||||
version=GROUP_TYPE_MICRO_VERSION)
|
||||
version=mv.GROUP_TYPE)
|
||||
output = view_builder.index(request, raw_group_types)
|
||||
|
||||
self.assertIn('group_types', output)
|
||||
|
@ -22,6 +22,7 @@ import mock
|
||||
from six.moves import http_client
|
||||
import webob
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.v3 import groups as v3_groups
|
||||
from cinder import context
|
||||
from cinder import db
|
||||
@ -36,10 +37,7 @@ from cinder.tests.unit import fake_constants as fake
|
||||
from cinder.tests.unit import utils
|
||||
from cinder.volume import api as volume_api
|
||||
|
||||
GROUP_MICRO_VERSION = '3.13'
|
||||
GROUP_FROM_SRC_MICRO_VERSION = '3.14'
|
||||
GROUP_REPLICATION_MICRO_VERSION = '3.38'
|
||||
INVALID_GROUP_REPLICATION_MICRO_VERSION = '3.37'
|
||||
INVALID_GROUP_REPLICATION = mv.get_prior_version(mv.GROUP_REPLICATION)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@ -134,7 +132,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
res_dict = self.controller.show(req, self.group1.id)
|
||||
|
||||
self.assertEqual(1, len(res_dict))
|
||||
@ -149,7 +147,10 @@ class GroupsAPITestCase(test.TestCase):
|
||||
self.assertEqual([fake.VOLUME_TYPE_ID],
|
||||
res_dict['group']['volume_types'])
|
||||
|
||||
@ddt.data(('3.24', False), ('3.24', True), ('3.25', False), ('3.25', True))
|
||||
@ddt.data((mv.get_prior_version(mv.GROUP_VOLUME_LIST), False),
|
||||
(mv.get_prior_version(mv.GROUP_VOLUME_LIST), True),
|
||||
(mv.GROUP_VOLUME_LIST, False),
|
||||
(mv.GROUP_VOLUME_LIST, True))
|
||||
@ddt.unpack
|
||||
@mock.patch('cinder.objects.volume_type.VolumeTypeList.get_all_by_group')
|
||||
@mock.patch('cinder.objects.volume.VolumeList.get_all_by_generic_group')
|
||||
@ -181,7 +182,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
# be contained in the response body. Else, "volumes" should not be
|
||||
# contained in the response body.
|
||||
self.assertEqual(3, len(res_dict['groups']))
|
||||
if (version, has_list_volume) == ('3.25', True):
|
||||
if (version, has_list_volume) == (mv.GROUP_VOLUME_LIST, True):
|
||||
self.assertEqual([fake.VOLUME_ID],
|
||||
res_dict['groups'][0]['volumes'])
|
||||
else:
|
||||
@ -211,7 +212,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
# be contained in the response body.
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s?list_volume=True' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version='3.25')
|
||||
version=mv.GROUP_VOLUME_LIST)
|
||||
res_dict = self.controller.show(req, self.group1.id)
|
||||
self.assertEqual(1, len(res_dict))
|
||||
self.assertEqual([fake.VOLUME_ID],
|
||||
@ -221,16 +222,17 @@ class GroupsAPITestCase(test.TestCase):
|
||||
# should not be contained in the response body.
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version='3.25')
|
||||
version=mv.GROUP_VOLUME_LIST)
|
||||
res_dict = self.controller.show(req, self.group1.id)
|
||||
self.assertEqual(1, len(res_dict))
|
||||
self.assertIsNone(res_dict['group'].get('volumes', None))
|
||||
|
||||
# If the microversion < 3.25, "volumes" should not be contained in the
|
||||
# response body.
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s?list_volume=True' %
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v3/%s/groups/%s?list_volume=True' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version='3.24')
|
||||
version=mv.get_prior_version(mv.GROUP_VOLUME_LIST))
|
||||
res_dict = self.controller.show(req, self.group1.id)
|
||||
self.assertEqual(1, len(res_dict))
|
||||
self.assertIsNone(res_dict['group'].get('volumes', None))
|
||||
@ -239,11 +241,12 @@ class GroupsAPITestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s' %
|
||||
(fake.PROJECT_ID,
|
||||
fake.WILL_NOT_BE_FOUND_ID),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
self.assertRaises(exception.GroupNotFound, self.controller.show,
|
||||
req, fake.WILL_NOT_BE_FOUND_ID)
|
||||
|
||||
@ddt.data('3.30', '3.31', '3.34')
|
||||
@ddt.data(mv.get_prior_version(mv.RESOURCE_FILTER),
|
||||
mv.RESOURCE_FILTER, mv.LIKE_FILTER)
|
||||
@mock.patch('cinder.api.common.reject_invalid_filters')
|
||||
def test_group_list_with_general_filter(self, version, mock_update):
|
||||
url = '/v3/%s/groups' % fake.PROJECT_ID
|
||||
@ -252,8 +255,8 @@ class GroupsAPITestCase(test.TestCase):
|
||||
use_admin_context=False)
|
||||
self.controller.index(req)
|
||||
|
||||
if version != '3.30':
|
||||
support_like = True if version == '3.34' else False
|
||||
if version != mv.get_prior_version(mv.RESOURCE_FILTER):
|
||||
support_like = True if version == mv.LIKE_FILTER else False
|
||||
mock_update.assert_called_once_with(req.environ['cinder.context'],
|
||||
mock.ANY, 'group',
|
||||
support_like)
|
||||
@ -273,7 +276,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
self.group3.save()
|
||||
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups' % fake.PROJECT_ID,
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
res_dict = self.controller.index(req)
|
||||
|
||||
self.assertEqual(1, len(res_dict))
|
||||
@ -295,7 +298,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
url = '/v3/%s/groups?limit=1' % fake.PROJECT_ID
|
||||
if is_detail:
|
||||
url = '/v3/%s/groups/detail?limit=1' % fake.PROJECT_ID
|
||||
req = fakes.HTTPRequest.blank(url, version=GROUP_MICRO_VERSION)
|
||||
req = fakes.HTTPRequest.blank(url, version=mv.GROUP_VOLUME)
|
||||
|
||||
if is_detail:
|
||||
res_dict = self.controller.detail(req)
|
||||
@ -320,7 +323,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
url = '/v3/%s/groups?offset=1' % fake.PROJECT_ID
|
||||
if is_detail:
|
||||
url = '/v3/%s/groups/detail?offset=1' % fake.PROJECT_ID
|
||||
req = fakes.HTTPRequest.blank(url, version=GROUP_MICRO_VERSION)
|
||||
req = fakes.HTTPRequest.blank(url, version=mv.GROUP_VOLUME)
|
||||
res_dict = self.controller.index(req)
|
||||
|
||||
self.assertEqual(1, len(res_dict))
|
||||
@ -337,7 +340,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
if is_detail:
|
||||
url = ('/v3/%s/groups/detail?offset=234523423455454' %
|
||||
fake.PROJECT_ID)
|
||||
req = fakes.HTTPRequest.blank(url, version=GROUP_MICRO_VERSION)
|
||||
req = fakes.HTTPRequest.blank(url, version=mv.GROUP_VOLUME)
|
||||
if is_detail:
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.detail,
|
||||
req)
|
||||
@ -351,7 +354,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
if is_detail:
|
||||
url = ('/v3/%s/groups/detail?limit=2&offset=1' %
|
||||
fake.PROJECT_ID)
|
||||
req = fakes.HTTPRequest.blank(url, version=GROUP_MICRO_VERSION)
|
||||
req = fakes.HTTPRequest.blank(url, version=mv.GROUP_VOLUME)
|
||||
|
||||
if is_detail:
|
||||
res_dict = self.controller.detail(req)
|
||||
@ -377,7 +380,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
url = ('/v3/%s/groups/detail?'
|
||||
'all_tenants=True&id=%s') % (fake.PROJECT_ID,
|
||||
self.group3.id)
|
||||
req = fakes.HTTPRequest.blank(url, version=GROUP_MICRO_VERSION,
|
||||
req = fakes.HTTPRequest.blank(url, version=mv.GROUP_VOLUME,
|
||||
use_admin_context=True)
|
||||
|
||||
if is_detail:
|
||||
@ -398,7 +401,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
if is_detail:
|
||||
url = ('/v3/%s/groups/detail?sort=id:asc' %
|
||||
fake.PROJECT_ID)
|
||||
req = fakes.HTTPRequest.blank(url, version=GROUP_MICRO_VERSION)
|
||||
req = fakes.HTTPRequest.blank(url, version=mv.GROUP_VOLUME)
|
||||
expect_result = [self.group1.id, self.group2.id,
|
||||
self.group3.id]
|
||||
expect_result.sort()
|
||||
@ -438,7 +441,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
# self.group3.save()
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/detail' %
|
||||
fake.PROJECT_ID,
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
res_dict = self.controller.detail(req)
|
||||
|
||||
self.assertEqual(1, len(res_dict))
|
||||
@ -476,7 +479,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
"description":
|
||||
"Group 1", }}
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups' % fake.PROJECT_ID,
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
self.assertEqual(1, len(res_dict))
|
||||
@ -489,7 +492,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
def test_create_group_with_no_body(self):
|
||||
# omit body from the request
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups' % fake.PROJECT_ID,
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, None)
|
||||
|
||||
@ -498,7 +501,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
self.group1.save()
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
body = {"delete": {"delete-volumes": False}}
|
||||
res_dict = self.controller.delete_group(
|
||||
req, self.group1.id, body)
|
||||
@ -513,7 +516,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
self.group1.save()
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
body = {"delete": {"delete-volumes": False}}
|
||||
res_dict = self.controller.delete_group(
|
||||
req, self.group1.id, body)
|
||||
@ -528,7 +531,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID,
|
||||
fake.WILL_NOT_BE_FOUND_ID),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
body = {"delete": {"delete-volumes": False}}
|
||||
self.assertRaises(exception.GroupNotFound,
|
||||
self.controller.delete_group,
|
||||
@ -538,7 +541,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID,
|
||||
self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
body = {"delete": {"delete-volumes": False}}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.delete_group,
|
||||
@ -548,7 +551,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID,
|
||||
self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
body = {"delete": {"delete-volumes": True}}
|
||||
res_dict = self.controller.delete_group(
|
||||
req, self.group1.id, body)
|
||||
@ -565,7 +568,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID,
|
||||
self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
body = {"delete": {"delete-volumes": True}}
|
||||
res_dict = self.controller.delete_group(
|
||||
req, self.group1.id, body)
|
||||
@ -620,7 +623,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
"description":
|
||||
"Group 1", }}
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups' % fake.PROJECT_ID,
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
ex = self.assertRaises(exception.GroupLimitExceeded,
|
||||
self.controller.create,
|
||||
req, body)
|
||||
@ -631,7 +634,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
self.group1.save()
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
body = {"invalid_request_element": {"delete-volumes": False}}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.delete_group,
|
||||
@ -642,7 +645,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
self.group1.save()
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
body = {"delete": {"delete-volumes": "abcd"}}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.delete_group,
|
||||
@ -653,7 +656,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
self.group1.save()
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
body = {"delete": {"delete-volumes": ""}}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.delete_group,
|
||||
@ -666,7 +669,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
body = {"delete": {"delete-volumes": True}}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.delete_group,
|
||||
@ -688,7 +691,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
vol = utils.create_volume(self.ctxt, group_id=self.group1.id)
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
body = {"delete": {"delete-volumes": True}}
|
||||
res_dict = self.controller.delete_group(
|
||||
req, self.group1.id, body)
|
||||
@ -707,7 +710,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
attach_status='attached')
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
body = {"delete": {"delete-volumes": True}}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.delete_group,
|
||||
@ -722,7 +725,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
utils.create_snapshot(self.ctxt, vol.id)
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
body = {"delete": {"delete-volumes": True}}
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.delete_group,
|
||||
@ -739,7 +742,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
deleted=True)
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
body = {"delete": {"delete-volumes": True}}
|
||||
res_dict = self.controller.delete_group(
|
||||
req, self.group1.id, body)
|
||||
@ -758,7 +761,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
"description":
|
||||
"Group 1", }}
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups' % fake.PROJECT_ID,
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.create,
|
||||
req, body)
|
||||
@ -770,7 +773,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
"description":
|
||||
"Group 1", }}
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups' % fake.PROJECT_ID,
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
self.assertRaises(webob.exc.HTTPBadRequest,
|
||||
self.controller.create,
|
||||
req, body)
|
||||
@ -820,7 +823,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
volume_type_id=volume_type_id)
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/update' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
name = 'newgroup'
|
||||
description = 'New Group Description'
|
||||
add_volumes = add_volume.id + "," + add_volume2.id
|
||||
@ -851,7 +854,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
self.group1.status = status
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/update' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
body = {"group": {"name": "new name",
|
||||
"description": "new description",
|
||||
"add_volumes": None,
|
||||
@ -870,7 +873,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
self.group1.save()
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/update' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
body = {"group": {"name": None,
|
||||
"description": None,
|
||||
"add_volumes": "fake-volume-uuid",
|
||||
@ -885,7 +888,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
self.group1.save()
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/update' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
body = {"group": {"name": None,
|
||||
"description": "new description",
|
||||
"add_volumes": None,
|
||||
@ -900,7 +903,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
self.group1.save()
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/update' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
body = {"group": {"name": None,
|
||||
"description": None,
|
||||
"add_volumes": None,
|
||||
@ -919,7 +922,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
status='wrong_status')
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/update' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
add_volumes = add_volume.id
|
||||
body = {"group": {"name": "group1",
|
||||
"description": "",
|
||||
@ -941,7 +944,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
volume_type_id=wrong_type)
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/update' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
add_volumes = add_volume.id
|
||||
body = {"group": {"name": "group1",
|
||||
"description": "",
|
||||
@ -962,7 +965,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
group_id=fake.GROUP2_ID)
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/update' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
add_volumes = add_volume.id
|
||||
body = {"group": {"name": "group1",
|
||||
"description": "",
|
||||
@ -984,7 +987,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
host=self.group1.host)
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/update' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version=GROUP_MICRO_VERSION)
|
||||
version=mv.GROUP_VOLUME)
|
||||
|
||||
body = {"group": {"name": "new name",
|
||||
"description": None,
|
||||
@ -999,16 +1002,16 @@ class GroupsAPITestCase(test.TestCase):
|
||||
self.assertEqual(add_volume.status, vol.status)
|
||||
add_volume.destroy()
|
||||
|
||||
@ddt.data(('3.11', 'fake_group_001',
|
||||
@ddt.data((mv.GROUP_TYPE, 'fake_group_001',
|
||||
fields.GroupStatus.AVAILABLE,
|
||||
exception.VersionNotFoundForAPIMethod),
|
||||
('3.19', 'fake_group_001',
|
||||
(mv.GROUP_SNAPSHOT_RESET_STATUS, 'fake_group_001',
|
||||
fields.GroupStatus.AVAILABLE,
|
||||
exception.VersionNotFoundForAPIMethod),
|
||||
('3.20', 'fake_group_001',
|
||||
(mv.GROUP_VOLUME_RESET_STATUS, 'fake_group_001',
|
||||
fields.GroupStatus.AVAILABLE,
|
||||
exception.GroupNotFound),
|
||||
('3.20', None,
|
||||
(mv.GROUP_VOLUME_RESET_STATUS, None,
|
||||
'invalid_test_status',
|
||||
webob.exc.HTTPBadRequest),
|
||||
)
|
||||
@ -1029,7 +1032,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
def test_reset_group_status(self):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID, self.group2.id),
|
||||
version='3.20')
|
||||
version=mv.GROUP_VOLUME_RESET_STATUS)
|
||||
body = {"reset_status": {
|
||||
"status": fields.GroupStatus.AVAILABLE
|
||||
}}
|
||||
@ -1068,7 +1071,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
"group_snapshot_id": group_snapshot.id}}
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/action' %
|
||||
fake.PROJECT_ID,
|
||||
version=GROUP_FROM_SRC_MICRO_VERSION)
|
||||
version=mv.GROUP_SNAPSHOTS)
|
||||
res_dict = self.controller.create_from_src(req, body)
|
||||
|
||||
self.assertIn('id', res_dict['group'])
|
||||
@ -1101,7 +1104,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
"source_group_id": source_grp.id}}
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/action' %
|
||||
fake.PROJECT_ID,
|
||||
version=GROUP_FROM_SRC_MICRO_VERSION)
|
||||
version=mv.GROUP_SNAPSHOTS)
|
||||
res_dict = self.controller.create_from_src(req, body)
|
||||
|
||||
self.assertIn('id', res_dict['group'])
|
||||
@ -1120,7 +1123,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
def test_enable_replication(self, mock_rep_grp_type, mock_rep_vol_type):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID, self.group3.id),
|
||||
version=GROUP_REPLICATION_MICRO_VERSION)
|
||||
version=mv.GROUP_REPLICATION)
|
||||
self.group3.status = fields.GroupStatus.AVAILABLE
|
||||
self.group3.save()
|
||||
body = {"enable_replication": {}}
|
||||
@ -1145,7 +1148,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
mock_rep_vol_type.return_value = is_vol_rep_type
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID, self.group3.id),
|
||||
version=GROUP_REPLICATION_MICRO_VERSION)
|
||||
version=mv.GROUP_REPLICATION)
|
||||
self.group3.status = fields.GroupStatus.AVAILABLE
|
||||
self.group3.save()
|
||||
body = {"enable_replication": {}}
|
||||
@ -1161,7 +1164,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
mock_rep_vol_type):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID, self.group3.id),
|
||||
version=GROUP_REPLICATION_MICRO_VERSION)
|
||||
version=mv.GROUP_REPLICATION)
|
||||
self.group3.status = fields.GroupStatus.AVAILABLE
|
||||
self.group3.save()
|
||||
body = {"enable_replication": {}}
|
||||
@ -1173,13 +1176,13 @@ class GroupsAPITestCase(test.TestCase):
|
||||
return_value=True)
|
||||
@mock.patch('cinder.volume.utils.is_group_a_type',
|
||||
return_value=True)
|
||||
@ddt.data((GROUP_REPLICATION_MICRO_VERSION, True,
|
||||
@ddt.data((mv.GROUP_REPLICATION, True,
|
||||
fields.GroupStatus.CREATING,
|
||||
webob.exc.HTTPBadRequest),
|
||||
(GROUP_REPLICATION_MICRO_VERSION, False,
|
||||
(mv.GROUP_REPLICATION, False,
|
||||
fields.GroupStatus.AVAILABLE,
|
||||
exception.GroupNotFound),
|
||||
(INVALID_GROUP_REPLICATION_MICRO_VERSION, True,
|
||||
(INVALID_GROUP_REPLICATION, True,
|
||||
fields.GroupStatus.AVAILABLE,
|
||||
exception.VersionNotFoundForAPIMethod),
|
||||
)
|
||||
@ -1209,7 +1212,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
def test_disable_replication(self, mock_rep_grp_type, mock_rep_vol_type):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID, self.group3.id),
|
||||
version=GROUP_REPLICATION_MICRO_VERSION)
|
||||
version=mv.GROUP_REPLICATION)
|
||||
self.group3.status = fields.GroupStatus.AVAILABLE
|
||||
self.group3.replication_status = fields.ReplicationStatus.ENABLED
|
||||
self.group3.save()
|
||||
@ -1227,19 +1230,19 @@ class GroupsAPITestCase(test.TestCase):
|
||||
return_value=True)
|
||||
@mock.patch('cinder.volume.utils.is_group_a_type',
|
||||
return_value=True)
|
||||
@ddt.data((GROUP_REPLICATION_MICRO_VERSION, True,
|
||||
@ddt.data((mv.GROUP_REPLICATION, True,
|
||||
fields.GroupStatus.CREATING,
|
||||
fields.ReplicationStatus.ENABLED,
|
||||
webob.exc.HTTPBadRequest),
|
||||
(GROUP_REPLICATION_MICRO_VERSION, True,
|
||||
(mv.GROUP_REPLICATION, True,
|
||||
fields.GroupStatus.AVAILABLE,
|
||||
fields.ReplicationStatus.DISABLED,
|
||||
webob.exc.HTTPBadRequest),
|
||||
(GROUP_REPLICATION_MICRO_VERSION, False,
|
||||
(mv.GROUP_REPLICATION, False,
|
||||
fields.GroupStatus.AVAILABLE,
|
||||
fields.ReplicationStatus.DISABLED,
|
||||
exception.GroupNotFound),
|
||||
(INVALID_GROUP_REPLICATION_MICRO_VERSION, True,
|
||||
(INVALID_GROUP_REPLICATION, True,
|
||||
fields.GroupStatus.AVAILABLE,
|
||||
fields.ReplicationStatus.ENABLED,
|
||||
exception.VersionNotFoundForAPIMethod),
|
||||
@ -1272,7 +1275,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
def test_failover_replication(self, mock_rep_grp_type, mock_rep_vol_type):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID, self.group3.id),
|
||||
version=GROUP_REPLICATION_MICRO_VERSION)
|
||||
version=mv.GROUP_REPLICATION)
|
||||
self.group3.status = fields.GroupStatus.AVAILABLE
|
||||
self.group3.replication_status = fields.ReplicationStatus.ENABLED
|
||||
self.group3.save()
|
||||
@ -1290,19 +1293,19 @@ class GroupsAPITestCase(test.TestCase):
|
||||
return_value=True)
|
||||
@mock.patch('cinder.volume.utils.is_group_a_type',
|
||||
return_value=True)
|
||||
@ddt.data((GROUP_REPLICATION_MICRO_VERSION, True,
|
||||
@ddt.data((mv.GROUP_REPLICATION, True,
|
||||
fields.GroupStatus.CREATING,
|
||||
fields.ReplicationStatus.ENABLED,
|
||||
webob.exc.HTTPBadRequest),
|
||||
(GROUP_REPLICATION_MICRO_VERSION, True,
|
||||
(mv.GROUP_REPLICATION, True,
|
||||
fields.GroupStatus.AVAILABLE,
|
||||
fields.ReplicationStatus.DISABLED,
|
||||
webob.exc.HTTPBadRequest),
|
||||
(GROUP_REPLICATION_MICRO_VERSION, False,
|
||||
(mv.GROUP_REPLICATION, False,
|
||||
fields.GroupStatus.AVAILABLE,
|
||||
fields.ReplicationStatus.DISABLED,
|
||||
exception.GroupNotFound),
|
||||
(INVALID_GROUP_REPLICATION_MICRO_VERSION, True,
|
||||
(INVALID_GROUP_REPLICATION, True,
|
||||
fields.GroupStatus.AVAILABLE,
|
||||
fields.ReplicationStatus.ENABLED,
|
||||
exception.VersionNotFoundForAPIMethod),
|
||||
@ -1337,7 +1340,7 @@ class GroupsAPITestCase(test.TestCase):
|
||||
mock_rep_grp_type, mock_rep_vol_type):
|
||||
req = fakes.HTTPRequest.blank('/v3/%s/groups/%s/action' %
|
||||
(fake.PROJECT_ID, self.group3.id),
|
||||
version=GROUP_REPLICATION_MICRO_VERSION)
|
||||
version=mv.GROUP_REPLICATION)
|
||||
targets = {
|
||||
'replication_targets': [
|
||||
{'backend_id': 'lvm_backend_1'}
|
||||
|
@ -16,12 +16,16 @@
|
||||
import ddt
|
||||
import mock
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import api_version_request as api_version
|
||||
from cinder.api.v3 import limits
|
||||
from cinder import test
|
||||
from cinder.tests.unit.api import fakes
|
||||
from cinder.tests.unit import fake_constants as fake
|
||||
|
||||
LIMITS_FILTER = mv.LIMITS_ADMIN_FILTER
|
||||
PRE_LIMITS_FILTER = mv.get_prior_version(LIMITS_FILTER)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class LimitsControllerTest(test.TestCase):
|
||||
@ -29,7 +33,8 @@ class LimitsControllerTest(test.TestCase):
|
||||
super(LimitsControllerTest, self).setUp()
|
||||
self.controller = limits.LimitsController()
|
||||
|
||||
@ddt.data(('3.38', True), ('3.38', False), ('3.39', True), ('3.39', False))
|
||||
@ddt.data((PRE_LIMITS_FILTER, True), (PRE_LIMITS_FILTER, False),
|
||||
(LIMITS_FILTER, True), (LIMITS_FILTER, False))
|
||||
@mock.patch('cinder.quota.VolumeTypeQuotaEngine.get_project_quotas')
|
||||
def test_get_limit_with_project_id(self, ver_project, mock_get_quotas):
|
||||
max_ver, has_project = ver_project
|
||||
@ -48,9 +53,9 @@ class LimitsControllerTest(test.TestCase):
|
||||
mock_get_quotas.side_effect = get_project_quotas
|
||||
|
||||
resp_dict = self.controller.index(req)
|
||||
# if admin, only 3.39 and req contains project_id filter, cinder
|
||||
# returns the specified project's quota.
|
||||
if max_ver == '3.39' and has_project:
|
||||
# if admin, only LIMITS_FILTER and req contains project_id filter,
|
||||
# cinder returns the specified project's quota.
|
||||
if max_ver == LIMITS_FILTER and has_project:
|
||||
self.assertEqual(
|
||||
5, resp_dict['limits']['absolute']['maxTotalVolumeGigabytes'])
|
||||
else:
|
||||
|
@ -15,6 +15,7 @@ import mock
|
||||
from six.moves import http_client
|
||||
|
||||
from cinder.api import extensions
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.v3 import messages
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
@ -66,8 +67,7 @@ class MessageApiTest(test.TestCase):
|
||||
self.mock_object(message_api.API, 'get', v3_fakes.fake_message_get)
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v3/messages/%s' % fakes.FAKE_UUID,
|
||||
version=messages.MESSAGES_BASE_MICRO_VERSION)
|
||||
'/v3/messages/%s' % fakes.FAKE_UUID, version=mv.MESSAGES)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
|
||||
res_dict = self.controller.show(req, fakes.FAKE_UUID)
|
||||
@ -81,8 +81,7 @@ class MessageApiTest(test.TestCase):
|
||||
message_id=fakes.FAKE_UUID))
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v3/messages/%s' % fakes.FAKE_UUID,
|
||||
version=messages.MESSAGES_BASE_MICRO_VERSION)
|
||||
'/v3/messages/%s' % fakes.FAKE_UUID, version=mv.MESSAGES)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
|
||||
self.assertRaises(exception.MessageNotFound, self.controller.show,
|
||||
@ -92,7 +91,7 @@ class MessageApiTest(test.TestCase):
|
||||
self.mock_object(message_api.API, 'get', v3_fakes.fake_message_get)
|
||||
|
||||
req = fakes.HTTPRequest.blank('/v3/messages/%s' % fakes.FAKE_UUID,
|
||||
version='3.0')
|
||||
version=mv.BASE_VERSION)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
|
||||
self.assertRaises(exception.VersionNotFoundForAPIMethod,
|
||||
@ -103,8 +102,7 @@ class MessageApiTest(test.TestCase):
|
||||
self.mock_object(message_api.API, 'delete')
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v3/messages/%s' % fakes.FAKE_UUID,
|
||||
version=messages.MESSAGES_BASE_MICRO_VERSION)
|
||||
'/v3/messages/%s' % fakes.FAKE_UUID, version=mv.MESSAGES)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
|
||||
resp = self.controller.delete(req, fakes.FAKE_UUID)
|
||||
@ -118,13 +116,13 @@ class MessageApiTest(test.TestCase):
|
||||
message_id=fakes.FAKE_UUID))
|
||||
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v3/messages/%s' % fakes.FAKE_UUID,
|
||||
version=messages.MESSAGES_BASE_MICRO_VERSION)
|
||||
'/v3/messages/%s' % fakes.FAKE_UUID, version=mv.MESSAGES)
|
||||
|
||||
self.assertRaises(exception.MessageNotFound, self.controller.delete,
|
||||
req, fakes.FAKE_UUID)
|
||||
|
||||
@ddt.data('3.30', '3.31', '3.34')
|
||||
@ddt.data(mv.get_prior_version(mv.RESOURCE_FILTER),
|
||||
mv.RESOURCE_FILTER, mv.LIKE_FILTER)
|
||||
@mock.patch('cinder.api.common.reject_invalid_filters')
|
||||
def test_message_list_with_general_filter(self, version, mock_update):
|
||||
url = '/v3/%s/messages' % fakes.FAKE_UUID
|
||||
@ -133,8 +131,8 @@ class MessageApiTest(test.TestCase):
|
||||
use_admin_context=False)
|
||||
self.controller.index(req)
|
||||
|
||||
if version != '3.30':
|
||||
support_like = True if version == '3.34' else False
|
||||
if version != mv.get_prior_version(mv.RESOURCE_FILTER):
|
||||
support_like = True if version == mv.LIKE_FILTER else False
|
||||
mock_update.assert_called_once_with(req.environ['cinder.context'],
|
||||
mock.ANY, 'message',
|
||||
support_like)
|
||||
@ -143,8 +141,7 @@ class MessageApiTest(test.TestCase):
|
||||
self.mock_object(message_api.API, 'get_all',
|
||||
return_value=[v3_fakes.fake_message(fakes.FAKE_UUID)])
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v3/messages/%s' % fakes.FAKE_UUID,
|
||||
version=messages.MESSAGES_BASE_MICRO_VERSION)
|
||||
'/v3/messages/%s' % fakes.FAKE_UUID, version=mv.MESSAGES)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
|
||||
res_dict = self.controller.index(req)
|
||||
|
@ -18,13 +18,12 @@ import ddt
|
||||
import mock
|
||||
import six
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.v3 import resource_filters as v3_filters
|
||||
from cinder import test
|
||||
from cinder.tests.unit.api import fakes
|
||||
from cinder.tests.unit import fake_constants as fake
|
||||
|
||||
FILTERS_MICRO_VERSION = '3.33'
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class ResourceFiltersAPITestCase(test.TestCase):
|
||||
@ -53,7 +52,7 @@ class ResourceFiltersAPITestCase(test.TestCase):
|
||||
if resource is not None:
|
||||
request_url += '?resource=%s' % resource
|
||||
req = fakes.HTTPRequest.blank(request_url,
|
||||
version=FILTERS_MICRO_VERSION)
|
||||
version=mv.RESOURCE_FILTER_CONFIG)
|
||||
|
||||
with mock.patch('cinder.api.common._FILTERS_COLLECTION', filters):
|
||||
result = self.controller.index(req)
|
||||
|
@ -20,6 +20,7 @@ from six.moves import http_client
|
||||
from six.moves.urllib.parse import urlencode
|
||||
import webob
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.v3 import router as router_v3
|
||||
from cinder import context
|
||||
from cinder import objects
|
||||
@ -51,13 +52,13 @@ class SnapshotManageTest(test.TestCase):
|
||||
fake.PROJECT_ID,
|
||||
True)
|
||||
|
||||
def _get_resp_post(self, body, version="3.8"):
|
||||
def _get_resp_post(self, body, version=mv.MANAGE_EXISTING_LIST):
|
||||
"""Helper to execute a POST manageable_snapshots API call."""
|
||||
req = webob.Request.blank('/v3/%s/manageable_snapshots' %
|
||||
fake.PROJECT_ID)
|
||||
req.method = 'POST'
|
||||
req.headers = mv.get_mv_header(version)
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.headers['OpenStack-API-Version'] = 'volume ' + version
|
||||
req.environ['cinder.context'] = self._admin_ctxt
|
||||
req.body = jsonutils.dump_as_bytes(body)
|
||||
res = req.get_response(app())
|
||||
@ -84,10 +85,12 @@ class SnapshotManageTest(test.TestCase):
|
||||
|
||||
def test_manage_snapshot_previous_version(self):
|
||||
body = {'snapshot': {'volume_id': fake.VOLUME_ID, 'ref': 'fake_ref'}}
|
||||
res = self._get_resp_post(body, version="3.7")
|
||||
res = self._get_resp_post(
|
||||
body, version=mv.get_prior_version(mv.MANAGE_EXISTING_LIST))
|
||||
self.assertEqual(http_client.NOT_FOUND, res.status_int, res)
|
||||
|
||||
def _get_resp_get(self, host, detailed, paging, version="3.8", **kwargs):
|
||||
def _get_resp_get(self, host, detailed, paging,
|
||||
version=mv.MANAGE_EXISTING_LIST, **kwargs):
|
||||
"""Helper to execute a GET os-snapshot-manage API call."""
|
||||
params = {'host': host} if host else {}
|
||||
params.update(kwargs)
|
||||
@ -101,8 +104,8 @@ class SnapshotManageTest(test.TestCase):
|
||||
req = webob.Request.blank('/v3/%s/manageable_snapshots%s%s' %
|
||||
(fake.PROJECT_ID, detail, query_string))
|
||||
req.method = 'GET'
|
||||
req.headers = mv.get_mv_header(version)
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.headers['OpenStack-API-Version'] = 'volume ' + version
|
||||
req.environ['cinder.context'] = self._admin_ctxt
|
||||
res = req.get_response(app())
|
||||
return res
|
||||
@ -120,7 +123,9 @@ class SnapshotManageTest(test.TestCase):
|
||||
self.assertEqual(http_client.OK, res.status_int)
|
||||
|
||||
def test_get_manageable_snapshots_previous_version(self):
|
||||
res = self._get_resp_get('fakehost', False, False, version="3.7")
|
||||
res = self._get_resp_get(
|
||||
'fakehost', False, False,
|
||||
version=mv.get_prior_version(mv.MANAGE_EXISTING_LIST))
|
||||
self.assertEqual(http_client.NOT_FOUND, res.status_int)
|
||||
|
||||
@mock.patch('cinder.volume.api.API.get_manageable_snapshots',
|
||||
@ -136,7 +141,9 @@ class SnapshotManageTest(test.TestCase):
|
||||
self.assertEqual(http_client.OK, res.status_int)
|
||||
|
||||
def test_get_manageable_snapshots_detail_previous_version(self):
|
||||
res = self._get_resp_get('fakehost', True, True, version="3.7")
|
||||
res = self._get_resp_get(
|
||||
'fakehost', True, True,
|
||||
version=mv.get_prior_version(mv.MANAGE_EXISTING_LIST))
|
||||
self.assertEqual(http_client.NOT_FOUND, res.status_int)
|
||||
|
||||
@ddt.data((True, True, 'detail_list'), (True, False, 'summary_list'),
|
||||
@ -150,12 +157,12 @@ class SnapshotManageTest(test.TestCase):
|
||||
if clustered:
|
||||
host = None
|
||||
cluster_name = 'mycluster'
|
||||
version = '3.17'
|
||||
version = mv.MANAGE_EXISTING_CLUSTER
|
||||
kwargs = {'cluster': cluster_name}
|
||||
else:
|
||||
host = 'fakehost'
|
||||
cluster_name = None
|
||||
version = '3.8'
|
||||
version = mv.MANAGE_EXISTING_LIST
|
||||
kwargs = {}
|
||||
service = objects.Service(disabled=False, host='fakehost',
|
||||
cluster_name=cluster_name)
|
||||
@ -183,12 +190,13 @@ class SnapshotManageTest(test.TestCase):
|
||||
mock.ANY, None, host=host, binary='cinder-volume',
|
||||
cluster_name=cluster_name)
|
||||
|
||||
@ddt.data('3.8', '3.17')
|
||||
@ddt.data(mv.MANAGE_EXISTING_LIST, mv.MANAGE_EXISTING_CLUSTER)
|
||||
def test_get_manageable_missing_host(self, version):
|
||||
res = self._get_resp_get(None, True, False, version=version)
|
||||
self.assertEqual(http_client.BAD_REQUEST, res.status_int)
|
||||
|
||||
def test_get_manageable_both_host_cluster(self):
|
||||
res = self._get_resp_get('host', True, False, version='3.17',
|
||||
res = self._get_resp_get('host', True, False,
|
||||
version=mv.MANAGE_EXISTING_CLUSTER,
|
||||
cluster='cluster')
|
||||
self.assertEqual(http_client.BAD_REQUEST, res.status_int)
|
||||
|
@ -17,7 +17,7 @@ import ddt
|
||||
|
||||
import mock
|
||||
|
||||
from cinder.api.openstack import api_version_request as api_version
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.v3 import snapshots
|
||||
from cinder import context
|
||||
from cinder import exception
|
||||
@ -54,9 +54,8 @@ def create_snapshot_query_with_metadata(metadata_query_string,
|
||||
"""Helper to create metadata querystring with microversion"""
|
||||
req = fakes.HTTPRequest.blank('/v3/snapshots?metadata=' +
|
||||
metadata_query_string)
|
||||
req.headers["OpenStack-API-Version"] = "volume " + api_microversion
|
||||
req.api_version_request = api_version.APIVersionRequest(
|
||||
api_microversion)
|
||||
req.headers = mv.get_mv_header(api_microversion)
|
||||
req.api_version_request = mv.get_api_version(api_microversion)
|
||||
|
||||
return req
|
||||
|
||||
@ -69,7 +68,9 @@ class SnapshotApiTest(test.TestCase):
|
||||
self.controller = snapshots.SnapshotsController()
|
||||
self.ctx = context.RequestContext(fake.USER_ID, fake.PROJECT_ID, True)
|
||||
|
||||
@ddt.data('3.14', '3.13', '3.41')
|
||||
@ddt.data(mv.GROUP_SNAPSHOTS,
|
||||
mv.get_prior_version(mv.GROUP_SNAPSHOTS),
|
||||
mv.SNAPSHOT_LIST_USER_ID)
|
||||
@mock.patch('cinder.db.snapshot_metadata_get', return_value=dict())
|
||||
@mock.patch('cinder.objects.Volume.get_by_id')
|
||||
@mock.patch('cinder.objects.Snapshot.get_by_id')
|
||||
@ -91,20 +92,20 @@ class SnapshotApiTest(test.TestCase):
|
||||
snapshot_get_by_id.return_value = snapshot_obj
|
||||
volume_get_by_id.return_value = fake_volume_obj
|
||||
req = fakes.HTTPRequest.blank('/v3/snapshots/%s' % UUID)
|
||||
req.api_version_request = api_version.APIVersionRequest(max_ver)
|
||||
req.api_version_request = mv.get_api_version(max_ver)
|
||||
resp_dict = self.controller.show(req, UUID)
|
||||
|
||||
self.assertIn('snapshot', resp_dict)
|
||||
self.assertEqual(UUID, resp_dict['snapshot']['id'])
|
||||
self.assertIn('updated_at', resp_dict['snapshot'])
|
||||
if max_ver == '3.14':
|
||||
if max_ver == mv.SNAPSHOT_LIST_USER_ID:
|
||||
self.assertIn('user_id', resp_dict['snapshot'])
|
||||
elif max_ver == mv.GROUP_SNAPSHOTS:
|
||||
self.assertIn('group_snapshot_id', resp_dict['snapshot'])
|
||||
self.assertNotIn('user_id', resp_dict['snapshot'])
|
||||
elif max_ver == '3.13':
|
||||
else:
|
||||
self.assertNotIn('group_snapshot_id', resp_dict['snapshot'])
|
||||
self.assertNotIn('user_id', resp_dict['snapshot'])
|
||||
elif max_ver == '3.41':
|
||||
self.assertIn('user_id', resp_dict['snapshot'])
|
||||
|
||||
def test_snapshot_show_invalid_id(self):
|
||||
snapshot_id = INVALID_UUID
|
||||
@ -144,7 +145,7 @@ class SnapshotApiTest(test.TestCase):
|
||||
# Generic filtering is introduced since '3,31' and we add
|
||||
# 'availability_zone' support by using generic filtering.
|
||||
req = fakes.HTTPRequest.blank(url, use_admin_context=is_admin_user,
|
||||
version='3.31')
|
||||
version=mv.RESOURCE_FILTER)
|
||||
res_dict = self.controller.detail(req)
|
||||
|
||||
self.assertEqual(1, len(res_dict['snapshots']))
|
||||
@ -154,12 +155,13 @@ class SnapshotApiTest(test.TestCase):
|
||||
self._create_snapshot(name='test1')
|
||||
self._create_snapshot(name='test2')
|
||||
|
||||
req = fakes.HTTPRequest.blank('/v3/snapshots?sort_key=name',
|
||||
version='3.29')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v3/snapshots?sort_key=name',
|
||||
version=mv.get_prior_version(mv.SNAPSHOT_SORT))
|
||||
self.assertRaises(exception.InvalidInput, self.controller.detail, req)
|
||||
|
||||
req = fakes.HTTPRequest.blank('/v3/snapshots?sort_key=name',
|
||||
version='3.30')
|
||||
version=mv.SNAPSHOT_SORT)
|
||||
res_dict = self.controller.detail(req)
|
||||
self.assertEqual(2, len(res_dict['snapshots']))
|
||||
self.assertEqual('test2', res_dict['snapshots'][0]['name'])
|
||||
@ -171,7 +173,8 @@ class SnapshotApiTest(test.TestCase):
|
||||
self._create_snapshot(metadata=metadata)
|
||||
|
||||
# Create request with metadata filter key1: value1
|
||||
req = create_snapshot_query_with_metadata('{"key1":"val1"}', '3.22')
|
||||
req = create_snapshot_query_with_metadata(
|
||||
'{"key1":"val1"}', mv.SNAPSHOT_LIST_METADATA_FILTER)
|
||||
|
||||
# query controller with above request
|
||||
res_dict = self.controller.detail(req)
|
||||
@ -184,7 +187,8 @@ class SnapshotApiTest(test.TestCase):
|
||||
'metadata'])
|
||||
|
||||
# Create request with metadata filter key2: value2
|
||||
req = create_snapshot_query_with_metadata('{"key2":"val2"}', '3.22')
|
||||
req = create_snapshot_query_with_metadata(
|
||||
'{"key2":"val2"}', mv.SNAPSHOT_LIST_METADATA_FILTER)
|
||||
|
||||
# query controller with above request
|
||||
res_dict = self.controller.detail(req)
|
||||
@ -199,7 +203,8 @@ class SnapshotApiTest(test.TestCase):
|
||||
|
||||
# Create request with metadata filter key1: value1, key11: value11
|
||||
req = create_snapshot_query_with_metadata(
|
||||
'{"key1":"val1", "key11":"val11"}', '3.22')
|
||||
'{"key1":"val1", "key11":"val11"}',
|
||||
mv.SNAPSHOT_LIST_METADATA_FILTER)
|
||||
|
||||
# query controller with above request
|
||||
res_dict = self.controller.detail(req)
|
||||
@ -212,7 +217,8 @@ class SnapshotApiTest(test.TestCase):
|
||||
'snapshots'][0]['metadata'])
|
||||
|
||||
# Create request with metadata filter key1: value1
|
||||
req = create_snapshot_query_with_metadata('{"key1":"val1"}', '3.22')
|
||||
req = create_snapshot_query_with_metadata(
|
||||
'{"key1":"val1"}', mv.SNAPSHOT_LIST_METADATA_FILTER)
|
||||
|
||||
# query controller with above request
|
||||
res_dict = self.controller.detail(req)
|
||||
@ -224,7 +230,19 @@ class SnapshotApiTest(test.TestCase):
|
||||
self.assertDictEqual({"key1": "val1", "key11": "val11"}, res_dict[
|
||||
'snapshots'][0]['metadata'])
|
||||
|
||||
@ddt.data('3.30', '3.31', '3.34')
|
||||
# Create request with metadata filter key2: value2
|
||||
req = create_snapshot_query_with_metadata(
|
||||
'{"key2":"val2"}', mv.SNAPSHOT_LIST_METADATA_FILTER)
|
||||
|
||||
# query controller with above request
|
||||
res_dict = self.controller.detail(req)
|
||||
|
||||
# verify no snapshot is returned
|
||||
self.assertEqual(0, len(res_dict['snapshots']))
|
||||
|
||||
@ddt.data(mv.get_prior_version(mv.RESOURCE_FILTER),
|
||||
mv.RESOURCE_FILTER,
|
||||
mv.LIKE_FILTER)
|
||||
@mock.patch('cinder.api.common.reject_invalid_filters')
|
||||
def test_snapshot_list_with_general_filter(self, version, mock_update):
|
||||
url = '/v3/%s/snapshots' % fake.PROJECT_ID
|
||||
@ -233,8 +251,8 @@ class SnapshotApiTest(test.TestCase):
|
||||
use_admin_context=False)
|
||||
self.controller.index(req)
|
||||
|
||||
if version != '3.30':
|
||||
support_like = True if version == '3.34' else False
|
||||
if version != mv.get_prior_version(mv.RESOURCE_FILTER):
|
||||
support_like = True if version == mv.LIKE_FILTER else False
|
||||
mock_update.assert_called_once_with(req.environ['cinder.context'],
|
||||
mock.ANY, 'snapshot',
|
||||
support_like)
|
||||
@ -245,7 +263,9 @@ class SnapshotApiTest(test.TestCase):
|
||||
self._create_snapshot(metadata=metadata)
|
||||
|
||||
# Create request with metadata filter key2: value2
|
||||
req = create_snapshot_query_with_metadata('{"key2":"val2"}', '3.21')
|
||||
req = create_snapshot_query_with_metadata(
|
||||
'{"key2":"val2"}',
|
||||
mv.get_prior_version(mv.SNAPSHOT_LIST_METADATA_FILTER))
|
||||
|
||||
# query controller with above request
|
||||
res_dict = self.controller.detail(req)
|
||||
|
@ -20,6 +20,7 @@ from six.moves import http_client
|
||||
from six.moves.urllib.parse import urlencode
|
||||
import webob
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.v3 import router as router_v3
|
||||
from cinder import context
|
||||
from cinder import objects
|
||||
@ -56,13 +57,13 @@ class VolumeManageTest(test.TestCase):
|
||||
fake.PROJECT_ID,
|
||||
True)
|
||||
|
||||
def _get_resp_post(self, body, version="3.8"):
|
||||
def _get_resp_post(self, body, version=mv.MANAGE_EXISTING_LIST):
|
||||
"""Helper to execute a POST manageable_volumes API call."""
|
||||
req = webob.Request.blank('/v3/%s/manageable_volumes' %
|
||||
fake.PROJECT_ID)
|
||||
req.method = 'POST'
|
||||
req.headers = mv.get_mv_header(version)
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.headers['OpenStack-API-Version'] = 'volume ' + version
|
||||
req.environ['cinder.context'] = self._admin_ctxt
|
||||
req.body = jsonutils.dump_as_bytes(body)
|
||||
res = req.get_response(app())
|
||||
@ -88,7 +89,8 @@ class VolumeManageTest(test.TestCase):
|
||||
res = self._get_resp_post(body)
|
||||
self.assertEqual(http_client.BAD_REQUEST, res.status_int, res)
|
||||
|
||||
def _get_resp_get(self, host, detailed, paging, version="3.8", **kwargs):
|
||||
def _get_resp_get(self, host, detailed, paging,
|
||||
version=mv.MANAGE_EXISTING_LIST, **kwargs):
|
||||
"""Helper to execute a GET os-volume-manage API call."""
|
||||
params = {'host': host} if host else {}
|
||||
params.update(kwargs)
|
||||
@ -103,8 +105,8 @@ class VolumeManageTest(test.TestCase):
|
||||
req = webob.Request.blank('/v3/%s/manageable_volumes%s%s' %
|
||||
(fake.PROJECT_ID, detail, query_string))
|
||||
req.method = 'GET'
|
||||
req.headers = mv.get_mv_header(version)
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.headers['OpenStack-API-Version'] = 'volume ' + version
|
||||
req.environ['cinder.context'] = self._admin_ctxt
|
||||
res = req.get_response(app())
|
||||
return res
|
||||
@ -122,7 +124,9 @@ class VolumeManageTest(test.TestCase):
|
||||
self.assertEqual(http_client.OK, res.status_int)
|
||||
|
||||
def test_get_manageable_volumes_previous_version(self):
|
||||
res = self._get_resp_get('fakehost', False, True, version="3.7")
|
||||
res = self._get_resp_get(
|
||||
'fakehost', False, True,
|
||||
version=mv.get_prior_version(mv.MANAGE_EXISTING_LIST))
|
||||
self.assertEqual(http_client.NOT_FOUND, res.status_int)
|
||||
|
||||
@mock.patch('cinder.volume.api.API.get_manageable_volumes',
|
||||
@ -138,7 +142,9 @@ class VolumeManageTest(test.TestCase):
|
||||
self.assertEqual(http_client.OK, res.status_int)
|
||||
|
||||
def test_get_manageable_volumes_detail_previous_version(self):
|
||||
res = self._get_resp_get('fakehost', True, False, version="3.7")
|
||||
res = self._get_resp_get(
|
||||
'fakehost', True, False,
|
||||
version=mv.get_prior_version(mv.MANAGE_EXISTING_LIST))
|
||||
self.assertEqual(http_client.NOT_FOUND, res.status_int)
|
||||
|
||||
@ddt.data((True, True, 'detail_list'), (True, False, 'summary_list'),
|
||||
@ -152,12 +158,12 @@ class VolumeManageTest(test.TestCase):
|
||||
if clustered:
|
||||
host = None
|
||||
cluster_name = 'mycluster'
|
||||
version = '3.17'
|
||||
version = mv.MANAGE_EXISTING_CLUSTER
|
||||
kwargs = {'cluster': cluster_name}
|
||||
else:
|
||||
host = 'fakehost'
|
||||
cluster_name = None
|
||||
version = '3.8'
|
||||
version = mv.MANAGE_EXISTING_LIST
|
||||
kwargs = {}
|
||||
service = objects.Service(disabled=False, host='fakehost',
|
||||
cluster_name=cluster_name)
|
||||
@ -185,12 +191,13 @@ class VolumeManageTest(test.TestCase):
|
||||
mock.ANY, None, host=host, binary='cinder-volume',
|
||||
cluster_name=cluster_name)
|
||||
|
||||
@ddt.data('3.8', '3.17')
|
||||
@ddt.data(mv.MANAGE_EXISTING_LIST, mv.MANAGE_EXISTING_CLUSTER)
|
||||
def test_get_manageable_missing_host(self, version):
|
||||
res = self._get_resp_get(None, True, False, version=version)
|
||||
self.assertEqual(http_client.BAD_REQUEST, res.status_int)
|
||||
|
||||
def test_get_manageable_both_host_cluster(self):
|
||||
res = self._get_resp_get('host', True, False, version='3.17',
|
||||
res = self._get_resp_get('host', True, False,
|
||||
version=mv.MANAGE_EXISTING_CLUSTER,
|
||||
cluster='cluster')
|
||||
self.assertEqual(http_client.BAD_REQUEST, res.status_int)
|
||||
|
@ -18,6 +18,7 @@ from oslo_serialization import jsonutils
|
||||
import webob
|
||||
|
||||
from cinder.api import extensions
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.v3 import volume_metadata
|
||||
from cinder.api.v3 import volumes
|
||||
from cinder import db
|
||||
@ -150,7 +151,7 @@ class VolumeMetaDataTest(test.TestCase):
|
||||
self.volume_controller.create(req, body)
|
||||
|
||||
def test_index(self):
|
||||
req = fakes.HTTPRequest.blank(self.url, version="3.15")
|
||||
req = fakes.HTTPRequest.blank(self.url, version=mv.ETAGS)
|
||||
data = self.controller.index(req, self.req_id)
|
||||
|
||||
expected = {
|
||||
@ -166,14 +167,14 @@ class VolumeMetaDataTest(test.TestCase):
|
||||
def test_index_nonexistent_volume(self):
|
||||
self.mock_object(db, 'volume_metadata_get',
|
||||
return_volume_nonexistent)
|
||||
req = fakes.HTTPRequest.blank(self.url, version="3.15")
|
||||
req = fakes.HTTPRequest.blank(self.url, version=mv.ETAGS)
|
||||
self.assertRaises(exception.VolumeNotFound,
|
||||
self.controller.index, req, self.url)
|
||||
|
||||
def test_index_no_data(self):
|
||||
self.mock_object(db, 'volume_metadata_get',
|
||||
return_empty_volume_metadata)
|
||||
req = fakes.HTTPRequest.blank(self.url, version="3.15")
|
||||
req = fakes.HTTPRequest.blank(self.url, version=mv.ETAGS)
|
||||
data = self.controller.index(req, self.req_id)
|
||||
expected = {'metadata': {}}
|
||||
result = jsonutils.loads(data.body)
|
||||
@ -182,7 +183,7 @@ class VolumeMetaDataTest(test.TestCase):
|
||||
def test_validate_etag_true(self):
|
||||
self.mock_object(db, 'volume_metadata_get',
|
||||
return_value={'key1': 'vanue1', 'key2': 'value2'})
|
||||
req = fakes.HTTPRequest.blank(self.url, version="3.15")
|
||||
req = fakes.HTTPRequest.blank(self.url, version=mv.ETAGS)
|
||||
req.environ['cinder.context'] = mock.Mock()
|
||||
req.if_match.etags = ['d5103bf7b26ff0310200d110da3ed186']
|
||||
self.assertTrue(self.controller._validate_etag(req, self.req_id))
|
||||
@ -192,7 +193,7 @@ class VolumeMetaDataTest(test.TestCase):
|
||||
fake_volume = {'id': self.req_id, 'status': 'available'}
|
||||
fake_context = mock.Mock()
|
||||
metadata_update.side_effect = return_new_volume_metadata
|
||||
req = fakes.HTTPRequest.blank(self.url, version="3.15")
|
||||
req = fakes.HTTPRequest.blank(self.url, version=mv.ETAGS)
|
||||
req.method = 'PUT'
|
||||
req.content_type = "application/json"
|
||||
expected = {
|
||||
@ -217,7 +218,7 @@ class VolumeMetaDataTest(test.TestCase):
|
||||
fake_volume = {'id': self.req_id, 'status': 'available'}
|
||||
fake_context = mock.Mock()
|
||||
metadata_update.side_effect = return_create_volume_metadata
|
||||
req = fakes.HTTPRequest.blank(self.url + '/key1', version="3.15")
|
||||
req = fakes.HTTPRequest.blank(self.url + '/key1', version=mv.ETAGS)
|
||||
req.method = 'PUT'
|
||||
body = {"meta": {"key1": "value1"}}
|
||||
req.body = jsonutils.dump_as_bytes(body)
|
||||
@ -235,7 +236,7 @@ class VolumeMetaDataTest(test.TestCase):
|
||||
def test_create_metadata_keys_value_none(self):
|
||||
self.mock_object(db, 'volume_metadata_update',
|
||||
return_create_volume_metadata)
|
||||
req = fakes.HTTPRequest.blank(self.url, version="3.15")
|
||||
req = fakes.HTTPRequest.blank(self.url, version=mv.ETAGS)
|
||||
req.method = 'POST'
|
||||
req.headers["content-type"] = "application/json"
|
||||
body = {"meta": {"key": None}}
|
||||
@ -245,7 +246,7 @@ class VolumeMetaDataTest(test.TestCase):
|
||||
def test_update_items_value_none(self):
|
||||
self.mock_object(db, 'volume_metadata_update',
|
||||
return_create_volume_metadata)
|
||||
req = fakes.HTTPRequest.blank(self.url + '/key1', version="3.15")
|
||||
req = fakes.HTTPRequest.blank(self.url + '/key1', version=mv.ETAGS)
|
||||
req.method = 'PUT'
|
||||
body = {"metadata": {"key": None}}
|
||||
req.body = jsonutils.dump_as_bytes(body)
|
||||
|
@ -19,7 +19,7 @@ import mock
|
||||
import webob
|
||||
|
||||
from cinder.api import extensions
|
||||
from cinder.api.openstack import api_version_request as api_version
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.v2.views.volumes import ViewBuilder
|
||||
from cinder.api.v3 import volumes
|
||||
from cinder import context
|
||||
@ -38,10 +38,7 @@ from cinder import utils
|
||||
from cinder.volume import api as volume_api
|
||||
from cinder.volume import api as vol_get
|
||||
|
||||
version_header_name = 'OpenStack-API-Version'
|
||||
|
||||
DEFAULT_AZ = "zone1:host1"
|
||||
REVERT_TO_SNAPSHOT_VERSION = '3.40'
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@ -61,7 +58,7 @@ class VolumeApiTest(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('/v3/volumes?bootable=True')
|
||||
req.method = 'GET'
|
||||
req.content_type = 'application/json'
|
||||
req.headers = {version_header_name: 'volume 3.0'}
|
||||
req.headers = mv.get_mv_header(mv.BASE_VERSION)
|
||||
req.environ['cinder.context'].is_admin = True
|
||||
|
||||
self.override_config('query_volume_filters', 'bootable')
|
||||
@ -77,9 +74,10 @@ class VolumeApiTest(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('/v3/volumes?bootable=True')
|
||||
req.method = 'GET'
|
||||
req.content_type = 'application/json'
|
||||
req.headers = {version_header_name: 'volume 3.2'}
|
||||
req.headers = mv.get_mv_header(mv.VOLUME_LIST_BOOTABLE)
|
||||
req.environ['cinder.context'].is_admin = True
|
||||
req.api_version_request = api_version.APIVersionRequest('3.29')
|
||||
req.api_version_request = mv.get_api_version(
|
||||
mv.VOLUME_LIST_BOOTABLE)
|
||||
|
||||
self.override_config('query_volume_filters', 'bootable')
|
||||
self.controller.index(req)
|
||||
@ -119,8 +117,9 @@ class VolumeApiTest(test.TestCase):
|
||||
vols = self._create_volume_with_glance_metadata()
|
||||
req = fakes.HTTPRequest.blank("/v3/volumes?glance_metadata="
|
||||
"{'image_name': 'imageTestOne'}")
|
||||
req.headers["OpenStack-API-Version"] = "volume 3.4"
|
||||
req.api_version_request = api_version.APIVersionRequest('3.4')
|
||||
req.headers = mv.get_mv_header(mv.VOLUME_LIST_GLANCE_METADATA)
|
||||
req.api_version_request = mv.get_api_version(
|
||||
mv.VOLUME_LIST_GLANCE_METADATA)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
res_dict = self.controller.index(req)
|
||||
volumes = res_dict['volumes']
|
||||
@ -131,8 +130,8 @@ class VolumeApiTest(test.TestCase):
|
||||
self._create_volume_with_glance_metadata()
|
||||
req = fakes.HTTPRequest.blank("/v3/volumes?glance_metadata="
|
||||
"{'image_name': 'imageTestOne'}")
|
||||
req.headers["OpenStack-API-Version"] = "volume 3.0"
|
||||
req.api_version_request = api_version.APIVersionRequest('3.0')
|
||||
req.headers = mv.get_mv_header(mv.BASE_VERSION)
|
||||
req.api_version_request = mv.get_api_version(mv.BASE_VERSION)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
res_dict = self.controller.index(req)
|
||||
volumes = res_dict['volumes']
|
||||
@ -142,8 +141,8 @@ class VolumeApiTest(test.TestCase):
|
||||
vols = self._create_volume_with_group()
|
||||
req = fakes.HTTPRequest.blank(("/v3/volumes?group_id=%s") %
|
||||
fake.GROUP_ID)
|
||||
req.headers["OpenStack-API-Version"] = "volume 3.10"
|
||||
req.api_version_request = api_version.APIVersionRequest('3.10')
|
||||
req.headers = mv.get_mv_header(mv.VOLUME_LIST_GROUP)
|
||||
req.api_version_request = mv.get_api_version(mv.VOLUME_LIST_GROUP)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
res_dict = self.controller.index(req)
|
||||
volumes = res_dict['volumes']
|
||||
@ -154,26 +153,29 @@ class VolumeApiTest(test.TestCase):
|
||||
self._create_volume_with_group()
|
||||
req = fakes.HTTPRequest.blank(("/v3/volumes?group_id=%s") %
|
||||
fake.GROUP_ID)
|
||||
req.headers["OpenStack-API-Version"] = "volume 3.9"
|
||||
req.api_version_request = api_version.APIVersionRequest('3.9')
|
||||
req.headers = mv.get_mv_header(mv.BACKUP_UPDATE)
|
||||
req.api_version_request = mv.get_api_version(mv.BACKUP_UPDATE)
|
||||
req.environ['cinder.context'] = self.ctxt
|
||||
res_dict = self.controller.index(req)
|
||||
volumes = res_dict['volumes']
|
||||
self.assertEqual(2, len(volumes))
|
||||
|
||||
def _fake_volumes_summary_request(self, version='3.12', all_tenant=False,
|
||||
def _fake_volumes_summary_request(self,
|
||||
version=mv.VOLUME_SUMMARY,
|
||||
all_tenant=False,
|
||||
is_admin=False):
|
||||
req_url = '/v3/volumes/summary'
|
||||
if all_tenant:
|
||||
req_url += '?all_tenants=True'
|
||||
req = fakes.HTTPRequest.blank(req_url, use_admin_context=is_admin)
|
||||
req.headers = {'OpenStack-API-Version': 'volume ' + version}
|
||||
req.api_version_request = api_version.APIVersionRequest(version)
|
||||
req.headers = mv.get_mv_header(version)
|
||||
req.api_version_request = mv.get_api_version(version)
|
||||
return req
|
||||
|
||||
def test_volumes_summary_in_unsupport_version(self):
|
||||
"""Function call to test summary volumes API in unsupported version"""
|
||||
req = self._fake_volumes_summary_request(version='3.7')
|
||||
req = self._fake_volumes_summary_request(
|
||||
version=mv.get_prior_version(mv.VOLUME_SUMMARY))
|
||||
self.assertRaises(exception.VersionNotFoundForAPIMethod,
|
||||
self.controller.summary, req)
|
||||
|
||||
@ -196,9 +198,10 @@ class VolumeApiTest(test.TestCase):
|
||||
self.assertEqual(expected, res_dict)
|
||||
|
||||
@ddt.data(
|
||||
('3.35', {'volume-summary': {'total_size': 0.0,
|
||||
(mv.get_prior_version(mv.VOLUME_SUMMARY_METADATA),
|
||||
{'volume-summary': {'total_size': 0.0,
|
||||
'total_count': 0}}),
|
||||
('3.36', {'volume-summary': {'total_size': 0.0,
|
||||
(mv.VOLUME_SUMMARY_METADATA, {'volume-summary': {'total_size': 0.0,
|
||||
'total_count': 0,
|
||||
'metadata': {}}}))
|
||||
@ddt.unpack
|
||||
@ -208,9 +211,11 @@ class VolumeApiTest(test.TestCase):
|
||||
self.assertEqual(expect_result, res_dict)
|
||||
|
||||
@ddt.data(
|
||||
('3.35', {'volume-summary': {'total_size': 2,
|
||||
(mv.get_prior_version(mv.VOLUME_SUMMARY_METADATA),
|
||||
{'volume-summary': {'total_size': 2,
|
||||
'total_count': 2}}),
|
||||
('3.36', {'volume-summary': {'total_size': 2,
|
||||
(mv.VOLUME_SUMMARY_METADATA,
|
||||
{'volume-summary': {'total_size': 2,
|
||||
'total_count': 2,
|
||||
'metadata': {
|
||||
'name': ['test_name1', 'test_name2'],
|
||||
@ -230,9 +235,11 @@ class VolumeApiTest(test.TestCase):
|
||||
self.assertEqual(expect_result, res_dict)
|
||||
|
||||
@ddt.data(
|
||||
('3.35', {'volume-summary': {'total_size': 2,
|
||||
(mv.get_prior_version(mv.VOLUME_SUMMARY_METADATA),
|
||||
{'volume-summary': {'total_size': 2,
|
||||
'total_count': 2}}),
|
||||
('3.36', {'volume-summary': {'total_size': 2,
|
||||
(mv.VOLUME_SUMMARY_METADATA,
|
||||
{'volume-summary': {'total_size': 2,
|
||||
'total_count': 2,
|
||||
'metadata': {
|
||||
'name': ['test_name1', 'test_name2'],
|
||||
@ -334,8 +341,9 @@ class VolumeApiTest(test.TestCase):
|
||||
if with_migration_status:
|
||||
volume['volume']['migration_status'] = None
|
||||
|
||||
# Remove group_id if max version is less than 3.13.
|
||||
if req_version and req_version.matches(None, "3.12"):
|
||||
# Remove group_id if max version is less than GROUP_VOLUME.
|
||||
if req_version and req_version.matches(
|
||||
None, mv.get_prior_version(mv.GROUP_VOLUME)):
|
||||
volume['volume'].pop('group_id')
|
||||
|
||||
return volume
|
||||
@ -356,13 +364,14 @@ class VolumeApiTest(test.TestCase):
|
||||
'group': test_group,
|
||||
}
|
||||
|
||||
# Remove group_id if max version is less than 3.13.
|
||||
if req_version and req_version.matches(None, "3.12"):
|
||||
# Remove group_id if max version is less than GROUP_VOLUME.
|
||||
if req_version and req_version.matches(
|
||||
None, mv.get_prior_version(mv.GROUP_VOLUME)):
|
||||
volume.pop('group')
|
||||
|
||||
return volume
|
||||
|
||||
@ddt.data('3.13', '3.12')
|
||||
@ddt.data(mv.GROUP_VOLUME, mv.get_prior_version(mv.GROUP_VOLUME))
|
||||
@mock.patch(
|
||||
'cinder.api.openstack.wsgi.Controller.validate_name_and_description')
|
||||
def test_volume_create(self, max_ver, mock_validate):
|
||||
@ -375,14 +384,14 @@ class VolumeApiTest(test.TestCase):
|
||||
vol = self._vol_in_request_body()
|
||||
body = {"volume": vol}
|
||||
req = fakes.HTTPRequest.blank('/v3/volumes')
|
||||
req.api_version_request = api_version.APIVersionRequest(max_ver)
|
||||
req.api_version_request = mv.get_api_version(max_ver)
|
||||
res_dict = self.controller.create(req, body)
|
||||
ex = self._expected_vol_from_controller(
|
||||
req_version=req.api_version_request)
|
||||
self.assertEqual(ex, res_dict)
|
||||
self.assertTrue(mock_validate.called)
|
||||
|
||||
@ddt.data('3.14', '3.13')
|
||||
@ddt.data(mv.GROUP_SNAPSHOTS, mv.get_prior_version(mv.GROUP_SNAPSHOTS))
|
||||
@mock.patch.object(group_api.API, 'get')
|
||||
@mock.patch.object(db.sqlalchemy.api, '_volume_type_get_full',
|
||||
autospec=True)
|
||||
@ -405,7 +414,7 @@ class VolumeApiTest(test.TestCase):
|
||||
group_id=fake.GROUP_ID)
|
||||
body = {"volume": vol}
|
||||
req = fakes.HTTPRequest.blank('/v3/volumes')
|
||||
req.api_version_request = api_version.APIVersionRequest(max_ver)
|
||||
req.api_version_request = mv.get_api_version(max_ver)
|
||||
res_dict = self.controller.create(req, body)
|
||||
ex = self._expected_vol_from_controller(
|
||||
snapshot_id=snapshot_id,
|
||||
@ -450,23 +459,26 @@ class VolumeApiTest(test.TestCase):
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create,
|
||||
req, body)
|
||||
|
||||
@ddt.data('3.30', '3.31', '3.34')
|
||||
@ddt.data(mv.get_prior_version(mv.RESOURCE_FILTER), mv.RESOURCE_FILTER,
|
||||
mv.LIKE_FILTER)
|
||||
@mock.patch.object(volume_api.API, 'check_volume_filters', mock.Mock())
|
||||
@mock.patch.object(utils, 'add_visible_admin_metadata', mock.Mock())
|
||||
@mock.patch('cinder.api.common.reject_invalid_filters')
|
||||
def test_list_volume_with_general_filter(self, version, mock_update):
|
||||
req = fakes.HTTPRequest.blank('/v3/volumes', version=version)
|
||||
self.controller.index(req)
|
||||
if version != '3.30':
|
||||
support_like = True if version == '3.34' else False
|
||||
if version >= mv.RESOURCE_FILTER:
|
||||
support_like = True if version == mv.LIKE_FILTER else False
|
||||
mock_update.assert_called_once_with(req.environ['cinder.context'],
|
||||
mock.ANY, 'volume',
|
||||
support_like)
|
||||
|
||||
@ddt.data({'admin': True, 'version': '3.21'},
|
||||
{'admin': False, 'version': '3.21'},
|
||||
{'admin': True, 'version': '3.20'},
|
||||
{'admin': False, 'version': '3.20'})
|
||||
@ddt.data({'admin': True, 'version': mv.VOLUME_DETAIL_PROVIDER_ID},
|
||||
{'admin': False, 'version': mv.VOLUME_DETAIL_PROVIDER_ID},
|
||||
{'admin': True,
|
||||
'version': mv.get_prior_version(mv.VOLUME_DETAIL_PROVIDER_ID)},
|
||||
{'admin': False,
|
||||
'version': mv.get_prior_version(mv.VOLUME_DETAIL_PROVIDER_ID)})
|
||||
@ddt.unpack
|
||||
def test_volume_show_provider_id(self, admin, version):
|
||||
self.mock_object(volume_api.API, 'get', v2_fakes.fake_volume_api_get)
|
||||
@ -482,8 +494,8 @@ class VolumeApiTest(test.TestCase):
|
||||
res_dict = self.controller.show(req, fake.VOLUME_ID)
|
||||
req_version = req.api_version_request
|
||||
# provider_id is in view if min version is greater than or equal to
|
||||
# 3.21 for admin.
|
||||
if req_version.matches("3.21", None) and admin:
|
||||
# VOLUME_DETAIL_PROVIDER_ID for admin.
|
||||
if req_version.matches(mv.VOLUME_DETAIL_PROVIDER_ID, None) and admin:
|
||||
self.assertIn('provider_id', res_dict['volume'])
|
||||
else:
|
||||
self.assertNotIn('provider_id', res_dict['volume'])
|
||||
@ -516,10 +528,9 @@ class VolumeApiTest(test.TestCase):
|
||||
mock_latest.side_effect = exception.VolumeSnapshotNotFound(volume_id=
|
||||
'fake_id')
|
||||
req = fakes.HTTPRequest.blank('/v3/volumes/fake_id/revert')
|
||||
req.headers = {'OpenStack-API-Version':
|
||||
'volume %s' % REVERT_TO_SNAPSHOT_VERSION}
|
||||
req.api_version_request = api_version.APIVersionRequest(
|
||||
REVERT_TO_SNAPSHOT_VERSION)
|
||||
req.headers = mv.get_mv_header(mv.VOLUME_REVERT)
|
||||
req.api_version_request = mv.get_api_version(
|
||||
mv.VOLUME_REVERT)
|
||||
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.revert,
|
||||
req, 'fake_id', {'revert': {'snapshot_id':
|
||||
@ -534,10 +545,9 @@ class VolumeApiTest(test.TestCase):
|
||||
fake_snapshot = self._fake_create_snapshot(fake.UUID1)
|
||||
mock_latest.return_value = fake_snapshot
|
||||
req = fakes.HTTPRequest.blank('/v3/volumes/fake_id/revert')
|
||||
req.headers = {'OpenStack-API-Version':
|
||||
'volume %s' % REVERT_TO_SNAPSHOT_VERSION}
|
||||
req.api_version_request = api_version.APIVersionRequest(
|
||||
REVERT_TO_SNAPSHOT_VERSION)
|
||||
req.headers = mv.get_mv_header(mv.VOLUME_REVERT)
|
||||
req.api_version_request = mv.get_api_version(
|
||||
mv.VOLUME_REVERT)
|
||||
|
||||
self.assertRaises(webob.exc.HTTPBadRequest, self.controller.revert,
|
||||
req, 'fake_id', {'revert': {'snapshot_id':
|
||||
@ -557,10 +567,9 @@ class VolumeApiTest(test.TestCase):
|
||||
mock_latest.return_value = fake_snapshot
|
||||
req = fakes.HTTPRequest.blank('/v3/volumes/%s/revert'
|
||||
% fake_volume['id'])
|
||||
req.headers = {'OpenStack-API-Version':
|
||||
'volume %s' % REVERT_TO_SNAPSHOT_VERSION}
|
||||
req.api_version_request = api_version.APIVersionRequest(
|
||||
REVERT_TO_SNAPSHOT_VERSION)
|
||||
req.headers = mv.get_mv_header(mv.VOLUME_REVERT)
|
||||
req.api_version_request = mv.get_api_version(
|
||||
mv.VOLUME_REVERT)
|
||||
# update volume's status failed
|
||||
mock_update.side_effect = [False, True]
|
||||
|
||||
|
@ -19,6 +19,7 @@ from oslo_serialization import jsonutils
|
||||
from six.moves import http_client
|
||||
import webob
|
||||
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.v3 import router as router_v3
|
||||
from cinder.api.v3 import workers
|
||||
from cinder import context
|
||||
@ -61,7 +62,7 @@ class WorkersTestCase(test.TestCase):
|
||||
overwrite=False)
|
||||
self.controller = workers.create_resource()
|
||||
|
||||
def _get_resp_post(self, body, version='3.24', ctxt=None):
|
||||
def _get_resp_post(self, body, version=mv.WORKERS_CLEANUP, ctxt=None):
|
||||
"""Helper to execute a POST workers API call."""
|
||||
req = webob.Request.blank('/v3/%s/workers/cleanup' % fake.PROJECT_ID)
|
||||
req.method = 'POST'
|
||||
@ -74,7 +75,7 @@ class WorkersTestCase(test.TestCase):
|
||||
|
||||
@mock.patch('cinder.scheduler.rpcapi.SchedulerAPI.work_cleanup')
|
||||
def test_cleanup_old_api_version(self, rpc_mock):
|
||||
res = self._get_resp_post({}, '3.19')
|
||||
res = self._get_resp_post({}, mv.get_prior_version(mv.WORKERS_CLEANUP))
|
||||
self.assertEqual(http_client.NOT_FOUND, res.status_code)
|
||||
rpc_mock.assert_not_called()
|
||||
|
||||
|
@ -16,6 +16,7 @@ from oslo_config import cfg
|
||||
from oslo_utils import timeutils
|
||||
|
||||
from cinder.api import extensions
|
||||
from cinder.api import microversions as mv
|
||||
from cinder.api.openstack import api_version_request as api_version
|
||||
from cinder.api.v3 import messages
|
||||
from cinder import context
|
||||
@ -128,8 +129,8 @@ class MessageApiTest(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank(url)
|
||||
req.method = 'GET'
|
||||
req.content_type = 'application/json'
|
||||
req.headers = {version_header_name: 'volume 3.5'}
|
||||
req.api_version_request = api_version.APIVersionRequest('3.30')
|
||||
req.headers = mv.get_mv_header(mv.MESSAGES_PAGINATION)
|
||||
req.api_version_request = mv.get_api_version(mv.RESOURCE_FILTER)
|
||||
req.environ['cinder.context'].is_admin = True
|
||||
|
||||
res = self.controller.index(req)
|
||||
@ -139,8 +140,8 @@ class MessageApiTest(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank(url)
|
||||
req.method = 'GET'
|
||||
req.content_type = 'application/json'
|
||||
req.headers = {version_header_name: 'volume 3.5'}
|
||||
req.api_version_request = api_version.APIVersionRequest('3.30')
|
||||
req.headers = mv.get_mv_header(mv.MESSAGES_PAGINATION)
|
||||
req.api_version_request = mv.get_api_version(mv.RESOURCE_FILTER)
|
||||
req.environ['cinder.context'].is_admin = True
|
||||
|
||||
res = self.controller.index(req)
|
||||
@ -149,12 +150,14 @@ class MessageApiTest(test.TestCase):
|
||||
def test_get_all_messages_with_limit_wrong_version(self):
|
||||
self.create_message_for_tests()
|
||||
|
||||
PRE_MESSAGES_PAGINATION = mv.get_prior_version(mv.MESSAGES_PAGINATION)
|
||||
|
||||
url = '/v3/messages?limit=1'
|
||||
req = fakes.HTTPRequest.blank(url)
|
||||
req.method = 'GET'
|
||||
req.content_type = 'application/json'
|
||||
req.headers["OpenStack-API-Version"] = "volume 3.3"
|
||||
req.api_version_request = api_version.APIVersionRequest('3.3')
|
||||
req.headers = mv.get_mv_header(PRE_MESSAGES_PAGINATION)
|
||||
req.api_version_request = mv.get_api_version(PRE_MESSAGES_PAGINATION)
|
||||
req.environ['cinder.context'].is_admin = True
|
||||
|
||||
res = self.controller.index(req)
|
||||
@ -167,8 +170,8 @@ class MessageApiTest(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank(url)
|
||||
req.method = 'GET'
|
||||
req.content_type = 'application/json'
|
||||
req.headers["OpenStack-API-Version"] = "volume 3.5"
|
||||
req.api_version_request = api_version.APIVersionRequest('3.5')
|
||||
req.headers = mv.get_mv_header(mv.MESSAGES_PAGINATION)
|
||||
req.api_version_request = mv.get_api_version(mv.MESSAGES_PAGINATION)
|
||||
req.environ['cinder.context'].is_admin = True
|
||||
|
||||
res = self.controller.index(req)
|
||||
@ -181,8 +184,8 @@ class MessageApiTest(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank(url)
|
||||
req.method = 'GET'
|
||||
req.content_type = 'application/json'
|
||||
req.headers["OpenStack-API-Version"] = "volume 3.5"
|
||||
req.api_version_request = api_version.APIVersionRequest('3.5')
|
||||
req.headers = mv.get_mv_header(mv.MESSAGES_PAGINATION)
|
||||
req.api_version_request = mv.get_api_version(mv.MESSAGES_PAGINATION)
|
||||
req.environ['cinder.context'].is_admin = True
|
||||
|
||||
res = self.controller.index(req)
|
||||
@ -196,8 +199,8 @@ class MessageApiTest(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank(url)
|
||||
req.method = 'GET'
|
||||
req.content_type = 'application/json'
|
||||
req.headers["OpenStack-API-Version"] = "volume 3.5"
|
||||
req.api_version_request = api_version.APIVersionRequest('3.5')
|
||||
req.headers = mv.get_mv_header(mv.MESSAGES_PAGINATION)
|
||||
req.api_version_request = mv.get_api_version(mv.MESSAGES_PAGINATION)
|
||||
req.environ['cinder.context'].is_admin = True
|
||||
|
||||
res = self.controller.index(req)
|
||||
@ -210,8 +213,8 @@ class MessageApiTest(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank(url)
|
||||
req.method = 'GET'
|
||||
req.content_type = 'application/json'
|
||||
req.headers["OpenStack-API-Version"] = "volume 3.5"
|
||||
req.api_version_request = api_version.APIVersionRequest('3.5')
|
||||
req.headers = mv.get_mv_header(mv.MESSAGES_PAGINATION)
|
||||
req.api_version_request = mv.get_api_version(mv.MESSAGES_PAGINATION)
|
||||
req.environ['cinder.context'].is_admin = True
|
||||
|
||||
res = self.controller.index(req)
|
||||
@ -242,8 +245,8 @@ class MessageApiTest(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank(url)
|
||||
req.method = 'GET'
|
||||
req.content_type = 'application/json'
|
||||
req.headers = {version_header_name: 'volume 3.5'}
|
||||
req.api_version_request = api_version.APIVersionRequest('3.30')
|
||||
req.headers = mv.get_mv_header(mv.MESSAGES_PAGINATION)
|
||||
req.api_version_request = mv.get_api_version(mv.RESOURCE_FILTER)
|
||||
req.environ['cinder.context'].is_admin = True
|
||||
|
||||
res = self.controller.index(req)
|
||||
@ -263,7 +266,7 @@ class MessageApiTest(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank(url)
|
||||
req.method = 'GET'
|
||||
req.content_type = 'application/json'
|
||||
req.headers = {version_header_name: 'volume 3.5'}
|
||||
req.headers = mv.get_mv_header(mv.MESSAGES_PAGINATION)
|
||||
req.api_version_request = api_version.max_api_version()
|
||||
req.environ['cinder.context'].is_admin = True
|
||||
|
||||
|
@ -1909,20 +1909,20 @@ class API(base.Base):
|
||||
def _check_boolean_filter_value(self, key, val, strict=False):
|
||||
"""Boolean filter values in Volume GET.
|
||||
|
||||
Before V3.2, all values other than 'False', 'false', 'FALSE' were
|
||||
trated as True for specific boolean filter parameters in Volume
|
||||
GET request.
|
||||
Before VOLUME_LIST_BOOTABLE, all values other than 'False', 'false',
|
||||
'FALSE' were trated as True for specific boolean filter parameters in
|
||||
Volume GET request.
|
||||
|
||||
But V3.2 onwards, only true/True/0/1/False/false parameters are
|
||||
supported.
|
||||
But VOLUME_LIST_BOOTABLE onwards, only true/True/0/1/False/false
|
||||
parameters are supported.
|
||||
All other input values to specific boolean filter parameter will
|
||||
lead to raising exception.
|
||||
|
||||
This changes API behavior. So, micro version introduced for V3.2
|
||||
onwards.
|
||||
This changes API behavior. So, micro version introduced for
|
||||
VOLUME_LIST_BOOTABLE onwards.
|
||||
"""
|
||||
if strict:
|
||||
# for updated behavior, from V3.2 onwards.
|
||||
# for updated behavior, from VOLUME_LIST_BOOTABLE onwards.
|
||||
# To translate any true/false/t/f/0/1 to True/False
|
||||
# which is only acceptable format in database queries.
|
||||
try:
|
||||
@ -1932,7 +1932,7 @@ class API(base.Base):
|
||||
'value': val}
|
||||
raise exception.InvalidInput(reason=msg)
|
||||
else:
|
||||
# For existing behavior(before version 3.2)
|
||||
# For existing behavior(before version VOLUME_LIST_BOOTABLE)
|
||||
accepted_true = ['True', 'true', 'TRUE']
|
||||
accepted_false = ['False', 'false', 'FALSE']
|
||||
|
||||
|
@ -278,8 +278,17 @@ necessary to add changes to other places which describe your change:
|
||||
be enough information that it could be used by the docs team for
|
||||
release notes.
|
||||
|
||||
* Constants should be used in the code to minimize errors on microversion
|
||||
merge conflicts. Define a constant for the new microversion in the
|
||||
``cinder/api/microversions.py`` file and use that in the rest of the code.
|
||||
|
||||
* Update the expected versions in affected tests.
|
||||
|
||||
* API changes should almost always include a release note announcing the
|
||||
availability of the new API functionality. The description of the API change
|
||||
should indicate which microversion is required for the change, and it should
|
||||
refer to the numerical value of the microversion and not its constant name.
|
||||
|
||||
Allocating a microversion
|
||||
-------------------------
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user