Coverage for manila/api/openstack/api_version_request.py: 100%
67 statements
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2026-02-18 22:19 +0000
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.
17import re
19from manila.api.openstack import versioned_method
20from manila import exception
21from manila.i18n import _
22from manila import utils
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.
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 = """
45 REST API Version History:
47 * 1.0 - Initial version. Includes all V1 APIs and extensions in Kilo.
48 * 2.0 - Versions API updated to reflect beginning of microversions epoch.
49 * 2.1 - Share create() doesn't ignore availability_zone field of share.
50 * 2.2 - Snapshots become optional feature.
51 * 2.3 - Share instances admin API
52 * 2.4 - Consistency Group support
53 * 2.5 - Share Migration admin API
54 * 2.6 - Return share_type UUID instead of name in Share API
55 * 2.7 - Rename old extension-like API URLs to core-API-like
56 * 2.8 - Attr "is_public" can be set for share using API "manage"
57 * 2.9 - Add export locations API
58 * 2.10 - Field 'access_rules_status' was added to shares and share
59 instances.
60 * 2.11 - Share Replication support
61 * 2.12 - Manage/unmanage snapshot API.
62 * 2.13 - Add "cephx" auth type to allow_access
63 * 2.14 - 'Preferred' attribute in export location metadata
64 * 2.15 - Added Share migration 'migration_cancel',
65 'migration_get_progress', 'migration_complete' APIs, renamed
66 'migrate_share' to 'migration_start' and added notify parameter
67 to 'migration_start'.
68 * 2.16 - Add user_id in share show/create/manage API.
69 * 2.17 - Added project_id and user_id fields to the JSON response of
70 snapshot show/create/manage API.
71 * 2.18 - Add gateway to the JSON response of share network show API.
72 * 2.19 - Share snapshot instances admin APIs
73 (list/show/detail/reset-status).
74 * 2.20 - Add MTU to the JSON response of share network show API.
75 * 2.21 - Add access_key to the response of access_list API.
76 * 2.22 - Updated migration_start API with 'preserve-metadata', 'writable',
77 'nondisruptive' and 'new_share_network_id' parameters, renamed
78 'force_host_copy' to 'force_host_assisted_migration', removed
79 'notify' parameter and removed previous migrate_share API support.
80 Updated reset_task_state API to accept 'None' value.
81 * 2.23 - Added share_type to filter results of scheduler-stats/pools API.
82 * 2.24 - Added optional create_share_from_snapshot_support extra spec,
83 which was previously inferred from the 'snapshot_support' extra
84 spec. Also made the 'snapshot_support' extra spec optional.
85 * 2.25 - Added quota-show detail API.
86 * 2.26 - Removed 'nova_net_id' parameter from share_network API.
87 * 2.27 - Added share revert to snapshot API.
88 * 2.28 - Added transitional states to access rules and replaced all
89 transitional access_rules_status values of
90 shares (share_instances) with 'syncing'. Share action API
91 'access_allow' now accepts rules even when a share or any of
92 its instances may have an access_rules_status set to 'error'.
93 * 2.29 - Updated migration_start API adding mandatory parameter
94 'preserve_snapshots' and changed 'preserve_metadata', 'writable',
95 'nondisruptive' to be mandatory as well. All previous
96 migration_start APIs prior to this microversion are now
97 unsupported.
98 * 2.30 - Added cast_rules_to_readonly field to share_instances.
99 * 2.31 - Convert consistency groups to share groups.
100 * 2.32 - Added mountable snapshots APIs.
101 * 2.33 - Added 'created_at' and 'updated_at' to the response of
102 access_list API.
103 * 2.34 - Added 'availability_zone_id' and 'consistent_snapshot_support'
104 fields to 'share_group' object.
105 * 2.35 - Added support to retrieve shares filtered by export_location_id
106 and export_location_path.
107 * 2.36 - Added like filter support in ``shares``, ``snapshots``,
108 ``share-networks``, ``share-groups`` list APIs.
109 * 2.37 - Added /messages APIs.
110 * 2.38 - Support IPv6 validation in allow_access API to enable IPv6 in
111 manila.
112 * 2.39 - Added share-type quotas.
113 * 2.40 - Added share group and share group snapshot quotas.
114 * 2.41 - Added 'description' in share type create/list APIs.
115 * 2.42 - Added ``with_count`` in share list API to get total count info.
116 * 2.43 - Added filter search by extra spec for share type list.
117 * 2.44 - Added 'ou' field to 'security_service' object.
118 * 2.45 - Added access metadata for share access and also introduced
119 the GET /share-access-rules API. The prior API to retrieve
120 access rules will not work with API version >=2.45.
121 * 2.46 - Added 'is_default' field to 'share_type' and 'share_group_type'
122 objects.
123 * 2.47 - Export locations for non-active share replicas are no longer
124 retrievable through the export locations APIs:
125 GET /v2/{tenant_id}/shares/{share_id}/export_locations and
126 GET /v2/{tenant_id}/shares/{share_id}/export_locations/{
127 export_location_id}. A new API is introduced at this
128 version: GET /v2/{tenant_id}/share-replicas/{
129 replica_id}/export-locations to allow retrieving individual
130 replica export locations if available.
131 * 2.48 - Added support for extra-spec "availability_zones" within Share
132 types along with validation in the API.
133 * 2.49 - Added Manage/Unmanage Share Server APIs. Updated Manage/Unmanage
134 Shares and Snapshots APIs to work in
135 ``driver_handles_shares_servers`` enabled mode.
136 * 2.50 - Added update share type API to Share Type APIs. Through this API
137 we can update the ``name``, ``description`` and/or
138 ``share_type_access:is_public`` fields of the share type.
139 * 2.51 - Added Share Network with multiple Subnets. Updated Share Networks
140 to handle with one or more subnets in different availability
141 zones.
142 * 2.52 - Added 'created_before' and 'created_since' field to list messages
143 filters, support querying user messages within the specified time
144 period.
145 * 2.53 - Added quota control to share replicas.
146 * 2.54 - Share and share instance objects include a new field called
147 "progress" which indicates the completion of a share creation
148 operation as a percentage.
149 * 2.55 - Share groups feature is no longer considered experimental.
150 * 2.56 - Share replication feature is no longer considered experimental.
151 * 2.57 - Added Share server migration operations:
152 'share_server_migration_check'
153 'share_server_migration_cancel'
154 'share_server_migration_complete'
155 'share_server_migration_start'
156 'share_server_migration_get_progress'
157 'share_server_reset_task_state'
158 * 2.58 - Added 'share_groups' and 'share_group_snapshots' to the limits
159 view.
160 * 2.59 - Add driver ``details`` field to migration get progress.
161 * 2.60 - API URLs no longer need to include a project_id parameter.
162 * 2.61 - Added optional provisioning:max_share_size and
163 provisioning:min_share_size extra specs,
164 which can add minimum and maximum share size restrictions
165 on a per share-type granularity.
166 * 2.62 - Added quota control to per share size.
167 * 2.63 - Changed the existing behavior of 'add_security_service' action on
168 the share network's endpoint to allow the addition of security
169 services, even when the share network is in use. Also, added new
170 actions on the share network's endpoint:
171 'update_security_service', 'update_security_service_check' and
172 'add_security_service_check'.
173 * 2.64 - Added 'force' field to extend share api, which can extend share
174 directly without validation through share scheduler.
175 * 2.65 - Added ability to set affinity scheduler hints via the share
176 create API.
177 * 2.66 - Added filter search by group spec for share group type list.
178 * 2.67 - Added ability to set 'only_host' scheduler hint for the share
179 create and share replica create API.
180 * 2.68 - Added admin only capabilities to share metadata API
181 * 2.69 - Added new share action to soft delete share to recycle bin or
182 restore share from recycle bin. Also, a new parameter called
183 `is_soft_deleted` was added so users can filter out
184 shares in the recycle bin while listing shares.
185 * 2.70 - Added support for multiple share network subnets in the same
186 availability zone. Also, users can add subnets for an in-use share
187 network.
188 * 2.71 - Added 'updated_at' field in share instance show API output.
189 * 2.72 - Added new option ``share-network`` to share replica creare API.
190 * 2.73 - Added Share Snapshot Metadata to Metadata API
191 * 2.74 - Allow/deny share access rule even if share replicas are in
192 'error' state.
193 * 2.75 - Added option to specify quiesce wait time in share replica
194 promote API.
195 * 2.76 - Added 'default_ad_site' field in security service object.
196 * 2.77 - Added support for share transfer between different projects.
197 * 2.78 - Added Share Network Subnet Metadata to Metadata API.
198 * 2.79 - Added ``with_count`` in share snapshot list API to get total
199 count info.
200 * 2.80 - Added share backup APIs.
201 * 2.81 - Added API methods, endpoint /resource-locks.
202 * 2.82 - Added lock and restriction to share access rules.
203 * 2.83 - Added 'disabled_reason' field to services.
204 * 2.84 - Added mount_point_name to shares.
205 * 2.85 - Added backup_type field to share backups.
206 * 2.86 - Add ensure share API.
207 * 2.87 - Added Share export location metadata API
208 * 2.88 - Added support for update Share access rule.
209 * 2.89 - Added support for passing Share network subnet metadata updates
210 to driver.
211 * 2.90 - Added encryption key reference option to share create API.
212 * 2.91 - Added support for targeted restores via the share backup API
213"""
215# The minimum and maximum versions of the API supported
216# The default api version request is defined to be the
217# minimum version of the API supported.
218_MIN_API_VERSION = "2.0"
219_MAX_API_VERSION = "2.91"
220DEFAULT_API_VERSION = _MIN_API_VERSION
223# NOTE(cyeoh): min and max versions declared as functions so we can
224# mock them for unittests. Do not use the constants directly anywhere
225# else.
226def min_api_version():
227 return APIVersionRequest(_MIN_API_VERSION)
230def max_api_version():
231 return APIVersionRequest(_MAX_API_VERSION)
234class APIVersionRequest(utils.ComparableMixin):
235 """This class represents an API Version Request.
237 This class includes convenience methods for manipulation
238 and comparison of version numbers as needed to implement
239 API microversions.
240 """
242 def __init__(self, version_string=None, experimental=False):
243 """Create an API version request object."""
244 self._ver_major = None
245 self._ver_minor = None
246 self._experimental = experimental
248 if version_string is not None:
249 match = re.match(r"^([1-9]\d*)\.([1-9]\d*|0)$",
250 version_string)
251 if match:
252 self._ver_major = int(match.group(1))
253 self._ver_minor = int(match.group(2))
254 else:
255 raise exception.InvalidAPIVersionString(version=version_string)
257 def __str__(self):
258 """Debug/Logging representation of object."""
259 params = {
260 'major': self._ver_major,
261 'minor': self._ver_minor,
262 'experimental': self._experimental,
263 }
264 return ("API Version Request Major: %(major)s, Minor: %(minor)s, "
265 "Experimental: %(experimental)s" % params)
267 def is_null(self):
268 return self._ver_major is None and self._ver_minor is None
270 def _cmpkey(self):
271 """Return the value used by ComparableMixin for rich comparisons."""
272 return self._ver_major, self._ver_minor
274 @property
275 def experimental(self):
276 return self._experimental
278 @experimental.setter
279 def experimental(self, value):
280 if not isinstance(value, bool):
281 msg = _('The experimental property must be a bool value.')
282 raise exception.InvalidParameterValue(err=msg)
283 self._experimental = value
285 def matches_versioned_method(self, method):
286 """Compares this version to that of a versioned method."""
288 if not isinstance(method, versioned_method.VersionedMethod):
289 msg = _('An API version request must be compared '
290 'to a VersionedMethod object.')
291 raise exception.InvalidParameterValue(err=msg)
293 return self.matches(method.start_version,
294 method.end_version,
295 method.experimental)
297 def matches(self, min_version, max_version, experimental=False):
298 """Compares this version to the specified min/max range.
300 Returns whether the version object represents a version
301 greater than or equal to the minimum version and less than
302 or equal to the maximum version.
304 If min_version is null then there is no minimum limit.
305 If max_version is null then there is no maximum limit.
306 If self is null then raise ValueError.
308 :param min_version: Minimum acceptable version.
309 :param max_version: Maximum acceptable version.
310 :param experimental: Whether to match experimental APIs.
311 :returns: boolean
312 """
314 if self.is_null():
315 raise ValueError
316 # NOTE(cknight): An experimental request should still match a
317 # non-experimental API, so the experimental check isn't just
318 # looking for equality.
319 if not self.experimental and experimental:
320 return False
322 if isinstance(min_version, str):
323 min_version = APIVersionRequest(version_string=min_version)
324 if isinstance(max_version, str):
325 max_version = APIVersionRequest(version_string=max_version)
327 if not (min_version or max_version):
328 return True
329 elif (min_version and max_version and
330 max_version.is_null() and min_version.is_null()):
331 return True
333 elif not max_version or max_version.is_null():
334 return min_version <= self
335 elif not min_version or min_version.is_null():
336 return self <= max_version
337 else:
338 return min_version <= self <= max_version
340 def get_string(self):
341 """Returns a string representation of this object.
343 If this method is used to create an APIVersionRequest,
344 the resulting object will be an equivalent request.
345 """
346 if self.is_null():
347 raise ValueError
348 return ("%(major)s.%(minor)s" %
349 {'major': self._ver_major, 'minor': self._ver_minor})