Merge "Use constants for microversion values"
This commit is contained in:
commit
470011b314
@ -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')
|
||||
@ -178,10 +179,10 @@ class GroupsAPITestCase(test.TestCase):
|
||||
res_dict = self.controller.detail(req)
|
||||
|
||||
# If the microversion >= 3.25 and "list_volume=True", "volumes" should
|
||||
# be contained in the response body. Else,"volumes" should not be
|
||||
# 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' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
version='3.24')
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/v3/%s/groups/%s?list_volume=True' %
|
||||
(fake.PROJECT_ID, self.group1.id),
|
||||
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,11 +198,12 @@ class VolumeApiTest(test.TestCase):
|
||||
self.assertEqual(expected, res_dict)
|
||||
|
||||
@ddt.data(
|
||||
('3.35', {'volume-summary': {'total_size': 0.0,
|
||||
'total_count': 0}}),
|
||||
('3.36', {'volume-summary': {'total_size': 0.0,
|
||||
'total_count': 0,
|
||||
'metadata': {}}}))
|
||||
(mv.get_prior_version(mv.VOLUME_SUMMARY_METADATA),
|
||||
{'volume-summary': {'total_size': 0.0,
|
||||
'total_count': 0}}),
|
||||
(mv.VOLUME_SUMMARY_METADATA, {'volume-summary': {'total_size': 0.0,
|
||||
'total_count': 0,
|
||||
'metadata': {}}}))
|
||||
@ddt.unpack
|
||||
def test_volume_summary_empty(self, summary_api_version, expect_result):
|
||||
req = self._fake_volumes_summary_request(version=summary_api_version)
|
||||
@ -208,13 +211,15 @@ class VolumeApiTest(test.TestCase):
|
||||
self.assertEqual(expect_result, res_dict)
|
||||
|
||||
@ddt.data(
|
||||
('3.35', {'volume-summary': {'total_size': 2,
|
||||
'total_count': 2}}),
|
||||
('3.36', {'volume-summary': {'total_size': 2,
|
||||
'total_count': 2,
|
||||
'metadata': {
|
||||
'name': ['test_name1', 'test_name2'],
|
||||
'age': ['test_age']}}}))
|
||||
(mv.get_prior_version(mv.VOLUME_SUMMARY_METADATA),
|
||||
{'volume-summary': {'total_size': 2,
|
||||
'total_count': 2}}),
|
||||
(mv.VOLUME_SUMMARY_METADATA,
|
||||
{'volume-summary': {'total_size': 2,
|
||||
'total_count': 2,
|
||||
'metadata': {
|
||||
'name': ['test_name1', 'test_name2'],
|
||||
'age': ['test_age']}}}))
|
||||
@ddt.unpack
|
||||
def test_volume_summary_return_metadata(self, summary_api_version,
|
||||
expect_result):
|
||||
@ -230,13 +235,15 @@ class VolumeApiTest(test.TestCase):
|
||||
self.assertEqual(expect_result, res_dict)
|
||||
|
||||
@ddt.data(
|
||||
('3.35', {'volume-summary': {'total_size': 2,
|
||||
'total_count': 2}}),
|
||||
('3.36', {'volume-summary': {'total_size': 2,
|
||||
'total_count': 2,
|
||||
'metadata': {
|
||||
'name': ['test_name1', 'test_name2'],
|
||||
'age': ['test_age']}}}))
|
||||
(mv.get_prior_version(mv.VOLUME_SUMMARY_METADATA),
|
||||
{'volume-summary': {'total_size': 2,
|
||||
'total_count': 2}}),
|
||||
(mv.VOLUME_SUMMARY_METADATA,
|
||||
{'volume-summary': {'total_size': 2,
|
||||
'total_count': 2,
|
||||
'metadata': {
|
||||
'name': ['test_name1', 'test_name2'],
|
||||
'age': ['test_age']}}}))
|
||||
@ddt.unpack
|
||||
def test_volume_summary_return_metadata_all_tenant(
|
||||
self, summary_api_version, expect_result):
|
||||
@ -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
|
||||
|
||||
|
@ -1910,20 +1910,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:
|
||||
@ -1933,7 +1933,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