python-openstackclient 9.0.0__py3-none-any.whl → 10.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (284) hide show
  1. openstackclient/__init__.py +2 -6
  2. openstackclient/api/api.py +41 -23
  3. openstackclient/api/compute_v2.py +44 -25
  4. openstackclient/api/object_store_v1.py +75 -97
  5. openstackclient/api/volume_v2.py +2 -1
  6. openstackclient/api/volume_v3.py +2 -1
  7. openstackclient/common/availability_zone.py +58 -42
  8. openstackclient/common/clientmanager.py +56 -29
  9. openstackclient/common/configuration.py +10 -3
  10. openstackclient/common/envvars.py +2 -2
  11. openstackclient/common/extension.py +14 -5
  12. openstackclient/common/limits.py +10 -5
  13. openstackclient/common/module.py +14 -6
  14. openstackclient/common/pagination.py +8 -2
  15. openstackclient/common/progressbar.py +7 -6
  16. openstackclient/common/project_cleanup.py +13 -7
  17. openstackclient/common/quota.py +97 -99
  18. openstackclient/common/versions.py +8 -2
  19. openstackclient/compute/client.py +7 -3
  20. openstackclient/compute/v2/agent.py +17 -10
  21. openstackclient/compute/v2/aggregate.py +36 -22
  22. openstackclient/compute/v2/console.py +14 -8
  23. openstackclient/compute/v2/console_connection.py +11 -3
  24. openstackclient/compute/v2/flavor.py +39 -21
  25. openstackclient/compute/v2/host.py +14 -6
  26. openstackclient/compute/v2/hypervisor.py +14 -5
  27. openstackclient/compute/v2/hypervisor_stats.py +10 -2
  28. openstackclient/compute/v2/keypair.py +29 -14
  29. openstackclient/compute/v2/server.py +249 -169
  30. openstackclient/compute/v2/server_backup.py +10 -4
  31. openstackclient/compute/v2/server_event.py +21 -12
  32. openstackclient/compute/v2/server_group.py +21 -11
  33. openstackclient/compute/v2/server_image.py +19 -10
  34. openstackclient/compute/v2/server_migration.py +24 -10
  35. openstackclient/compute/v2/server_share.py +274 -0
  36. openstackclient/compute/v2/server_volume.py +10 -4
  37. openstackclient/compute/v2/service.py +14 -7
  38. openstackclient/compute/v2/usage.py +26 -21
  39. openstackclient/identity/client.py +8 -3
  40. openstackclient/identity/common.py +78 -47
  41. openstackclient/identity/v2_0/catalog.py +14 -7
  42. openstackclient/identity/v2_0/ec2creds.py +21 -10
  43. openstackclient/identity/v2_0/endpoint.py +23 -11
  44. openstackclient/identity/v2_0/project.py +25 -14
  45. openstackclient/identity/v2_0/role.py +28 -14
  46. openstackclient/identity/v2_0/role_assignment.py +9 -3
  47. openstackclient/identity/v2_0/service.py +23 -11
  48. openstackclient/identity/v2_0/token.py +12 -5
  49. openstackclient/identity/v2_0/user.py +26 -15
  50. openstackclient/identity/v3/access_rule.py +26 -12
  51. openstackclient/identity/v3/application_credential.py +59 -24
  52. openstackclient/identity/v3/catalog.py +14 -7
  53. openstackclient/identity/v3/consumer.py +22 -11
  54. openstackclient/identity/v3/credential.py +36 -16
  55. openstackclient/identity/v3/domain.py +37 -18
  56. openstackclient/identity/v3/ec2creds.py +25 -12
  57. openstackclient/identity/v3/endpoint.py +42 -20
  58. openstackclient/identity/v3/endpoint_group.py +28 -17
  59. openstackclient/identity/v3/federation_protocol.py +38 -16
  60. openstackclient/identity/v3/group.py +55 -32
  61. openstackclient/identity/v3/identity_provider.py +92 -57
  62. openstackclient/identity/v3/implied_role.py +21 -9
  63. openstackclient/identity/v3/limit.py +38 -16
  64. openstackclient/identity/v3/mapping.py +26 -13
  65. openstackclient/identity/v3/policy.py +23 -12
  66. openstackclient/identity/v3/project.py +43 -23
  67. openstackclient/identity/v3/region.py +36 -16
  68. openstackclient/identity/v3/registered_limit.py +40 -16
  69. openstackclient/identity/v3/role.py +61 -31
  70. openstackclient/identity/v3/role_assignment.py +23 -6
  71. openstackclient/identity/v3/service.py +36 -16
  72. openstackclient/identity/v3/service_provider.py +37 -15
  73. openstackclient/identity/v3/tag.py +23 -6
  74. openstackclient/identity/v3/token.py +30 -14
  75. openstackclient/identity/v3/trust.py +32 -14
  76. openstackclient/identity/v3/unscoped_saml.py +10 -2
  77. openstackclient/identity/v3/user.py +49 -26
  78. openstackclient/image/client.py +7 -3
  79. openstackclient/image/v1/image.py +33 -26
  80. openstackclient/image/v2/cache.py +14 -9
  81. openstackclient/image/v2/image.py +74 -48
  82. openstackclient/image/v2/info.py +7 -1
  83. openstackclient/image/v2/metadef_namespaces.py +109 -13
  84. openstackclient/image/v2/metadef_objects.py +28 -15
  85. openstackclient/image/v2/metadef_properties.py +24 -13
  86. openstackclient/image/v2/metadef_resource_type_association.py +14 -7
  87. openstackclient/image/v2/metadef_resource_types.py +7 -1
  88. openstackclient/image/v2/task.py +15 -6
  89. openstackclient/locale/tr_TR/LC_MESSAGES/openstackclient.po +7 -192
  90. openstackclient/network/client.py +7 -2
  91. openstackclient/network/common.py +16 -241
  92. openstackclient/network/utils.py +36 -22
  93. openstackclient/network/v2/address_group.py +27 -16
  94. openstackclient/network/v2/address_scope.py +24 -13
  95. openstackclient/network/v2/bgpvpn/bgpvpn.py +463 -0
  96. openstackclient/network/v2/bgpvpn/constants.py +30 -0
  97. openstackclient/network/v2/bgpvpn/network_association.py +214 -0
  98. openstackclient/network/v2/bgpvpn/port_association.py +490 -0
  99. openstackclient/network/v2/bgpvpn/router_association.py +288 -0
  100. openstackclient/network/v2/default_security_group_rule.py +19 -10
  101. openstackclient/network/v2/floating_ip.py +110 -159
  102. openstackclient/network/v2/floating_ip_port_forwarding.py +30 -18
  103. openstackclient/network/v2/fwaas/__init__.py +0 -0
  104. openstackclient/network/v2/fwaas/group.py +466 -0
  105. openstackclient/network/v2/fwaas/policy.py +518 -0
  106. openstackclient/network/v2/fwaas/rule.py +574 -0
  107. openstackclient/network/v2/ip_availability.py +13 -5
  108. openstackclient/network/v2/l3_conntrack_helper.py +22 -13
  109. openstackclient/network/v2/local_ip.py +24 -13
  110. openstackclient/network/v2/local_ip_association.py +14 -7
  111. openstackclient/network/v2/ndp_proxy.py +20 -11
  112. openstackclient/network/v2/network.py +129 -196
  113. openstackclient/network/v2/network_agent.py +46 -25
  114. openstackclient/network/v2/network_auto_allocated_topology.py +22 -11
  115. openstackclient/network/v2/network_flavor.py +27 -16
  116. openstackclient/network/v2/network_flavor_profile.py +23 -12
  117. openstackclient/network/v2/network_meter.py +21 -10
  118. openstackclient/network/v2/network_meter_rule.py +21 -11
  119. openstackclient/network/v2/network_qos_policy.py +25 -15
  120. openstackclient/network/v2/network_qos_rule.py +32 -17
  121. openstackclient/network/v2/network_qos_rule_type.py +13 -5
  122. openstackclient/network/v2/network_rbac.py +23 -12
  123. openstackclient/network/v2/network_segment.py +20 -11
  124. openstackclient/network/v2/network_segment_range.py +56 -29
  125. openstackclient/network/v2/network_service_provider.py +7 -1
  126. openstackclient/network/v2/network_trunk.py +38 -22
  127. openstackclient/network/v2/port.py +54 -29
  128. openstackclient/network/v2/router.py +75 -52
  129. openstackclient/network/v2/security_group.py +87 -157
  130. openstackclient/network/v2/security_group_rule.py +100 -280
  131. openstackclient/network/v2/subnet.py +49 -28
  132. openstackclient/network/v2/subnet_pool.py +30 -17
  133. openstackclient/network/v2/taas/tap_flow.py +22 -11
  134. openstackclient/network/v2/taas/tap_mirror.py +22 -11
  135. openstackclient/network/v2/taas/tap_service.py +23 -12
  136. openstackclient/object/client.py +7 -2
  137. openstackclient/object/v1/account.py +13 -6
  138. openstackclient/object/v1/container.py +25 -15
  139. openstackclient/object/v1/object.py +25 -15
  140. openstackclient/py.typed +0 -0
  141. openstackclient/shell.py +46 -10
  142. openstackclient/tests/functional/base.py +55 -20
  143. openstackclient/tests/functional/common/test_extension.py +4 -0
  144. openstackclient/tests/functional/common/test_quota.py +3 -1
  145. openstackclient/tests/functional/compute/v2/common.py +14 -13
  146. openstackclient/tests/functional/compute/v2/test_flavor.py +3 -1
  147. openstackclient/tests/functional/compute/v2/test_server.py +3 -0
  148. openstackclient/tests/functional/identity/v2/common.py +10 -6
  149. openstackclient/tests/functional/identity/v2/test_role.py +4 -4
  150. openstackclient/tests/functional/identity/v3/common.py +25 -19
  151. openstackclient/tests/functional/identity/v3/test_group.py +20 -20
  152. openstackclient/tests/functional/identity/v3/test_idp.py +3 -1
  153. openstackclient/tests/functional/identity/v3/test_project.py +10 -10
  154. openstackclient/tests/functional/identity/v3/test_role.py +18 -18
  155. openstackclient/tests/functional/identity/v3/test_role_assignment.py +12 -12
  156. openstackclient/tests/functional/identity/v3/test_user.py +8 -8
  157. openstackclient/tests/functional/image/base.py +1 -6
  158. openstackclient/tests/functional/network/v2/common.py +5 -2
  159. openstackclient/tests/functional/network/v2/test_floating_ip.py +10 -4
  160. openstackclient/tests/functional/network/v2/test_ip_availability.py +4 -0
  161. openstackclient/tests/functional/network/v2/test_network_meter_rule.py +3 -2
  162. openstackclient/tests/functional/network/v2/test_network_segment.py +5 -0
  163. openstackclient/tests/functional/network/v2/test_subnet.py +13 -9
  164. openstackclient/tests/functional/object/v1/common.py +4 -0
  165. openstackclient/tests/functional/volume/v2/common.py +4 -0
  166. openstackclient/tests/functional/volume/v2/test_volume_snapshot.py +27 -11
  167. openstackclient/tests/functional/volume/v2/test_volume_type.py +2 -2
  168. openstackclient/tests/functional/volume/v3/common.py +4 -0
  169. openstackclient/tests/functional/volume/v3/test_volume_snapshot.py +11 -7
  170. openstackclient/tests/functional/volume/v3/test_volume_type.py +2 -2
  171. openstackclient/tests/unit/common/test_availability_zone.py +35 -49
  172. openstackclient/tests/unit/common/test_extension.py +2 -2
  173. openstackclient/tests/unit/common/test_module.py +12 -7
  174. openstackclient/tests/unit/common/test_project_cleanup.py +3 -1
  175. openstackclient/tests/unit/common/test_quota.py +6 -26
  176. openstackclient/tests/unit/compute/v2/fakes.py +25 -0
  177. openstackclient/tests/unit/compute/v2/test_flavor.py +28 -2
  178. openstackclient/tests/unit/compute/v2/test_keypair.py +6 -6
  179. openstackclient/tests/unit/compute/v2/test_server.py +11 -96
  180. openstackclient/tests/unit/compute/v2/test_server_share.py +287 -0
  181. openstackclient/tests/unit/identity/v3/fakes.py +3 -0
  182. openstackclient/tests/unit/identity/v3/test_group.py +4 -14
  183. openstackclient/tests/unit/identity/v3/test_identity_provider.py +303 -299
  184. openstackclient/tests/unit/identity/v3/test_user.py +4 -4
  185. openstackclient/tests/unit/image/v2/test_image.py +11 -11
  186. openstackclient/tests/unit/image/v2/test_metadef_namespaces.py +105 -6
  187. openstackclient/tests/unit/network/test_common.py +0 -155
  188. openstackclient/tests/unit/network/v2/bgpvpn/__init__.py +0 -0
  189. openstackclient/tests/unit/network/v2/bgpvpn/fakes.py +179 -0
  190. openstackclient/tests/unit/network/v2/bgpvpn/test_bgpvpn.py +584 -0
  191. openstackclient/tests/unit/network/v2/bgpvpn/test_network_association.py +285 -0
  192. openstackclient/tests/unit/network/v2/bgpvpn/test_port_association.py +384 -0
  193. openstackclient/tests/unit/network/v2/bgpvpn/test_router_association.py +297 -0
  194. openstackclient/tests/unit/network/v2/fwaas/__init__.py +0 -0
  195. openstackclient/tests/unit/network/v2/fwaas/test_group.py +897 -0
  196. openstackclient/tests/unit/network/v2/fwaas/test_policy.py +869 -0
  197. openstackclient/tests/unit/network/v2/fwaas/test_rule.py +980 -0
  198. openstackclient/tests/unit/network/v2/taas/{test_osc_tap_flow.py → test_tap_flow.py} +18 -25
  199. openstackclient/tests/unit/network/v2/taas/{test_osc_tap_mirror.py → test_tap_mirror.py} +19 -29
  200. openstackclient/tests/unit/network/v2/taas/{test_osc_tap_service.py → test_tap_service.py} +19 -29
  201. openstackclient/tests/unit/network/v2/test_address_group.py +2 -2
  202. openstackclient/tests/unit/network/v2/{test_floating_ip_network.py → test_floating_ip.py} +3 -2
  203. openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py +13 -13
  204. openstackclient/tests/unit/network/v2/test_network_agent.py +8 -4
  205. openstackclient/tests/unit/network/v2/test_network_auto_allocated_topology.py +3 -3
  206. openstackclient/tests/unit/network/v2/test_network_flavor.py +2 -2
  207. openstackclient/tests/unit/network/v2/test_network_qos_policy.py +1 -1
  208. openstackclient/tests/unit/network/v2/test_network_qos_rule.py +2 -2
  209. openstackclient/tests/unit/network/v2/test_network_rbac.py +1 -1
  210. openstackclient/tests/unit/network/v2/test_network_segment.py +1 -1
  211. openstackclient/tests/unit/network/v2/test_network_segment_range.py +7 -10
  212. openstackclient/tests/unit/network/v2/test_network_trunk.py +1 -1
  213. openstackclient/tests/unit/network/v2/test_router.py +8 -9
  214. openstackclient/tests/unit/network/v2/{test_security_group_network.py → test_security_group.py} +1 -20
  215. openstackclient/tests/unit/network/v2/{test_security_group_rule_network.py → test_security_group_rule.py} +7 -41
  216. openstackclient/tests/unit/network/v2/test_subnet.py +2 -1
  217. openstackclient/tests/unit/network/v2/test_subnet_pool.py +2 -1
  218. openstackclient/tests/unit/object/v1/fakes.py +8 -7
  219. openstackclient/tests/unit/object/v1/test_container.py +65 -101
  220. openstackclient/tests/unit/object/v1/test_container_all.py +8 -1
  221. openstackclient/tests/unit/object/v1/test_object.py +44 -84
  222. openstackclient/tests/unit/object/v1/test_object_all.py +8 -1
  223. openstackclient/tests/unit/test_hacking.py +108 -0
  224. openstackclient/tests/unit/volume/v2/fakes.py +1 -0
  225. openstackclient/tests/unit/volume/v2/test_volume_backup.py +1 -5
  226. openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +2 -1
  227. openstackclient/tests/unit/volume/v2/test_volume_type.py +2 -4
  228. openstackclient/tests/unit/volume/v3/fakes.py +1 -0
  229. openstackclient/tests/unit/volume/v3/test_volume.py +60 -3
  230. openstackclient/tests/unit/volume/v3/test_volume_attachment.py +1 -1
  231. openstackclient/tests/unit/volume/v3/test_volume_backup.py +1 -5
  232. openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +55 -1
  233. openstackclient/tests/unit/volume/v3/test_volume_type.py +2 -4
  234. openstackclient/volume/client.py +7 -3
  235. openstackclient/volume/v2/backup_record.py +15 -6
  236. openstackclient/volume/v2/consistency_group.py +29 -17
  237. openstackclient/volume/v2/consistency_group_snapshot.py +25 -10
  238. openstackclient/volume/v2/qos_specs.py +28 -17
  239. openstackclient/volume/v2/service.py +17 -6
  240. openstackclient/volume/v2/volume.py +57 -29
  241. openstackclient/volume/v2/volume_backend.py +19 -6
  242. openstackclient/volume/v2/volume_backup.py +46 -20
  243. openstackclient/volume/v2/volume_host.py +6 -4
  244. openstackclient/volume/v2/volume_snapshot.py +50 -24
  245. openstackclient/volume/v2/volume_transfer_request.py +31 -13
  246. openstackclient/volume/v2/volume_type.py +43 -24
  247. openstackclient/volume/v3/block_storage_cleanup.py +11 -3
  248. openstackclient/volume/v3/block_storage_cluster.py +19 -7
  249. openstackclient/volume/v3/block_storage_log_level.py +15 -6
  250. openstackclient/volume/v3/block_storage_manage.py +10 -4
  251. openstackclient/volume/v3/block_storage_resource_filter.py +17 -5
  252. openstackclient/volume/v3/service.py +16 -6
  253. openstackclient/volume/v3/volume.py +89 -39
  254. openstackclient/volume/v3/volume_attachment.py +43 -21
  255. openstackclient/volume/v3/volume_backup.py +53 -24
  256. openstackclient/volume/v3/volume_group.py +23 -13
  257. openstackclient/volume/v3/volume_group_snapshot.py +32 -13
  258. openstackclient/volume/v3/volume_group_type.py +26 -13
  259. openstackclient/volume/v3/volume_message.py +15 -7
  260. openstackclient/volume/v3/volume_snapshot.py +69 -32
  261. openstackclient/volume/v3/volume_transfer_request.py +31 -13
  262. openstackclient/volume/v3/volume_type.py +42 -24
  263. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/METADATA +6 -6
  264. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/RECORD +271 -260
  265. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/WHEEL +1 -1
  266. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/entry_points.txt +53 -1
  267. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/licenses/AUTHORS +4 -0
  268. python_openstackclient-10.0.0.dist-info/pbr.json +1 -0
  269. openstackclient/api/image_v1.py +0 -69
  270. openstackclient/api/image_v2.py +0 -79
  271. openstackclient/network/v2/floating_ip_pool.py +0 -38
  272. openstackclient/tests/functional/image/v1/test_image.py +0 -97
  273. openstackclient/tests/unit/api/test_image_v1.py +0 -96
  274. openstackclient/tests/unit/api/test_image_v2.py +0 -96
  275. openstackclient/tests/unit/network/v2/test_floating_ip_compute.py +0 -248
  276. openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py +0 -49
  277. openstackclient/tests/unit/network/v2/test_floating_ip_pool_network.py +0 -39
  278. openstackclient/tests/unit/network/v2/test_network_compute.py +0 -404
  279. openstackclient/tests/unit/network/v2/test_security_group_compute.py +0 -392
  280. openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +0 -555
  281. python_openstackclient-9.0.0.dist-info/pbr.json +0 -1
  282. /openstackclient/{tests/functional/image/v1 → network/v2/bgpvpn}/__init__.py +0 -0
  283. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/licenses/LICENSE +0 -0
  284. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/top_level.txt +0 -0
