1# Copyright 2014 IBM Corp. 2# Copyright 2015 Clinton Knight 3# All Rights Reserved. 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); you may 6# not use this file except in compliance with the License. You may obtain 7# a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14# License for the specific language governing permissions and limitations 15# under the License. 16 17import re 18 19from cinder.api.openstack import versioned_method 20from cinder import exception 21from cinder.i18n import _ 22from cinder import utils 23 24# Define the minimum and maximum version of the API across all of the 25# REST API. The format of the version is: 26# X.Y where: 27# 28# - X will only be changed if a significant backwards incompatible API 29# change is made which affects the API as whole. That is, something 30# that is only very very rarely incremented. 31# 32# - Y when you make any change to the API. Note that this includes 33# semantic changes which may not affect the input or output formats or 34# even originate in the API code layer. We are not distinguishing 35# between backwards compatible and backwards incompatible changes in 36# the versioning system. It must be made clear in the documentation as 37# to what is a backwards compatible change and what is a backwards 38# incompatible one. 39 40# 41# You must update the API version history string below with a one or 42# two line description as well as update rest_api_version_history.rst 43REST_API_VERSION_HISTORY = """ 44 45 REST API Version History: 46 47 * 3.0 - Includes all V2 APIs and extensions. V1 API is still supported. 48 * 3.0 - Versions API updated to reflect beginning of microversions epoch. 49 * 3.1 - Adds visibility and protected to _volume_upload_image parameters. 50 * 3.2 - Bootable filters in volume GET call no longer treats all values 51 passed to it as true. 52 * 3.3 - Add user messages APIs. 53 * 3.4 - Adds glance_metadata filter to list/detail volumes in _get_volumes. 54 * 3.5 - Add pagination support to messages API. 55 * 3.6 - Allows to set empty description and empty name for consistency 56 group in consisgroup-update operation. 57 * 3.7 - Add cluster API and cluster_name field to service list API 58 * 3.8 - Adds resources from volume_manage and snapshot_manage extensions. 59 * 3.9 - Add backup update interface. 60 * 3.10 - Add group_id filter to list/detail volumes in _get_volumes. 61 * 3.11 - Add group types and group specs API. 62 * 3.12 - Add volumes summary API. 63 * 3.13 - Add generic volume groups API. 64 * 3.14 - Add group snapshot and create group from src APIs. 65 * 3.15 - Inject the response's `Etag` header to avoid the lost update 66 problem with volume metadata. 67 * 3.16 - Migrate volume now supports cluster 68 * 3.17 - Getting manageable volumes and snapshots now accepts cluster. 69 * 3.18 - Add backup project attribute. 70 * 3.19 - Add API reset status actions 'reset_status' to group snapshot. 71 * 3.20 - Add API reset status actions 'reset_status' to generic 72 volume group. 73 * 3.21 - Show provider_id in detailed view of a volume for admin. 74 * 3.22 - Add filtering based on metadata for snapshot listing. 75 * 3.23 - Allow passing force parameter to volume delete. 76 * 3.24 - Add workers/cleanup endpoint. 77 * 3.25 - Add ``volumes`` field to group list/detail and group show. 78 * 3.26 - Add failover action and cluster listings accept new filters and 79 return new data. 80 * 3.27 - Add attachment API 81 * 3.28 - Add filters support to get_pools 82 * 3.29 - Add filter, sorter and pagination support in group snapshot. 83 * 3.30 - Support sort snapshots with "name". 84 * 3.31 - Add support for configure resource query filters. 85 * 3.32 - Add set-log and get-log service actions. 86 * 3.33 - Add ``resource_filters`` API to retrieve configured 87 resource filters. 88 * 3.34 - Add like filter support in ``volume``, ``backup``, ``snapshot``, 89 ``message``, ``attachment``, ``group`` and ``group-snapshot`` 90 list APIs. 91 * 3.35 - Add ``volume-type`` filter to Get-Pools API. 92 * 3.36 - Add metadata to volumes/summary response body. 93 * 3.37 - Support sort backup by "name". 94 * 3.38 - Add replication group API (Tiramisu). 95 * 3.39 - Add ``project_id`` admin filters support to limits. 96 * 3.40 - Add volume revert to its latest snapshot support. 97 * 3.41 - Add ``user_id`` field to snapshot list/detail and snapshot show. 98 * 3.42 - Add ability to extend 'in-use' volume. User should be aware of the 99 whole environment before using this feature because it's dependent 100 on several external factors below: 101 1. nova-compute version - needs to be the latest for Pike. 102 2. only the libvirt compute driver supports this currently. 103 3. only iscsi and fibre channel volume types are supported 104 on the nova side currently. 105 Administrator can disable this ability by updating the 106 'volume:extend_attached_volume' policy rule. Extend in reserved 107 state is intentionally NOT allowed. 108 * 3.43 - Support backup CRUD with metadata. 109 * 3.44 - Add attachment-complete. 110 * 3.45 - Add ``count`` field to volume, backup and snapshot list and 111 detail APIs. 112 * 3.46 - Support create volume by Nova specific image (0 size image). 113 * 3.47 - Support create volume from backup. 114 * 3.48 - Add ``shared_targets`` and ``service_uuid`` fields to volume. 115 * 3.49 - Support report backend storage state in service list. 116 * 3.50 - Add multiattach capability 117""" 118 119# The minimum and maximum versions of the API supported 120# The default api version request is defined to be the 121# minimum version of the API supported. 122# Explicitly using /v2 endpoints will still work 123_MIN_API_VERSION = "3.0" 124_MAX_API_VERSION = "3.50" 125_LEGACY_API_VERSION2 = "2.0" 126UPDATED = "2017-09-19T20:18:14Z" 127 128 129# NOTE(cyeoh): min and max versions declared as functions so we can 130# mock them for unittests. Do not use the constants directly anywhere 131# else. 132def min_api_version(): 133 return APIVersionRequest(_MIN_API_VERSION) 134 135 136def max_api_version(): 137 return APIVersionRequest(_MAX_API_VERSION) 138 139 140def legacy_api_version2(): 141 return APIVersionRequest(_LEGACY_API_VERSION2) 142 143 144class APIVersionRequest(utils.ComparableMixin): 145 """This class represents an API Version Request. 146 147 This class includes convenience methods for manipulation 148 and comparison of version numbers as needed to implement 149 API microversions. 150 """ 151 152 def __init__(self, version_string=None, experimental=False): 153 """Create an API version request object.""" 154 self._ver_major = None 155 self._ver_minor = None 156 157 if version_string is not None: 158 match = re.match(r"^([1-9]\d*)\.([1-9]\d*|0)$", 159 version_string) 160 if match: 161 self._ver_major = int(match.group(1)) 162 self._ver_minor = int(match.group(2)) 163 else: 164 raise exception.InvalidAPIVersionString(version=version_string) 165 166 def __str__(self): 167 """Debug/Logging representation of object.""" 168 return ("API Version Request Major: %(major)s, Minor: %(minor)s" 169 % {'major': self._ver_major, 'minor': self._ver_minor}) 170 171 def __bool__(self): 172 return (self._ver_major or self._ver_minor) is not None 173 174 __nonzero__ = __bool__ 175 176 def _cmpkey(self): 177 """Return the value used by ComparableMixin for rich comparisons.""" 178 return self._ver_major, self._ver_minor 179 180 def matches_versioned_method(self, method): 181 """Compares this version to that of a versioned method.""" 182 183 if type(method) != versioned_method.VersionedMethod: 184 msg = _('An API version request must be compared ' 185 'to a VersionedMethod object.') 186 raise exception.InvalidParameterValue(err=msg) 187 188 return self.matches(method.start_version, 189 method.end_version, 190 method.experimental) 191 192 def matches(self, min_version, max_version=None, experimental=False): 193 """Compares this version to the specified min/max range. 194 195 Returns whether the version object represents a version 196 greater than or equal to the minimum version and less than 197 or equal to the maximum version. 198 199 If min_version is null then there is no minimum limit. 200 If max_version is null then there is no maximum limit. 201 If self is null then raise ValueError. 202 203 :param min_version: Minimum acceptable version. 204 :param max_version: Maximum acceptable version. 205 :param experimental: Whether to match experimental APIs. 206 :returns: boolean 207 """ 208 209 if not self: 210 raise ValueError 211 212 if isinstance(min_version, str): 213 min_version = APIVersionRequest(version_string=min_version) 214 if isinstance(max_version, str): 215 max_version = APIVersionRequest(version_string=max_version) 216 217 if not min_version and not max_version: 218 return True 219 220 if not max_version: 221 return min_version <= self 222 if not min_version: 223 return self <= max_version 224 return min_version <= self <= max_version 225 226 def get_string(self): 227 """Returns a string representation of this object. 228 229 If this method is used to create an APIVersionRequest, 230 the resulting object will be an equivalent request. 231 """ 232 if not self: 233 raise ValueError 234 return ("%(major)s.%(minor)s" % 235 {'major': self._ver_major, 'minor': self._ver_minor}) 236