python-openstackclient 9.0.0__py3-none-any.whl → 10.1.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 (352) 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 +59 -43
  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 +36 -34
  14. openstackclient/common/pagination.py +50 -6
  15. openstackclient/common/progressbar.py +7 -6
  16. openstackclient/common/project_cleanup.py +11 -6
  17. openstackclient/common/quota.py +105 -103
  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 +42 -22
  25. openstackclient/compute/v2/host.py +14 -6
  26. openstackclient/compute/v2/hypervisor.py +16 -5
  27. openstackclient/compute/v2/hypervisor_stats.py +10 -2
  28. openstackclient/compute/v2/keypair.py +35 -16
  29. openstackclient/compute/v2/server.py +268 -179
  30. openstackclient/compute/v2/server_backup.py +10 -4
  31. openstackclient/compute/v2/server_event.py +28 -12
  32. openstackclient/compute/v2/server_group.py +23 -11
  33. openstackclient/compute/v2/server_image.py +19 -10
  34. openstackclient/compute/v2/server_migration.py +27 -10
  35. openstackclient/compute/v2/server_share.py +274 -0
  36. openstackclient/compute/v2/server_volume.py +13 -5
  37. openstackclient/compute/v2/service.py +17 -8
  38. openstackclient/compute/v2/usage.py +28 -23
  39. openstackclient/identity/client.py +8 -3
  40. openstackclient/identity/common.py +82 -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 +32 -12
  51. openstackclient/identity/v3/application_credential.py +66 -24
  52. openstackclient/identity/v3/catalog.py +14 -7
  53. openstackclient/identity/v3/consumer.py +22 -11
  54. openstackclient/identity/v3/credential.py +39 -17
  55. openstackclient/identity/v3/domain.py +40 -19
  56. openstackclient/identity/v3/ec2creds.py +25 -12
  57. openstackclient/identity/v3/endpoint.py +98 -64
  58. openstackclient/identity/v3/endpoint_group.py +28 -17
  59. openstackclient/identity/v3/federation_protocol.py +44 -20
  60. openstackclient/identity/v3/group.py +64 -40
  61. openstackclient/identity/v3/identity_provider.py +95 -57
  62. openstackclient/identity/v3/implied_role.py +21 -9
  63. openstackclient/identity/v3/limit.py +42 -17
  64. openstackclient/identity/v3/mapping.py +58 -28
  65. openstackclient/identity/v3/policy.py +23 -12
  66. openstackclient/identity/v3/project.py +59 -26
  67. openstackclient/identity/v3/region.py +39 -17
  68. openstackclient/identity/v3/registered_limit.py +41 -16
  69. openstackclient/identity/v3/role.py +62 -31
  70. openstackclient/identity/v3/role_assignment.py +25 -7
  71. openstackclient/identity/v3/service.py +39 -17
  72. openstackclient/identity/v3/service_provider.py +40 -16
  73. openstackclient/identity/v3/tag.py +23 -6
  74. openstackclient/identity/v3/token.py +30 -14
  75. openstackclient/identity/v3/trust.py +39 -18
  76. openstackclient/identity/v3/unscoped_saml.py +10 -2
  77. openstackclient/identity/v3/user.py +86 -36
  78. openstackclient/image/client.py +7 -3
  79. openstackclient/image/v1/image.py +33 -26
  80. openstackclient/image/v2/cache.py +16 -11
  81. openstackclient/image/v2/image.py +88 -56
  82. openstackclient/image/v2/info.py +7 -1
  83. openstackclient/image/v2/metadef_namespaces.py +117 -20
  84. openstackclient/image/v2/metadef_objects.py +32 -19
  85. openstackclient/image/v2/metadef_properties.py +30 -16
  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 +25 -27
  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 +27 -54
  93. openstackclient/network/v2/address_group.py +39 -16
  94. openstackclient/network/v2/address_scope.py +36 -20
  95. openstackclient/network/v2/bgpvpn/bgpvpn.py +477 -0
  96. openstackclient/network/v2/bgpvpn/constants.py +30 -0
  97. openstackclient/network/v2/bgpvpn/network_association.py +226 -0
  98. openstackclient/network/v2/bgpvpn/port_association.py +504 -0
  99. openstackclient/network/v2/bgpvpn/router_association.py +301 -0
  100. openstackclient/network/v2/default_security_group_rule.py +31 -14
  101. openstackclient/network/v2/floating_ip.py +121 -162
  102. openstackclient/network/v2/floating_ip_port_forwarding.py +41 -19
  103. openstackclient/network/v2/fwaas/__init__.py +0 -0
  104. openstackclient/network/v2/fwaas/group.py +499 -0
  105. openstackclient/network/v2/fwaas/policy.py +518 -0
  106. openstackclient/network/v2/fwaas/rule.py +610 -0
  107. openstackclient/network/v2/ip_availability.py +25 -8
  108. openstackclient/network/v2/l3_conntrack_helper.py +35 -13
  109. openstackclient/network/v2/local_ip.py +27 -13
  110. openstackclient/network/v2/local_ip_association.py +17 -7
  111. openstackclient/network/v2/ndp_proxy.py +23 -11
  112. openstackclient/network/v2/network.py +213 -213
  113. openstackclient/network/v2/network_agent.py +77 -34
  114. openstackclient/network/v2/network_auto_allocated_topology.py +27 -15
  115. openstackclient/network/v2/network_flavor.py +45 -21
  116. openstackclient/network/v2/network_flavor_profile.py +42 -17
  117. openstackclient/network/v2/network_meter.py +39 -15
  118. openstackclient/network/v2/network_meter_rule.py +40 -12
  119. openstackclient/network/v2/network_qos_policy.py +39 -21
  120. openstackclient/network/v2/network_qos_rule.py +48 -18
  121. openstackclient/network/v2/network_qos_rule_type.py +28 -9
  122. openstackclient/network/v2/network_rbac.py +34 -16
  123. openstackclient/network/v2/network_segment.py +32 -11
  124. openstackclient/network/v2/network_segment_range.py +70 -31
  125. openstackclient/network/v2/network_service_provider.py +7 -1
  126. openstackclient/network/v2/network_trunk.py +41 -22
  127. openstackclient/network/v2/port.py +141 -40
  128. openstackclient/network/v2/router.py +101 -67
  129. openstackclient/network/v2/security_group.py +97 -198
  130. openstackclient/network/v2/security_group_rule.py +115 -282
  131. openstackclient/network/v2/subnet.py +63 -34
  132. openstackclient/network/v2/subnet_pool.py +42 -24
  133. openstackclient/network/v2/taas/tap_flow.py +35 -14
  134. openstackclient/network/v2/taas/tap_mirror.py +28 -14
  135. openstackclient/network/v2/taas/tap_service.py +26 -12
  136. openstackclient/object/client.py +7 -2
  137. openstackclient/object/v1/account.py +13 -6
  138. openstackclient/object/v1/container.py +28 -16
  139. openstackclient/object/v1/object.py +28 -16
  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 +59 -19
  151. openstackclient/tests/functional/identity/v3/test_application_credential.py +1 -1
  152. openstackclient/tests/functional/identity/v3/test_group.py +20 -20
  153. openstackclient/tests/functional/identity/v3/test_idp.py +3 -1
  154. openstackclient/tests/functional/identity/v3/test_mapping.py +81 -0
  155. openstackclient/tests/functional/identity/v3/test_project.py +10 -10
  156. openstackclient/tests/functional/identity/v3/test_role.py +18 -18
  157. openstackclient/tests/functional/identity/v3/test_role_assignment.py +12 -12
  158. openstackclient/tests/functional/identity/v3/test_user.py +8 -8
  159. openstackclient/tests/functional/image/base.py +1 -6
  160. openstackclient/tests/functional/network/v2/common.py +5 -2
  161. openstackclient/tests/functional/network/v2/test_floating_ip.py +10 -4
  162. openstackclient/tests/functional/network/v2/test_ip_availability.py +4 -0
  163. openstackclient/tests/functional/network/v2/test_network_meter_rule.py +3 -2
  164. openstackclient/tests/functional/network/v2/test_network_segment.py +5 -0
  165. openstackclient/tests/functional/network/v2/test_subnet.py +13 -9
  166. openstackclient/tests/functional/object/v1/common.py +4 -0
  167. openstackclient/tests/functional/volume/v2/common.py +4 -0
  168. openstackclient/tests/functional/volume/v2/test_volume_snapshot.py +27 -11
  169. openstackclient/tests/functional/volume/v2/test_volume_type.py +2 -2
  170. openstackclient/tests/functional/volume/v3/common.py +4 -0
  171. openstackclient/tests/functional/volume/v3/test_volume_group.py +163 -0
  172. openstackclient/tests/functional/volume/v3/test_volume_snapshot.py +11 -7
  173. openstackclient/tests/functional/volume/v3/test_volume_type.py +2 -2
  174. openstackclient/tests/unit/common/test_availability_zone.py +35 -49
  175. openstackclient/tests/unit/common/test_extension.py +2 -2
  176. openstackclient/tests/unit/common/test_limits.py +1 -1
  177. openstackclient/tests/unit/common/test_module.py +82 -44
  178. openstackclient/tests/unit/common/test_project_cleanup.py +3 -1
  179. openstackclient/tests/unit/common/test_quota.py +15 -26
  180. openstackclient/tests/unit/compute/v2/fakes.py +26 -57
  181. openstackclient/tests/unit/compute/v2/test_agent.py +4 -4
  182. openstackclient/tests/unit/compute/v2/test_aggregate.py +1 -1
  183. openstackclient/tests/unit/compute/v2/test_console.py +2 -2
  184. openstackclient/tests/unit/compute/v2/test_console_connection.py +1 -1
  185. openstackclient/tests/unit/compute/v2/test_flavor.py +29 -3
  186. openstackclient/tests/unit/compute/v2/test_host.py +3 -3
  187. openstackclient/tests/unit/compute/v2/test_hypervisor.py +2 -2
  188. openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py +1 -1
  189. openstackclient/tests/unit/compute/v2/test_keypair.py +7 -7
  190. openstackclient/tests/unit/compute/v2/test_server.py +26 -111
  191. openstackclient/tests/unit/compute/v2/test_server_backup.py +1 -1
  192. openstackclient/tests/unit/compute/v2/test_server_event.py +2 -2
  193. openstackclient/tests/unit/compute/v2/test_server_group.py +1 -1
  194. openstackclient/tests/unit/compute/v2/test_server_image.py +1 -1
  195. openstackclient/tests/unit/compute/v2/test_server_migration.py +4 -4
  196. openstackclient/tests/unit/compute/v2/test_server_share.py +287 -0
  197. openstackclient/tests/unit/compute/v2/test_server_volume.py +2 -2
  198. openstackclient/tests/unit/compute/v2/test_service.py +3 -3
  199. openstackclient/tests/unit/compute/v2/test_usage.py +1 -1
  200. openstackclient/tests/unit/identity/v2_0/fakes.py +3 -7
  201. openstackclient/tests/unit/identity/v2_0/test_endpoint.py +1 -1
  202. openstackclient/tests/unit/identity/v2_0/test_project.py +1 -1
  203. openstackclient/tests/unit/identity/v2_0/test_role.py +1 -1
  204. openstackclient/tests/unit/identity/v2_0/test_role_assignment.py +1 -1
  205. openstackclient/tests/unit/identity/v2_0/test_service.py +1 -1
  206. openstackclient/tests/unit/identity/v2_0/test_token.py +2 -2
  207. openstackclient/tests/unit/identity/v2_0/test_user.py +1 -1
  208. openstackclient/tests/unit/identity/v3/fakes.py +8 -38
  209. openstackclient/tests/unit/identity/v3/test_access_rule.py +3 -3
  210. openstackclient/tests/unit/identity/v3/test_application_credential.py +4 -4
  211. openstackclient/tests/unit/identity/v3/test_credential.py +5 -5
  212. openstackclient/tests/unit/identity/v3/test_domain.py +5 -5
  213. openstackclient/tests/unit/identity/v3/test_endpoint.py +6 -6
  214. openstackclient/tests/unit/identity/v3/test_endpoint_group.py +1 -1
  215. openstackclient/tests/unit/identity/v3/test_group.py +12 -22
  216. openstackclient/tests/unit/identity/v3/test_identity_provider.py +303 -299
  217. openstackclient/tests/unit/identity/v3/test_implied_role.py +1 -1
  218. openstackclient/tests/unit/identity/v3/test_limit.py +5 -5
  219. openstackclient/tests/unit/identity/v3/test_mappings.py +163 -79
  220. openstackclient/tests/unit/identity/v3/test_project.py +28 -5
  221. openstackclient/tests/unit/identity/v3/test_protocol.py +3 -3
  222. openstackclient/tests/unit/identity/v3/test_region.py +5 -5
  223. openstackclient/tests/unit/identity/v3/test_registered_limit.py +5 -5
  224. openstackclient/tests/unit/identity/v3/test_role.py +8 -8
  225. openstackclient/tests/unit/identity/v3/test_role_assignment.py +1 -1
  226. openstackclient/tests/unit/identity/v3/test_service.py +5 -5
  227. openstackclient/tests/unit/identity/v3/test_token.py +2 -2
  228. openstackclient/tests/unit/identity/v3/test_trust.py +4 -4
  229. openstackclient/tests/unit/identity/v3/test_user.py +77 -10
  230. openstackclient/tests/unit/image/v2/test_image.py +11 -11
  231. openstackclient/tests/unit/image/v2/test_metadef_namespaces.py +105 -6
  232. openstackclient/tests/unit/network/test_common.py +0 -155
  233. openstackclient/tests/unit/network/v2/bgpvpn/__init__.py +0 -0
  234. openstackclient/tests/unit/network/v2/bgpvpn/fakes.py +179 -0
  235. openstackclient/tests/unit/network/v2/bgpvpn/test_bgpvpn.py +584 -0
  236. openstackclient/tests/unit/network/v2/bgpvpn/test_network_association.py +285 -0
  237. openstackclient/tests/unit/network/v2/bgpvpn/test_port_association.py +384 -0
  238. openstackclient/tests/unit/network/v2/bgpvpn/test_router_association.py +297 -0
  239. openstackclient/tests/unit/network/v2/fakes.py +5 -77
  240. openstackclient/tests/unit/network/v2/fwaas/__init__.py +0 -0
  241. openstackclient/tests/unit/network/v2/fwaas/test_group.py +923 -0
  242. openstackclient/tests/unit/network/v2/fwaas/test_policy.py +869 -0
  243. openstackclient/tests/unit/network/v2/fwaas/test_rule.py +1005 -0
  244. openstackclient/tests/unit/network/v2/taas/{test_osc_tap_flow.py → test_tap_flow.py} +18 -25
  245. openstackclient/tests/unit/network/v2/taas/{test_osc_tap_mirror.py → test_tap_mirror.py} +19 -29
  246. openstackclient/tests/unit/network/v2/taas/{test_osc_tap_service.py → test_tap_service.py} +19 -29
  247. openstackclient/tests/unit/network/v2/test_address_group.py +26 -2
  248. openstackclient/tests/unit/network/v2/test_address_scope.py +24 -0
  249. openstackclient/tests/unit/network/v2/{test_floating_ip_network.py → test_floating_ip.py} +27 -2
  250. openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py +37 -13
  251. openstackclient/tests/unit/network/v2/test_ip_availability.py +25 -0
  252. openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py +29 -3
  253. openstackclient/tests/unit/network/v2/test_network.py +74 -12
  254. openstackclient/tests/unit/network/v2/test_network_agent.py +58 -5
  255. openstackclient/tests/unit/network/v2/test_network_auto_allocated_topology.py +3 -3
  256. openstackclient/tests/unit/network/v2/test_network_flavor.py +26 -2
  257. openstackclient/tests/unit/network/v2/test_network_flavor_profile.py +24 -0
  258. openstackclient/tests/unit/network/v2/test_network_meter.py +24 -0
  259. openstackclient/tests/unit/network/v2/test_network_qos_policy.py +25 -1
  260. openstackclient/tests/unit/network/v2/test_network_qos_rule.py +2 -2
  261. openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py +24 -0
  262. openstackclient/tests/unit/network/v2/test_network_rbac.py +25 -1
  263. openstackclient/tests/unit/network/v2/test_network_segment.py +25 -1
  264. openstackclient/tests/unit/network/v2/test_network_segment_range.py +31 -10
  265. openstackclient/tests/unit/network/v2/test_network_trunk.py +1 -1
  266. openstackclient/tests/unit/network/v2/test_port.py +166 -0
  267. openstackclient/tests/unit/network/v2/test_router.py +36 -16
  268. openstackclient/tests/unit/network/v2/{test_security_group_network.py → test_security_group.py} +11 -8
  269. openstackclient/tests/unit/network/v2/{test_security_group_rule_network.py → test_security_group_rule.py} +28 -37
  270. openstackclient/tests/unit/network/v2/test_subnet.py +30 -5
  271. openstackclient/tests/unit/network/v2/test_subnet_pool.py +26 -1
  272. openstackclient/tests/unit/object/v1/fakes.py +8 -7
  273. openstackclient/tests/unit/object/v1/test_container.py +65 -101
  274. openstackclient/tests/unit/object/v1/test_container_all.py +8 -1
  275. openstackclient/tests/unit/object/v1/test_object.py +44 -84
  276. openstackclient/tests/unit/object/v1/test_object_all.py +8 -1
  277. openstackclient/tests/unit/test_hacking.py +108 -0
  278. openstackclient/tests/unit/volume/v2/fakes.py +21 -140
  279. openstackclient/tests/unit/volume/v2/test_volume_backup.py +6 -14
  280. openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +8 -1
  281. openstackclient/tests/unit/volume/v2/test_volume_type.py +2 -4
  282. openstackclient/tests/unit/volume/v3/fakes.py +205 -100
  283. openstackclient/tests/unit/volume/v3/test_backup_record.py +114 -0
  284. openstackclient/tests/unit/volume/v3/test_consistency_group.py +720 -0
  285. openstackclient/tests/unit/volume/v3/test_consistency_group_snapshot.py +354 -0
  286. openstackclient/tests/unit/volume/v3/test_qos_specs.py +455 -0
  287. openstackclient/tests/unit/volume/v3/test_volume.py +60 -3
  288. openstackclient/tests/unit/volume/v3/test_volume_attachment.py +3 -1
  289. openstackclient/tests/unit/volume/v3/test_volume_backend.py +158 -0
  290. openstackclient/tests/unit/volume/v3/test_volume_backup.py +6 -14
  291. openstackclient/tests/unit/volume/v3/test_volume_group_type.py +65 -0
  292. openstackclient/tests/unit/volume/v3/test_volume_host.py +115 -0
  293. openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +61 -1
  294. openstackclient/tests/unit/volume/v3/test_volume_type.py +2 -4
  295. openstackclient/volume/client.py +7 -3
  296. openstackclient/volume/v2/backup_record.py +15 -6
  297. openstackclient/volume/v2/consistency_group.py +29 -17
  298. openstackclient/volume/v2/consistency_group_snapshot.py +25 -10
  299. openstackclient/volume/v2/qos_specs.py +28 -17
  300. openstackclient/volume/v2/service.py +17 -6
  301. openstackclient/volume/v2/volume.py +60 -30
  302. openstackclient/volume/v2/volume_backend.py +19 -6
  303. openstackclient/volume/v2/volume_backup.py +48 -23
  304. openstackclient/volume/v2/volume_host.py +6 -4
  305. openstackclient/volume/v2/volume_snapshot.py +49 -24
  306. openstackclient/volume/v2/volume_transfer_request.py +31 -13
  307. openstackclient/volume/v2/volume_type.py +43 -24
  308. openstackclient/volume/v3/backup_record.py +94 -0
  309. openstackclient/volume/v3/block_storage_cleanup.py +11 -3
  310. openstackclient/volume/v3/block_storage_cluster.py +19 -7
  311. openstackclient/volume/v3/block_storage_log_level.py +15 -6
  312. openstackclient/volume/v3/block_storage_manage.py +10 -4
  313. openstackclient/volume/v3/block_storage_resource_filter.py +17 -5
  314. openstackclient/volume/v3/consistency_group.py +400 -0
  315. openstackclient/volume/v3/consistency_group_snapshot.py +225 -0
  316. openstackclient/volume/v3/qos_specs.py +389 -0
  317. openstackclient/volume/v3/service.py +16 -6
  318. openstackclient/volume/v3/volume.py +92 -40
  319. openstackclient/volume/v3/volume_attachment.py +47 -21
  320. openstackclient/volume/v3/volume_backend.py +130 -0
  321. openstackclient/volume/v3/volume_backup.py +55 -27
  322. openstackclient/volume/v3/volume_group.py +23 -13
  323. openstackclient/volume/v3/volume_group_snapshot.py +34 -17
  324. openstackclient/volume/v3/volume_group_type.py +27 -14
  325. openstackclient/volume/v3/volume_host.py +74 -0
  326. openstackclient/volume/v3/volume_message.py +18 -8
  327. openstackclient/volume/v3/volume_snapshot.py +70 -32
  328. openstackclient/volume/v3/volume_transfer_request.py +31 -13
  329. openstackclient/volume/v3/volume_type.py +42 -24
  330. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/METADATA +7 -8
  331. python_openstackclient-10.1.0.dist-info/RECORD +524 -0
  332. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/WHEEL +1 -1
  333. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/entry_points.txt +77 -25
  334. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/licenses/AUTHORS +9 -0
  335. python_openstackclient-10.1.0.dist-info/pbr.json +1 -0
  336. openstackclient/api/image_v1.py +0 -69
  337. openstackclient/api/image_v2.py +0 -79
  338. openstackclient/network/v2/floating_ip_pool.py +0 -38
  339. openstackclient/tests/functional/image/v1/test_image.py +0 -97
  340. openstackclient/tests/unit/api/test_image_v1.py +0 -96
  341. openstackclient/tests/unit/api/test_image_v2.py +0 -96
  342. openstackclient/tests/unit/network/v2/test_floating_ip_compute.py +0 -248
  343. openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py +0 -49
  344. openstackclient/tests/unit/network/v2/test_floating_ip_pool_network.py +0 -39
  345. openstackclient/tests/unit/network/v2/test_network_compute.py +0 -404
  346. openstackclient/tests/unit/network/v2/test_security_group_compute.py +0 -392
  347. openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +0 -555
  348. python_openstackclient-9.0.0.dist-info/RECORD +0 -499
  349. python_openstackclient-9.0.0.dist-info/pbr.json +0 -1
  350. /openstackclient/{tests/functional/image/v1 → network/v2/bgpvpn}/__init__.py +0 -0
  351. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/licenses/LICENSE +0 -0
  352. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/top_level.txt +0 -0