@@ -14,6 +14,9 @@
14
14
 
15
15
  """Block Storage Service action implementations"""
16
16
 
17
+ import argparse
18
+ from typing import Any
19
+
17
20
  from openstack import utils as sdk_utils
18
21
  from osc_lib import exceptions
19
22
 
@@ -27,7 +30,7 @@ class BlockStorageLogLevelList(command.Lister):
27
30
  Supported by --os-volume-api-version 3.32 or greater.
28
31
  """
29
32
 
30
- def get_parser(self, prog_name):
33
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
31
34
  parser = super().get_parser(prog_name)
32
35
  parser.add_argument(
33
36
  "--host",
@@ -63,8 +66,12 @@ class BlockStorageLogLevelList(command.Lister):
63
66
  )
64
67
  return parser
65
68
 
66
- def take_action(self, parsed_args):
67
- volume_client = self.app.client_manager.sdk_connection.volume
69
+ def take_action(
70
+ self, parsed_args: argparse.Namespace
71
+ ) -> tuple[list[str], list[tuple[Any, ...]]]:
72
+ volume_client = sdk_utils.ensure_service_version(
73
+ self.app.client_manager.sdk_connection.volume, '3'
74
+ )
68
75
  columns = [
69
76
  "Binary",
70
77
  "Host",
@@ -98,7 +105,7 @@ class BlockStorageLogLevelSet(command.Command):
98
105
  Supported by --os-volume-api-version 3.32 or greater.
99
106
  """
