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

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 manila.api.openstack import versioned_method 

20from manila import exception 

21from manila.i18n import _ 

22from manila 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 * 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""" 

214 

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 

221 

222 

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) 

228 

229 

230def max_api_version(): 

231 return APIVersionRequest(_MAX_API_VERSION) 

232 

233 

234class APIVersionRequest(utils.ComparableMixin): 

235 """This class represents an API Version Request. 

236 

237 This class includes convenience methods for manipulation 

238 and comparison of version numbers as needed to implement 

239 API microversions. 

240 """ 

241 

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 

247 

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) 

256 

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) 

266 

267 def is_null(self): 

268 return self._ver_major is None and self._ver_minor is None 

269 

270 def _cmpkey(self): 

271 """Return the value used by ComparableMixin for rich comparisons.""" 

272 return self._ver_major, self._ver_minor 

273 

274 @property 

275 def experimental(self): 

276 return self._experimental 

277 

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 

284 

285 def matches_versioned_method(self, method): 

286 """Compares this version to that of a versioned method.""" 

287 

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) 

292 

293 return self.matches(method.start_version, 

294 method.end_version, 

295 method.experimental) 

296 

297 def matches(self, min_version, max_version, experimental=False): 

298 """Compares this version to the specified min/max range. 

299 

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. 

303 

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. 

307 

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 """ 

313 

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 

321 

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) 

326 

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 

332 

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 

339 

340 def get_string(self): 

341 """Returns a string representation of this object. 

342 

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})