@@ -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, object]:
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',
@@ -627,10 +644,14 @@ class ListVolume(command.Lister):
627
644
  default=False,
628
645
  help=_('List additional fields in output'),
629
646
  )
630
- pagination.add_marker_pagination_option_to_parser(parser)
647
+ pagination.add_marker_pagination_option_to_parser(
648
+ parser, include_max_items=False
649
+ )
631
650
  return parser
632
651
 
633
- def take_action(self, parsed_args):
652
+ def take_action(
653
+ self, parsed_args: argparse.Namespace
654
+ ) -> tuple[Sequence[str], Iterable[tuple[Any, ...]]]:
634
655
  volume_client = self.app.client_manager.volume
635
656
  identity_client = self.app.client_manager.identity
636
657
 
@@ -706,7 +727,7 @@ class ListVolume(command.Lister):
706
727
  compute_client = self.app.client_manager.compute
707
728
  for s in compute_client.servers():
708
729
  server_cache[s.id] = s
709
- except sdk_exceptions.SDKException: # noqa: S110
730
+ except sdk_exceptions.SDKException:
710
731
  # Just forget it if there's any trouble
711
732
  pass
712
733
  AttachmentsColumnWithCache = functools.partial(
@@ -736,21 +757,29 @@ class ListVolume(command.Lister):
736
757
  class MigrateVolume(command.Command):
737
758
  _description = _("Migrate volume to a new host")
738
759
 
739
- def get_parser(self, prog_name):
760
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
740
761
  parser = super().get_parser(prog_name)
741
762
  parser.add_argument(
742
763
  'volume',
743
764
  metavar="<volume>",
744
765
  help=_("Volume to migrate (name or ID)"),
745
766
  )
746
- parser.add_argument(
767
+ destination_group = parser.add_mutually_exclusive_group(required=True)
768
+ destination_group.add_argument(
747
769
  '--host',
748
770
  metavar="<host>",
749
- required=True,
750
771
  help=_(
751
772
  "Destination host (takes the form: host@backend-name#pool)"
752
773
  ),
753
774
  )
775
+ destination_group.add_argument(
776
+ '--cluster',
777
+ metavar="<cluster>",
778
+ help=_(
779
+ "Destination cluster to migrate the volume to "
780
+ "(requires --os-volume-api-version 3.16 or higher)"
781
+ ),
782
+ )
754
783
  parser.add_argument(
755
784
  '--force-host-copy',
756
785
  action="store_true",
@@ -768,26 +797,38 @@ class MigrateVolume(command.Command):
768
797
  "(possibly by another operation)"
769
798
  ),
770
799
  )
771
- # TODO(stephenfin): Add --cluster argument
772
800
  return parser
773
801
 
774
- def take_action(self, parsed_args):
775
- volume_client = self.app.client_manager.sdk_connection.volume
802
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
803
+ volume_client = sdk_utils.ensure_service_version(
804
+ self.app.client_manager.sdk_connection.volume, '3'
805
+ )
776
806
  volume = volume_client.find_volume(
777
807
  parsed_args.volume, ignore_missing=False
778
808
  )
809
+
810
+ if parsed_args.cluster and not sdk_utils.supports_microversion(
811
+ volume_client, '3.16'
812
+ ):
813
+ msg = _(
814
+ "--os-volume-api-version 3.16 or greater is required to "
815
+ "support the volume migration with cluster"
816
+ )
817
+ raise exceptions.CommandError(msg)
818
+
779
819
  volume_client.migrate_volume(
780
820
  volume.id,
781
821
  host=parsed_args.host,
782
822
  force_host_copy=parsed_args.force_host_copy,
783
823
  lock_volume=parsed_args.lock_volume,
824
+ cluster=parsed_args.cluster,
784
825
  )
785
826
 
786
827
 
787
828
  class SetVolume(command.Command):
788
829
  _description = _("Set volume properties")
789
830
 
790
- def get_parser(self, prog_name):
831
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
791
832
  parser = super().get_parser(prog_name)
792
833
  parser.add_argument(
793
834
  'volume',
@@ -940,7 +981,7 @@ class SetVolume(command.Command):
940
981
  )
941
982
  return parser
942
983
 
943
- def take_action(self, parsed_args):
984
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
944
985
  volume_client = self.app.client_manager.volume
945
986
  volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
946
987
 
@@ -1113,7 +1154,7 @@ class SetVolume(command.Command):
1113
1154
  class ShowVolume(command.ShowOne):
1114
1155
  _description = _("Display volume details")
1115
1156
 
1116
- def get_parser(self, prog_name):
1157
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
1117
1158
  parser = super().get_parser(prog_name)
1118
1159
  parser.add_argument(
1119
1160
  'volume',
@@ -1122,20 +1163,25 @@ class ShowVolume(command.ShowOne):
1122
1163
  )
1123
1164
  return parser
1124
1165
 
1125
- def take_action(self, parsed_args):
1126
- volume_client = self.app.client_manager.sdk_connection.volume
1166
+ def take_action(
1167
+ self, parsed_args: argparse.Namespace
1168
+ ) -> tuple[Sequence[str], Iterable[Any]]:
1169
+ volume_client = sdk_utils.ensure_service_version(
1170
+ self.app.client_manager.sdk_connection.volume, '3'
1171
+ )
1127
1172
  volume = volume_client.find_volume(
1128
1173
  parsed_args.volume, ignore_missing=False
1129
1174
  )
1130
1175
 
1131
1176
  data = _format_volume(volume)
1132
- return zip(*sorted(data.items()))
1177
+ col_headers, col_data = zip(*sorted(data.items()))
1178
+ return col_headers, col_data
1133
1179
 
1134
1180
 
1135
1181
  class UnsetVolume(command.Command):
1136
1182
  _description = _("Unset volume properties")
1137
1183
 
1138
- def get_parser(self, prog_name):
1184
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
1139
1185
  parser = super().get_parser(prog_name)
1140
1186
  parser.add_argument(
1141
1187
  'volume',
@@ -1164,7 +1210,7 @@ class UnsetVolume(command.Command):
1164
1210
  )
1165
1211
  return parser
1166
1212
 
1167
- def take_action(self, parsed_args):
1213
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
1168
1214
  volume_client = self.app.client_manager.volume
1169
1215
  volume = utils.find_resource(volume_client.volumes, parsed_args.volume)
1170
1216
 
@@ -1196,7 +1242,7 @@ class UnsetVolume(command.Command):
1196
1242
  class VolumeSummary(command.ShowOne):
1197
1243
  _description = _("Show a summary of all volumes in this deployment.")
1198
1244
 
1199
- def get_parser(self, prog_name):
1245
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
1200
1246
  parser = super().get_parser(prog_name)
1201
1247
  parser.add_argument(
1202
1248
  '--all-projects',
@@ -1206,8 +1252,12 @@ class VolumeSummary(command.ShowOne):
1206
1252
  )
1207
1253
  return parser
1208
1254
 
1209
- def take_action(self, parsed_args):
1210
- volume_client = self.app.client_manager.sdk_connection.volume
1255
+ def take_action(
1256
+ self, parsed_args: argparse.Namespace
1257
+ ) -> tuple[Sequence[str], Iterable[Any]]:
1258
+ volume_client = sdk_utils.ensure_service_version(
1259
+ self.app.client_manager.sdk_connection.volume, '3'
1260
+ )
1211
1261
 
1212
1262
  if not sdk_utils.supports_microversion(volume_client, '3.12'):
1213
1263
  msg = _(
@@ -1246,7 +1296,7 @@ class VolumeSummary(command.ShowOne):
1246
1296
  class VolumeRevertToSnapshot(command.Command):
1247
1297
  _description = _("Revert a volume to a snapshot.")
1248
1298
 
1249
- def get_parser(self, prog_name):
1299
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
1250
1300
  parser = super().get_parser(prog_name)
1251
1301
  parser.add_argument(
1252
1302
  'snapshot',
@@ -1258,8 +1308,10 @@ class VolumeRevertToSnapshot(command.Command):
1258
1308
  )
1259
1309
  return parser
1260
1310
 
1261
- def take_action(self, parsed_args):
1262
- volume_client = self.app.client_manager.sdk_connection.volume
1311
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
1312
+ volume_client = sdk_utils.ensure_service_version(
1313
+ self.app.client_manager.sdk_connection.volume, '3'
1314
+ )
1263
1315
 
1264
1316
  if not sdk_utils.supports_microversion(volume_client, '3.40'):
1265
1317
  msg = _(
@@ -10,9 +10,12 @@
10
10
  # License for the specific language governing permissions and limitations
11
11
  # under the License.
12
12
 
13
+ import argparse
14
+ from collections.abc import Iterable, Sequence
13
15
  import logging
14
- import typing as ty
16
+ from typing import Any
15
17
 
18
+ from openstack.block_storage.v3 import attachment as _attachment
16
19
  from openstack import utils as sdk_utils
17
20
  from osc_lib.cli import format_columns
18
21
  from osc_lib import exceptions
@@ -32,7 +35,9 @@ _FILTER_DEPRECATED = _(
32
35
  )
33
36
 
34
37
 
35
- def _format_attachment(attachment):
38
+ def _format_attachment(
39
+ attachment: _attachment.Attachment,
40
+ ) -> tuple[tuple[str, ...], Iterable[Any]]:
36
41
  columns = (
37
42
  'id',
38
43
  'volume_id',
@@ -57,7 +62,7 @@ def _format_attachment(attachment):
57
62
  # VolumeAttachmentManager.create returns a dict while everything else
58
63
  # returns a VolumeAttachment object
59
64
  if isinstance(attachment, dict):
60
- data: tuple[ty.Any, ...] = ()
65
+ data: tuple[Any, ...] = ()
61
66
  for column in columns:
62
67
  if column == 'connection_info':
63
68
  data += (format_columns.DictColumn(attachment[column]),)
@@ -88,7 +93,7 @@ class CreateVolumeAttachment(command.ShowOne):
88
93
  add volume' command should be preferred.
89
94
  """
90
95
 
91
- def get_parser(self, prog_name):
96
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
92
97
  parser = super().get_parser(prog_name)
93
98
  parser.add_argument(
94
99
  'volume',
@@ -171,8 +176,12 @@ class CreateVolumeAttachment(command.ShowOne):
171
176
  )
172
177
  return parser
173
178
 
174
- def take_action(self, parsed_args):
175
- volume_client = self.app.client_manager.sdk_connection.volume
179
+ def take_action(
180
+ self, parsed_args: argparse.Namespace
181
+ ) -> tuple[Sequence[str], Iterable[Any]]:
182
+ volume_client = sdk_utils.ensure_service_version(
183
+ self.app.client_manager.sdk_connection.volume, '3'
184
+ )
176
185
  compute_client = self.app.client_manager.compute
177
186
 
178
187
  if not sdk_utils.supports_microversion(volume_client, '3.27'):
@@ -249,7 +258,7 @@ class DeleteVolumeAttachment(command.Command):
249
258
  remove' command should be preferred.
250
259
  """
251
260
 
252
- def get_parser(self, prog_name):
261
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
253
262
  parser = super().get_parser(prog_name)
254
263
  parser.add_argument(
255
264
  'attachment',
@@ -258,8 +267,10 @@ class DeleteVolumeAttachment(command.Command):
258
267
  )
259
268
  return parser
260
269
 
261
- def take_action(self, parsed_args):
262
- volume_client = self.app.client_manager.sdk_connection.volume
270
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
271
+ volume_client = sdk_utils.ensure_service_version(
272
+ self.app.client_manager.sdk_connection.volume, '3'
273
+ )
263
274
 
264
275
  if not sdk_utils.supports_microversion(volume_client, '3.27'):
265
276
  msg = _(
@@ -280,7 +291,7 @@ class SetVolumeAttachment(command.ShowOne):
280
291
  connected to.
281
292
  """
282
293
 
283
- def get_parser(self, prog_name):
294
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
284
295
  parser = super().get_parser(prog_name)
285
296
  parser.add_argument(
286
297
  'attachment',
@@ -332,8 +343,12 @@ class SetVolumeAttachment(command.ShowOne):
332
343
  )
333
344
  return parser
334
345
 
335
- def take_action(self, parsed_args):
336
- volume_client = self.app.client_manager.sdk_connection.volume
346
+ def take_action(
347
+ self, parsed_args: argparse.Namespace
348
+ ) -> tuple[Sequence[str], Iterable[Any]]:
349
+ volume_client = sdk_utils.ensure_service_version(
350
+ self.app.client_manager.sdk_connection.volume, '3'
351
+ )
337
352
 
338
353
  if not sdk_utils.supports_microversion(volume_client, '3.27'):
339
354
  msg = _(
@@ -363,7 +378,7 @@ class SetVolumeAttachment(command.ShowOne):
363
378
  class CompleteVolumeAttachment(command.Command):
364
379
  """Complete an attachment for a volume."""
365
380
 
366
- def get_parser(self, prog_name):
381
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
367
382
  parser = super().get_parser(prog_name)
368
383
  parser.add_argument(
369
384
  'attachment',
@@ -372,8 +387,10 @@ class CompleteVolumeAttachment(command.Command):
372
387
  )
373
388
  return parser
374
389
 
375
- def take_action(self, parsed_args):
376
- volume_client = self.app.client_manager.sdk_connection.volume
390
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
391
+ volume_client = sdk_utils.ensure_service_version(
392
+ self.app.client_manager.sdk_connection.volume, '3'
393
+ )
377
394
 
378
395
  if not sdk_utils.supports_microversion(volume_client, '3.44'):
379
396
  msg = _(
@@ -388,7 +405,7 @@ class CompleteVolumeAttachment(command.Command):
388
405
  class ListVolumeAttachment(command.Lister):
389
406
  """Lists all volume attachments."""
390
407
 
391
- def get_parser(self, prog_name):
408
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
392
409
  parser = super().get_parser(prog_name)
393
410
  parser.add_argument(
394
411
  '--project',
@@ -432,8 +449,12 @@ class ListVolumeAttachment(command.Lister):
432
449
  # )
433
450
  return parser
434
451
 
435
- def take_action(self, parsed_args):
436
- volume_client = self.app.client_manager.sdk_connection.volume
452
+ def take_action(
453
+ self, parsed_args: argparse.Namespace
454
+ ) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
455
+ volume_client = sdk_utils.ensure_service_version(
456
+ self.app.client_manager.sdk_connection.volume, '3'
457
+ )
437
458
  identity_client = self.app.client_manager.identity
438
459
 
439
460
  if not sdk_utils.supports_microversion(volume_client, '3.27'):
@@ -466,6 +487,7 @@ class ListVolumeAttachment(command.Lister):
466
487
  search_opts=search_opts,
467
488
  marker=parsed_args.marker,
468
489
  limit=parsed_args.limit,
490
+ max_items=parsed_args.max_items,
469
491
  )
470
492
 
471
493
  column_headers = (
@@ -490,7 +512,7 @@ class ListVolumeAttachment(command.Lister):
490
512
  class ShowVolumeAttachment(command.ShowOne):
491
513
  """Show detailed information for a volume attachment."""
492
514
 
493
- def get_parser(self, prog_name):
515
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
494
516
  parser = super().get_parser(prog_name)
495
517
  parser.add_argument(
496
518
  'attachment',
@@ -499,8 +521,12 @@ class ShowVolumeAttachment(command.ShowOne):
499
521
  )
500
522
  return parser
501
523
 
502
- def take_action(self, parsed_args):
503
- volume_client = self.app.client_manager.sdk_connection.volume
524
+ def take_action(
525
+ self, parsed_args: argparse.Namespace
526
+ ) -> tuple[Sequence[str], Iterable[Any]]:
527
+ volume_client = sdk_utils.ensure_service_version(
528
+ self.app.client_manager.sdk_connection.volume, '3'
529
+ )
504
530
 
505
531
  if not sdk_utils.supports_microversion(volume_client, '3.27'):
506
532
  msg = _(
@@ -0,0 +1,130 @@
1
+ #
2
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
3
+ # not use this file except in compliance with the License. You may obtain
4
+ # a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11
+ # License for the specific language governing permissions and limitations
12
+ # under the License.
13
+ #
14
+
15
+ """Storage backend action implementations"""
16
+
17
+ import argparse
18
+ from collections.abc import Iterable, Sequence
19
+ from typing import Any
20
+
21
+ from openstack import utils as sdk_utils
22
+ from osc_lib.cli import format_columns
23
+ from osc_lib import utils
24
+
25
+ from openstackclient import command
26
+ from openstackclient.i18n import _
27
+
28
+
29
+ class ShowCapability(command.Lister):
30
+ _description = _("Show capability command")
31
+
32
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
33
+ parser = super().get_parser(prog_name)
34
+ parser.add_argument(
35
+ "host",
36
+ metavar="<host>",
37
+ help=_("List capabilities of specified host (host@backend-name)"),
38
+ )
39
+ return parser
40
+
41
+ def take_action(
42
+ self, parsed_args: argparse.Namespace
43
+ ) -> tuple[Sequence[str], Iterable[tuple[Any, ...]]]:
44
+ volume_client = sdk_utils.ensure_service_version(
45
+ self.app.client_manager.sdk_connection.volume, '3'
46
+ )
47
+
48
+ columns = [
49
+ 'Title',
50
+ 'Key',
51
+ 'Type',
52
+ 'Description',
53
+ ]
54
+
55
+ data = volume_client.get_capabilities(parsed_args.host)
56
+
57
+ # The get capabilities API is... interesting. We only want the names of
58
+ # the capabilities that can set for a backend through extra specs, so
59
+ # we need to extract out that part of the mess that is returned.
60
+ print_data = []
61
+ keys = data.properties
62
+ for key in keys:
63
+ # Stuff the key into the details to make it easier to output
64
+ capability_data = data.properties[key]
65
+ capability_data['key'] = key
66
+ print_data.append(capability_data)
67
+
68
+ return (
69
+ columns,
70
+ (
71
+ utils.get_dict_properties(
72
+ s,
73
+ columns,
74
+ )
75
+ for s in print_data
76
+ ),
77
+ )
78
+
79
+
80
+ class ListPool(command.Lister):
81
+ _description = _("List pool command")
82
+
83
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
84
+ parser = super().get_parser(prog_name)
85
+ parser.add_argument(
86
+ "--long",
87
+ action="store_true",
88
+ default=False,
89
+ help=_("Show detailed information about pools."),
90
+ )
91
+ # TODO(smcginnis): Starting with Cinder microversion 3.33, user is also
92
+ # able to pass in --filters with a <key>=<value> pair to filter on.
93
+ return parser
94
+
95
+ def take_action(
96
+ self, parsed_args: argparse.Namespace
97
+ ) -> tuple[Sequence[str], Iterable[tuple[Any, ...]]]:
98
+ volume_client = sdk_utils.ensure_service_version(
99
+ self.app.client_manager.sdk_connection.volume, '3'
100
+ )
101
+
102
+ if parsed_args.long:
103
+ columns = [
104
+ 'name',
105
+ 'capabilities',
106
+ ]
107
+
108
+ headers = [
109
+ 'Name',
110
+ 'Capabilities',
111
+ ]
112
+ else:
113
+ columns = [
114
+ 'Name',
115
+ ]
116
+ headers = columns
117
+
118
+ data = volume_client.backend_pools(detailed=parsed_args.long)
119
+ formatters = {'capabilities': format_columns.DictColumn}
120
+ return (
121
+ headers,
122
+ (
123
+ utils.get_item_properties(
124
+ s,
125
+ columns,
126
+ formatters=formatters,
127
+ )
128
+ for s in data
129
+ ),
130
+ )