100
107
 
101
- def get_parser(self, prog_name):
108
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
102
109
  parser = super().get_parser(prog_name)
103
110
  parser.add_argument(
104
111
  "level",
@@ -141,8 +148,10 @@ class BlockStorageLogLevelSet(command.Command):
141
148
  )
142
149
  return parser
143
150
 
144
- def take_action(self, parsed_args):
145
- volume_client = self.app.client_manager.sdk_connection.volume
151
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
152
+ volume_client = sdk_utils.ensure_service_version(
153
+ self.app.client_manager.sdk_connection.volume, '3'
154
+ )
146
155
 
147
156
  if not sdk_utils.supports_microversion(volume_client, '3.32'):
148
157
  msg = _(
@@ -14,6 +14,8 @@
14
14
  """Block Storage Volume/Snapshot Management implementations"""
15
15
 
16
16
  import argparse
17
+ from collections.abc import Iterable
18
+ from typing import Any
17
19
 
18
20
  from cinderclient import api_versions
19
21
  from osc_lib import exceptions
@@ -32,7 +34,7 @@ class BlockStorageManageVolumes(command.Lister):
32
34
  Supported by --os-volume-api-version 3.8 or greater.
33
35
  """
34
36
 
35
- def get_parser(self, prog_name):
37
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
36
38
  parser = super().get_parser(prog_name)
37
39
  host_group = parser.add_mutually_exclusive_group()
38
40
  host_group.add_argument(
@@ -104,7 +106,9 @@ class BlockStorageManageVolumes(command.Lister):
104
106
  )
105
107
  return parser
106
108
 
107
- def take_action(self, parsed_args):
109
+ def take_action(
110
+ self, parsed_args: argparse.Namespace
111
+ ) -> tuple[list[str], Iterable[tuple[Any, ...]]]:
108
112
  volume_client = self.app.client_manager.volume
109
113
 
110
114
  if parsed_args.host is None and parsed_args.cluster is None:
@@ -196,7 +200,7 @@ class BlockStorageManageSnapshots(command.Lister):
196
200
  Supported by --os-volume-api-version 3.8 or greater.
197
201
  """
198
202
 
199
- def get_parser(self, prog_name):
203
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
200
204
  parser = super().get_parser(prog_name)
201
205
  host_group = parser.add_mutually_exclusive_group()
202
206
  host_group.add_argument(
@@ -268,7 +272,9 @@ class BlockStorageManageSnapshots(command.Lister):
268
272
  )
269
273
  return parser
270
274
 
271
- def take_action(self, parsed_args):
275
+ def take_action(
276
+ self, parsed_args: argparse.Namespace
277
+ ) -> tuple[list[str], Iterable[tuple[Any, ...]]]:
272
278
  volume_client = self.app.client_manager.volume
273
279
 
274
280
  if parsed_args.host is None and parsed_args.cluster is None:
@@ -12,6 +12,10 @@
12
12
 
13
13
  """Volume V3 Resource Filters implementations"""
14
14
 
15
+ import argparse
16
+ from collections.abc import Iterable, Sequence
17
+ from typing import Any
18
+
15
19
  from openstack import utils as sdk_utils
16
20
  from osc_lib.cli import format_columns
17
21
  from osc_lib import exceptions
@@ -24,8 +28,12 @@ from openstackclient.i18n import _
24
28
  class ListBlockStorageResourceFilter(command.Lister):
25
29
  _description = _('List block storage resource filters')
26
30
 
27
- def take_action(self, parsed_args):
28
- volume_client = self.app.client_manager.sdk_connection.volume
31
+ def take_action(
32
+ self, parsed_args: argparse.Namespace
33
+ ) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
34
+ volume_client = sdk_utils.ensure_service_version(
35
+ self.app.client_manager.sdk_connection.volume, '3'
36
+ )
29
37
 
30
38
  if not sdk_utils.supports_microversion(volume_client, '3.33'):
31
39
  msg = _(
@@ -58,7 +66,7 @@ class ListBlockStorageResourceFilter(command.Lister):
58
66
  class ShowBlockStorageResourceFilter(command.ShowOne):
59
67
  _description = _('Show filters for a block storage resource type')
60
68
 
61
- def get_parser(self, prog_name):
69
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
62
70
  parser = super().get_parser(prog_name)
63
71
  parser.add_argument(
64
72
  'resource',
@@ -68,8 +76,12 @@ class ShowBlockStorageResourceFilter(command.ShowOne):
68
76
 
69
77
  return parser
70
78
 
71
- def take_action(self, parsed_args):
72
- volume_client = self.app.client_manager.sdk_connection.volume
79
+ def take_action(
80
+ self, parsed_args: argparse.Namespace
81
+ ) -> tuple[Sequence[str], Iterable[Any]]:
82
+ volume_client = sdk_utils.ensure_service_version(
83
+ self.app.client_manager.sdk_connection.volume, '3'
84
+ )
73
85
 
74
86
  if not sdk_utils.supports_microversion(volume_client, '3.33'):
75
87
  msg = _(
@@ -14,6 +14,10 @@
14
14
 
15
15
  """Service action implementations"""
16
16
 
17
+ import argparse
18
+ from collections.abc import Iterable
19
+ from typing import Any
20
+
17
21
  from openstack import utils as sdk_utils
18
22
  from osc_lib import exceptions
19
23
  from osc_lib import utils
@@ -25,7 +29,7 @@ from openstackclient.i18n import _
25
29
  class ListService(command.Lister):
26
30
  _description = _("List service command")
27
31
 
28
- def get_parser(self, prog_name):
32
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
29
33
  parser = super().get_parser(prog_name)
30
34
  parser.add_argument(
31
35
  "--host",
@@ -45,8 +49,12 @@ class ListService(command.Lister):
45
49
  )
46
50
  return parser
47
51
 
48
- def take_action(self, parsed_args):
49
- volume_client = self.app.client_manager.sdk_connection.volume
52
+ def take_action(
53
+ self, parsed_args: argparse.Namespace
54
+ ) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
55
+ volume_client = sdk_utils.ensure_service_version(
56
+ self.app.client_manager.sdk_connection.volume, '3'
57
+ )
50
58
 
51
59
  columns: tuple[str, ...] = (
52
60
  "binary",
@@ -93,7 +101,7 @@ class ListService(command.Lister):
93
101
  class SetService(command.Command):
94
102
  _description = _("Set volume service properties")
95
103
 
96
- def get_parser(self, prog_name):
104
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
97
105
  parser = super().get_parser(prog_name)
98
106
  parser.add_argument(
99
107
  "host",
@@ -122,7 +130,7 @@ class SetService(command.Command):
122
130
  )
123
131
  return parser
124
132
 
125
- def take_action(self, parsed_args):
133
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
126
134
  if parsed_args.disable_reason and not parsed_args.disable:
127
135
  msg = _(
128
136
  "Cannot specify option --disable-reason without "
@@ -130,7 +138,9 @@ class SetService(command.Command):
130
138
  )
131
139
  raise exceptions.CommandError(msg)
132
140
 
133
- volume_client = self.app.client_manager.sdk_connection.volume
141
+ volume_client = sdk_utils.ensure_service_version(
142
+ self.app.client_manager.sdk_connection.volume, '3'
143
+ )
134
144
 
135
145
  service = volume_client.find_service(
136
146
  parsed_args.service, ignore_missing=False, host=parsed_args.host
@@ -15,10 +15,11 @@
15
15
  """Volume V3 Volume action implementations"""
16
16
 
17
17
  import argparse
18
+ from collections.abc import Iterable, Sequence
18
19
  import copy
19
20
  import functools
20
21
  import logging
21
- import typing as ty
22
+ from typing import Any
22
23
 
23
24
  from cliff import columns as cliff_columns
24
25
  from openstack.block_storage.v3 import volume as _volume
@@ -44,14 +45,20 @@ class KeyValueHintAction(argparse.Action):
44
45
 
45
46
  APPEND_KEYS = ('same_host', 'different_host')
46
47
 
47
- def __init__(self, *args, **kwargs):
48
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
48
49
  self._key_value_action = parseractions.KeyValueAction(*args, **kwargs)
49
50
  self._key_value_append_action = parseractions.KeyValueAppendAction(
50
51
  *args, **kwargs
51
52
  )
52
53
  super().__init__(*args, **kwargs)
53
54
 
54
- def __call__(self, parser, namespace, values, option_string=None):
55
+ def __call__(
56
+ self,
57
+ parser: argparse.ArgumentParser,
58
+ namespace: argparse.Namespace,
59
+ values: Any,
60
+ option_string: str | None = None,
61
+ ) -> None:
55
62
  if values.startswith(self.APPEND_KEYS):
56
63
  self._key_value_append_action(
57
64
  parser, namespace, values, option_string=option_string
@@ -62,7 +69,7 @@ class KeyValueHintAction(argparse.Action):
62
69
  )
63
70
 
64
71
 
65
- class AttachmentsColumn(cliff_columns.FormattableColumn[list[ty.Any]]):
72
+ class AttachmentsColumn(cliff_columns.FormattableColumn[list[Any]]):
66
73
  """Formattable column for attachments column.
67
74
 
68
75
  Unlike the parent FormattableColumn class, the initializer of the
@@ -73,11 +80,13 @@ class AttachmentsColumn(cliff_columns.FormattableColumn[list[ty.Any]]):
73
80
  ``functools.partial(AttachmentsColumn, server_cache)``.
74
81
  """
75
82
 
76
- def __init__(self, value, server_cache=None):
83
+ def __init__(
84
+ self, value: list[Any], server_cache: dict[str, Any] | None = None
85
+ ) -> None:
77
86
  super().__init__(value)
78
87
  self._server_cache = server_cache or {}
79
88
 
80
- def human_readable(self):
89
+ def human_readable(self) -> str:
81
90
  """Return a formatted string of a volume's attached instances
82
91
 
83
92
  :rtype: a string of formatted instances
@@ -93,7 +102,7 @@ class AttachmentsColumn(cliff_columns.FormattableColumn[list[ty.Any]]):
93
102
  return msg
94
103
 
95
104
 
96
- def _format_volume(volume: _volume.Volume) -> dict[str, ty.Any]:
105
+ def _format_volume(volume: _volume.Volume) -> dict[str, Any]:
97
106
  # Some columns returned by openstacksdk should not be shown because they're
98
107
  # either irrelevant or duplicates
99
108
  ignored_columns = {
@@ -143,7 +152,7 @@ class CreateVolume(command.ShowOne):
143
152
  _description = _("Create new volume")
144
153
 
145
154
  @staticmethod
146
- def _check_size_arg(args):
155
+ def _check_size_arg(args: argparse.Namespace) -> None:
147
156
  """Check whether --size option is required or not.
148
157
 
149
158
  Require size parameter in case if any of the following is not
@@ -164,7 +173,7 @@ class CreateVolume(command.ShowOne):
164
173
  )
165
174
  raise exceptions.CommandError(msg)
166
175
 
167
- def get_parser(self, prog_name):
176
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
168
177
  parser = super().get_parser(prog_name)
169
178
  parser.add_argument(
170
179
  "name",
@@ -313,7 +322,9 @@ class CreateVolume(command.ShowOne):
313
322
  )
314
323
  return parser
315
324
 
316
- def take_action(self, parsed_args):
325
+ def take_action(
326
+ self, parsed_args: argparse.Namespace
327
+ ) -> tuple[Sequence[str], Iterable[Any]]:
317
328
  self._check_size_arg(parsed_args)
318
329
  # size is validated in the above call to
319
330
  # _check_size_arg where we check that size
@@ -321,7 +332,9 @@ class CreateVolume(command.ShowOne):
321
332
  # volume from snapshot, backup or source volume
322
333
  size = parsed_args.size
323
334
 
324
- volume_client = self.app.client_manager.sdk_connection.volume
335
+ volume_client = sdk_utils.ensure_service_version(
336
+ self.app.client_manager.sdk_connection.volume, '3'
337
+ )
325
338
  image_client = self.app.client_manager.image
326
339
 
327
340
  if (
@@ -386,7 +399,8 @@ class CreateVolume(command.ShowOne):
386
399
  bootable=parsed_args.bootable,
387
400
  )
388
401
  data = _format_volume(volume)
389
- return zip(*sorted(data.items()))
402
+ col_headers, col_data = zip(*sorted(data.items()))
403
+ return col_headers, col_data
390
404
 
391
405
  source_volume = None
392
406
  if parsed_args.source:
@@ -491,13 +505,14 @@ class CreateVolume(command.ShowOne):
491
505
  )
492
506
 
493
507
  data = _format_volume(volume)
494
- return zip(*sorted(data.items()))
508
+ col_headers, col_data = zip(*sorted(data.items()))
509
+ return col_headers, col_data
495
510
 
496
511
 
497
512
  class DeleteVolume(command.Command):
498
513
  _description = _("Delete volume(s)")
499
514
 
500
- def get_parser(self, prog_name):
515
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
501
516
  parser = super().get_parser(prog_name)
502
517
  parser.add_argument(
503
518
  "volumes",
@@ -535,8 +550,10 @@ class DeleteVolume(command.Command):
535
550
  )
536
551
  return parser
537
552
 
538
- def take_action(self, parsed_args):
539
- volume_client = self.app.client_manager.sdk_connection.volume
553
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
554
+ volume_client = sdk_utils.ensure_service_version(
555
+ self.app.client_manager.sdk_connection.volume, '3'
556
+ )
540
557
  result = 0
541
558
 
542
559
  if parsed_args.remote and (parsed_args.force or parsed_args.cascade):
@@ -581,7 +598,7 @@ class DeleteVolume(command.Command):
581
598
  class ListVolume(command.Lister):
582
599
  _description = _("List volumes")
583
600
 
584
- def get_parser(self, prog_name):
601
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
585
602
  parser = super().get_parser(prog_name)
586
603
  parser.add_argument(
587
604
  '--project',
@@ -630,7 +647,9 @@ class ListVolume(command.Lister):
630
647
  pagination.add_marker_pagination_option_to_parser(parser)
631
648
  return parser
632
649
 
633
- def take_action(self, parsed_args):
650
+ def take_action(
651
+ self, parsed_args: argparse.Namespace
652
+ ) -> tuple[Sequence[str], Iterable[tuple[Any, ...]]]:
634
653
  volume_client = self.app.client_manager.volume
635
654
  identity_client = self.app.client_manager.identity
636
655
 
@@ -706,7 +725,7 @@ class ListVolume(command.Lister):
706
725
  compute_client = self.app.client_manager.compute
707
726
  for s in compute_client.servers():
708
727
  server_cache[s.id] = s
709
- except sdk_exceptions.SDKException: # noqa: S110
728
+ except sdk_exceptions.SDKException:
710
729
  # Just forget it if there's any trouble
711
730
  pass
712
731
  AttachmentsColumnWithCache = functools.partial(
@@ -736,21 +755,29 @@ class ListVolume(command.Lister):
736
755
  class MigrateVolume(command.Command):
737
756
  _description = _("Migrate volume to a new host")
738
757
 
739
- def get_parser(self, prog_name):
758
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
740
759
  parser = super().get_parser(prog_name)
741
760
  parser.add_argument(
742
761
  'volume',
743
762
  metavar="<volume>",
744
763
  help=_("Volume to migrate (name or ID)"),
745
764
  )
746
- parser.add_argument(
765
+ destination_group = parser.add_mutually_exclusive_group(required=True)
766
+ destination_group.add_argument(
747
767
  '--host',
748
768
  metavar="<host>",
749
- required=True,
750
769
  help=_(
751
770
  "Destination host (takes the form: host@backend-name#pool)"
752
771
  ),
753
772
  )
773
+ destination_group.add_argument(
774
+ '--cluster',
775
+ metavar="<cluster>",
776
+ help=_(
777
+ "Destination cluster to migrate the volume to "
778
+ "(requires --os-volume-api-version 3.16 or higher)"
779
+ ),
780
+ )
754
781
  parser.add_argument(
755
782
  '--force-host-copy',
756
783
  action="store_true",
@@ -768,26 +795,38 @@ class MigrateVolume(command.Command):
768
795
  "(possibly by another operation)"
769
796
  ),
770
797
  )
771
- # TODO(stephenfin): Add --cluster argument
772
798
  return parser
773
799
 
774
- def take_action(self, parsed_args):
775
- volume_client = self.app.client_manager.sdk_connection.volume
800
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
801
+ volume_client = sdk_utils.ensure_service_version(
802
+ self.app.client_manager.sdk_connection.volume, '3'
803
+ )
776
804
  volume = volume_client.find_volume(
777
805
  parsed_args.volume, ignore_missing=False
778
806
  )
807
+
808
+ if parsed_args.cluster and not sdk_utils.supports_microversion(
809
+ volume_client, '3.16'
810
+ ):
811
+ msg = _(
812
+ "--os-volume-api-version 3.16 or greater is required to "
813
+ "support the volume migration with cluster"
814
+ )
815
+ raise exceptions.CommandError(msg)
816
+
779
817
  volume_client.migrate_volume(
780
818
  volume.id,
781
819
  host=parsed_args.host,
782
820
  force_host_copy=parsed_args.force_host_copy,
783
821
  lock_volume=parsed_args.lock_volume,
822
+ cluster=parsed_args.cluster,
784
823
  )
785
824
 
786
825
 
787
826
  class SetVolume(command.Command):
788
827
  _description = _("Set volume properties")
789
828
 
790
- def get_parser(self, prog_name):
829
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
791
830
  parser = super().get_parser(prog_name)
792
831
  parser.add_argument(
793
832
  'volume',
@@ -940,7 +979,7 @@ class SetVolume(command.Command):
940
979
  )
941
980
  return parser
942
981
 
943
- def take_action(self, parsed_args):
982
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
944
983
  volume_client = self.app.client_manager.volume
945
984
  volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
946
985
 
@@ -1113,7 +1152,7 @@ class SetVolume(command.Command):
1113
1152
  class ShowVolume(command.ShowOne):
1114
1153
  _description = _("Display volume details")
1115
1154
 
1116
- def get_parser(self, prog_name):
1155
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
1117
1156
  parser = super().get_parser(prog_name)
1118
1157
  parser.add_argument(
1119
1158
  'volume',
@@ -1122,20 +1161,25 @@ class ShowVolume(command.ShowOne):
1122
1161
  )
1123
1162
  return parser
1124
1163
 
1125
- def take_action(self, parsed_args):
1126
- volume_client = self.app.client_manager.sdk_connection.volume
1164
+ def take_action(
1165
+ self, parsed_args: argparse.Namespace
1166
+ ) -> tuple[Sequence[str], Iterable[Any]]:
1167
+ volume_client = sdk_utils.ensure_service_version(
1168
+ self.app.client_manager.sdk_connection.volume, '3'
1169
+ )
1127
1170
  volume = volume_client.find_volume(
1128
1171
  parsed_args.volume, ignore_missing=False
1129
1172
  )
1130
1173
 
1131
1174
  data = _format_volume(volume)
1132
- return zip(*sorted(data.items()))
1175
+ col_headers, col_data = zip(*sorted(data.items()))
1176
+ return col_headers, col_data
1133
1177
 
1134
1178
 
1135
1179
  class UnsetVolume(command.Command):
1136
1180
  _description = _("Unset volume properties")
1137
1181
 
1138
- def get_parser(self, prog_name):
1182
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
1139
1183
  parser = super().get_parser(prog_name)
1140
1184
  parser.add_argument(
1141
1185
  'volume',
@@ -1164,7 +1208,7 @@ class UnsetVolume(command.Command):
1164
1208
  )
1165
1209
  return parser
1166
1210
 
1167
- def take_action(self, parsed_args):
1211
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
1168
1212
  volume_client = self.app.client_manager.volume
1169
1213
  volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
1170
1214
 
@@ -1196,7 +1240,7 @@ class UnsetVolume(command.Command):
1196
1240
  class VolumeSummary(command.ShowOne):
1197
1241
  _description = _("Show a summary of all volumes in this deployment.")
1198
1242
 
1199
- def get_parser(self, prog_name):
1243
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
1200
1244
  parser = super().get_parser(prog_name)
1201
1245
  parser.add_argument(
1202
1246
  '--all-projects',
@@ -1206,8 +1250,12 @@ class VolumeSummary(command.ShowOne):
1206
1250
  )
1207
1251
  return parser
1208
1252
 
1209
- def take_action(self, parsed_args):
1210
- volume_client = self.app.client_manager.sdk_connection.volume
1253
+ def take_action(
1254
+ self, parsed_args: argparse.Namespace
1255
+ ) -> tuple[Sequence[str], Iterable[Any]]:
1256
+ volume_client = sdk_utils.ensure_service_version(
1257
+ self.app.client_manager.sdk_connection.volume, '3'
1258
+ )
1211
1259
 
1212
1260
  if not sdk_utils.supports_microversion(volume_client, '3.12'):
1213
1261
  msg = _(
@@ -1246,7 +1294,7 @@ class VolumeSummary(command.ShowOne):
1246
1294
  class VolumeRevertToSnapshot(command.Command):
1247
1295
  _description = _("Revert a volume to a snapshot.")
1248
1296
 
1249
- def get_parser(self, prog_name):
1297
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
1250
1298
  parser = super().get_parser(prog_name)
1251
1299
  parser.add_argument(
1252
1300
  'snapshot',
@@ -1258,8 +1306,10 @@ class VolumeRevertToSnapshot(command.Command):
1258
1306
  )
1259
1307
  return parser
1260
1308
 
1261
- def take_action(self, parsed_args):
1262
- volume_client = self.app.client_manager.sdk_connection.volume
1309
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
1310
+ volume_client = sdk_utils.ensure_service_version(
1311
+ self.app.client_manager.sdk_connection.volume, '3'
1312
+ )
1263
1313
 
1264
1314
  if not sdk_utils.supports_microversion(volume_client, '3.40'):
1265
1315
  msg = _(