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
@@ -10,6 +10,10 @@
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
15
+ from typing import Any
16
+
13
17
  from cinderclient import api_versions
14
18
  from osc_lib import exceptions
15
19
  from osc_lib import utils
@@ -18,7 +22,9 @@ from openstackclient import command
18
22
  from openstackclient.i18n import _
19
23
 
20
24
 
21
- def _format_cluster(cluster, detailed=False):
25
+ def _format_cluster(
26
+ cluster: Any, detailed: bool = False
27
+ ) -> tuple[Sequence[str], Iterable[Any]]:
22
28
  columns: tuple[str, ...] = (
23
29
  'name',
24
30
  'binary',
@@ -73,7 +79,7 @@ class ListBlockStorageCluster(command.Lister):
73
79
  This command requires ``--os-volume-api-version`` 3.7 or greater.
74
80
  """
75
81
 
76
- def get_parser(self, prog_name):
82
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
77
83
  parser = super().get_parser(prog_name)
78
84
  parser.add_argument(
79
85
  '--cluster',
@@ -137,7 +143,9 @@ class ListBlockStorageCluster(command.Lister):
137
143
  )
138
144
  return parser
139
145
 
140
- def take_action(self, parsed_args):
146
+ def take_action(
147
+ self, parsed_args: argparse.Namespace
148
+ ) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
141
149
  volume_client = self.app.client_manager.volume
142
150
 
143
151
  if volume_client.api_version < api_versions.APIVersion('3.7'):
@@ -180,7 +188,7 @@ class SetBlockStorageCluster(command.Command):
180
188
  This command requires ``--os-volume-api-version`` 3.7 or greater.
181
189
  """
182
190
 
183
- def get_parser(self, prog_name):
191
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
184
192
  parser = super().get_parser(prog_name)
185
193
  parser.add_argument(
186
194
  'cluster',
@@ -221,7 +229,9 @@ class SetBlockStorageCluster(command.Command):
221
229
  )
222
230
  return parser
223
231
 
224
- def take_action(self, parsed_args):
232
+ def take_action(
233
+ self, parsed_args: argparse.Namespace
234
+ ) -> tuple[Sequence[str], Iterable[Any]]:
225
235
  volume_client = self.app.client_manager.volume
226
236
 
227
237
  if volume_client.api_version < api_versions.APIVersion('3.7'):
@@ -251,7 +261,7 @@ class ShowBlockStorageCluster(command.ShowOne):
251
261
  This command requires ``--os-volume-api-version`` 3.7 or greater.
252
262
  """
253
263
 
254
- def get_parser(self, prog_name):
264
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
255
265
  parser = super().get_parser(prog_name)
256
266
  parser.add_argument(
257
267
  'cluster',
@@ -265,7 +275,9 @@ class ShowBlockStorageCluster(command.ShowOne):
265
275
  )
266
276
  return parser
267
277
 
268
- def take_action(self, parsed_args):
278
+ def take_action(
279
+ self, parsed_args: argparse.Namespace
280
+ ) -> tuple[Sequence[str], Iterable[Any]]:
269
281
  volume_client = self.app.client_manager.volume
270
282
 
271
283
  if volume_client.api_version < api_versions.APIVersion('3.7'):
@@ -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 = _(
@@ -0,0 +1,400 @@
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
+ """Volume v3 consistency group action implementations"""
15
+
16
+ import argparse
17
+ import logging
18
+ from collections.abc import Iterable, Sequence
19
+ from typing import Any
20
+
21
+ from osc_lib.cli import format_columns
22
+ from osc_lib import exceptions
23
+ from osc_lib import utils
24
+
25
+ from openstackclient import command
26
+ from openstackclient.i18n import _
27
+
28
+
29
+ LOG = logging.getLogger(__name__)
30
+
31
+
32
+ def _find_volumes(
33
+ parsed_args_volumes: list[str], volume_client: Any
34
+ ) -> tuple[int, str]:
35
+ result = 0
36
+ uuid = ''
37
+ for volume in parsed_args_volumes:
38
+ try:
39
+ volume_id = utils.find_resource(volume_client.volumes, volume).id
40
+ uuid += volume_id + ','
41
+ except Exception as e:
42
+ result += 1
43
+ LOG.error(
44
+ _("Failed to find volume with name or ID '%(volume)s':%(e)s"),
45
+ {'volume': volume, 'e': e},
46
+ )
47
+
48
+ return result, uuid
49
+
50
+
51
+ class AddVolumeToConsistencyGroup(command.Command):
52
+ _description = _("Add volume(s) to consistency group")
53
+
54
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
55
+ parser = super().get_parser(prog_name)
56
+ parser.add_argument(
57
+ 'consistency_group',
58
+ metavar="<consistency-group>",
59
+ help=_('Consistency group to contain <volume> (name or ID)'),
60
+ )
61
+ parser.add_argument(
62
+ 'volumes',
63
+ metavar='<volume>',
64
+ nargs='+',
65
+ help=_(
66
+ 'Volume(s) to add to <consistency-group> (name or ID) '
67
+ '(repeat option to add multiple volumes)'
68
+ ),
69
+ )
70
+ return parser
71
+
72
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
73
+ volume_client = self.app.client_manager.volume
74
+ result, add_uuid = _find_volumes(parsed_args.volumes, volume_client)
75
+
76
+ if result > 0:
77
+ total = len(parsed_args.volumes)
78
+ LOG.error(
79
+ _("%(result)s of %(total)s volumes failed to add."),
80
+ {'result': result, 'total': total},
81
+ )
82
+
83
+ if add_uuid:
84
+ add_uuid = add_uuid.rstrip(',')
85
+ consistency_group_id = utils.find_resource(
86
+ volume_client.consistencygroups, parsed_args.consistency_group
87
+ ).id
88
+ volume_client.consistencygroups.update(
89
+ consistency_group_id, add_volumes=add_uuid
90
+ )
91
+
92
+
93
+ class CreateConsistencyGroup(command.ShowOne):
94
+ _description = _("Create new consistency group.")
95
+
96
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
97
+ parser = super().get_parser(prog_name)
98
+ parser.add_argument(
99
+ "name",
100
+ metavar="<name>",
101
+ nargs="?",
102
+ help=_("Name of new consistency group (default to None)"),
103
+ )
104
+ exclusive_group = parser.add_mutually_exclusive_group(required=True)
105
+ exclusive_group.add_argument(
106
+ "--volume-type",
107
+ metavar="<volume-type>",
108
+ help=_("Volume type of this consistency group (name or ID)"),
109
+ )
110
+ exclusive_group.add_argument(
111
+ "--source",
112
+ metavar="<consistency-group>",
113
+ help=_("Existing consistency group (name or ID)"),
114
+ )
115
+ # NOTE(stephenfin): Legacy alias
116
+ exclusive_group.add_argument(
117
+ "--consistency-group-source",
118
+ metavar="<consistency-group>",
119
+ dest='source',
120
+ help=argparse.SUPPRESS,
121
+ )
122
+ exclusive_group.add_argument(
123
+ "--snapshot",
124
+ metavar="<consistency-group-snapshot>",
125
+ help=_("Existing consistency group snapshot (name or ID)"),
126
+ )
127
+ # NOTE(stephenfin): Legacy alias
128
+ exclusive_group.add_argument(
129
+ "--consistency-group-snapshot",
130
+ metavar="<consistency-group-snapshot>",
131
+ dest='snapshot',
132
+ help=argparse.SUPPRESS,
133
+ )
134
+ parser.add_argument(
135
+ "--description",
136
+ metavar="<description>",
137
+ help=_("Description of this consistency group"),
138
+ )
139
+ parser.add_argument(
140
+ "--availability-zone",
141
+ metavar="<availability-zone>",
142
+ help=_(
143
+ "Availability zone for this consistency group "
144
+ "(not available if creating consistency group "
145
+ "from source)"
146
+ ),
147
+ )
148
+ return parser
149
+
150
+ def take_action(
151
+ self, parsed_args: argparse.Namespace
152
+ ) -> tuple[Sequence[str], Iterable[Any]]:
153
+ volume_client = self.app.client_manager.volume
154
+ if parsed_args.volume_type:
155
+ volume_type_id = utils.find_resource(
156
+ volume_client.volume_types, parsed_args.volume_type
157
+ ).id
158
+ consistency_group = volume_client.consistencygroups.create(
159
+ volume_type_id,
160
+ name=parsed_args.name,
161
+ description=parsed_args.description,
162
+ availability_zone=parsed_args.availability_zone,
163
+ )
164
+ else:
165
+ if parsed_args.availability_zone:
166
+ msg = _(
167
+ "'--availability-zone' option will not work "
168
+ "if creating consistency group from source"
169
+ )
170
+ LOG.warning(msg)
171
+
172
+ consistency_group_id = None
173
+ consistency_group_snapshot = None
174
+ if parsed_args.source:
175
+ consistency_group_id = utils.find_resource(
176
+ volume_client.consistencygroups,
177
+ parsed_args.source,
178
+ ).id
179
+ elif parsed_args.snapshot:
180
+ consistency_group_snapshot = utils.find_resource(
181
+ volume_client.cgsnapshots,
182
+ parsed_args.snapshot,
183
+ ).id
184
+
185
+ consistency_group = (
186
+ volume_client.consistencygroups.create_from_src(
187
+ consistency_group_snapshot,
188
+ consistency_group_id,
189
+ name=parsed_args.name,
190
+ description=parsed_args.description,
191
+ )
192
+ )
193
+
194
+ col_headers, col_data = zip(*sorted(consistency_group._info.items()))
195
+ return col_headers, col_data
196
+
197
+
198
+ class DeleteConsistencyGroup(command.Command):
199
+ _description = _("Delete consistency group(s).")
200
+
201
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
202
+ parser = super().get_parser(prog_name)
203
+ parser.add_argument(
204
+ 'consistency_groups',
205
+ metavar='<consistency-group>',
206
+ nargs="+",
207
+ help=_('Consistency group(s) to delete (name or ID)'),
208
+ )
209
+ parser.add_argument(
210
+ '--force',
211
+ action='store_true',
212
+ default=False,
213
+ help=_("Allow delete in state other than error or available"),
214
+ )
215
+ return parser
216
+
217
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
218
+ volume_client = self.app.client_manager.volume
219
+ result = 0
220
+
221
+ for i in parsed_args.consistency_groups:
222
+ try:
223
+ consistency_group_id = utils.find_resource(
224
+ volume_client.consistencygroups, i
225
+ ).id
226
+ volume_client.consistencygroups.delete(
227
+ consistency_group_id, parsed_args.force
228
+ )
229
+ except Exception as e:
230
+ result += 1
231
+ LOG.error(
232
+ _(
233
+ "Failed to delete consistency group with "
234
+ "name or ID '%(consistency_group)s':%(e)s"
235
+ ),
236
+ {'consistency_group': i, 'e': e},
237
+ )
238
+
239
+ if result > 0:
240
+ total = len(parsed_args.consistency_groups)
241
+ msg = _(
242
+ "%(result)s of %(total)s consistency groups failed to delete."
243
+ ) % {'result': result, 'total': total}
244
+ raise exceptions.CommandError(msg)
245
+
246
+
247
+ class ListConsistencyGroup(command.Lister):
248
+ _description = _("List consistency groups.")
249
+
250
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
251
+ parser = super().get_parser(prog_name)
252
+ parser.add_argument(
253
+ '--all-projects',
254
+ action="store_true",
255
+ help=_(
256
+ 'Show details for all projects. Admin only. '
257
+ '(defaults to False)'
258
+ ),
259
+ )
260
+ parser.add_argument(
261
+ '--long',
262
+ action="store_true",
263
+ help=_('List additional fields in output'),
264
+ )
265
+ return parser
266
+
267
+ def take_action(
268
+ self, parsed_args: argparse.Namespace
269
+ ) -> tuple[Sequence[str], Iterable[tuple[Any, ...]]]:
270
+ if parsed_args.long:
271
+ columns = [
272
+ 'ID',
273
+ 'Status',
274
+ 'Availability Zone',
275
+ 'Name',
276
+ 'Description',
277
+ 'Volume Types',
278
+ ]
279
+ else:
280
+ columns = ['ID', 'Status', 'Name']
281
+ volume_client = self.app.client_manager.volume
282
+ consistency_groups = volume_client.consistencygroups.list(
283
+ detailed=True,
284
+ search_opts={'all_tenants': parsed_args.all_projects},
285
+ )
286
+
287
+ return (
288
+ columns,
289
+ (
290
+ utils.get_item_properties(
291
+ s,
292
+ columns,
293
+ formatters={'Volume Types': format_columns.ListColumn},
294
+ )
295
+ for s in consistency_groups
296
+ ),
297
+ )
298
+
299
+
300
+ class RemoveVolumeFromConsistencyGroup(command.Command):
301
+ _description = _("Remove volume(s) from consistency group")
302
+
303
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
304
+ parser = super().get_parser(prog_name)
305
+ parser.add_argument(
306
+ 'consistency_group',
307
+ metavar="<consistency-group>",
308
+ help=_('Consistency group containing <volume> (name or ID)'),
309
+ )
310
+ parser.add_argument(
311
+ 'volumes',
312
+ metavar='<volume>',
313
+ nargs='+',
314
+ help=_(
315
+ 'Volume(s) to remove from <consistency-group> (name or ID) '
316
+ '(repeat option to remove multiple volumes)'
317
+ ),
318
+ )
319
+ return parser
320
+
321
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
322
+ volume_client = self.app.client_manager.volume
323
+ result, remove_uuid = _find_volumes(parsed_args.volumes, volume_client)
324
+
325
+ if result > 0:
326
+ total = len(parsed_args.volumes)
327
+ LOG.error(
328
+ _("%(result)s of %(total)s volumes failed to remove."),
329
+ {'result': result, 'total': total},
330
+ )
331
+
332
+ if remove_uuid:
333
+ remove_uuid = remove_uuid.rstrip(',')
334
+ consistency_group_id = utils.find_resource(
335
+ volume_client.consistencygroups, parsed_args.consistency_group
336
+ ).id
337
+ volume_client.consistencygroups.update(
338
+ consistency_group_id, remove_volumes=remove_uuid
339
+ )
340
+
341
+
342
+ class SetConsistencyGroup(command.Command):
343
+ _description = _("Set consistency group properties")
344
+
345
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
346
+ parser = super().get_parser(prog_name)
347
+ parser.add_argument(
348
+ 'consistency_group',
349
+ metavar='<consistency-group>',
350
+ help=_('Consistency group to modify (name or ID)'),
351
+ )
352
+ parser.add_argument(
353
+ '--name',
354
+ metavar='<name>',
355
+ help=_('New consistency group name'),
356
+ )
357
+ parser.add_argument(
358
+ '--description',
359
+ metavar='<description>',
360
+ help=_('New consistency group description'),
361
+ )
362
+ return parser
363
+
364
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
365
+ volume_client = self.app.client_manager.volume
366
+ kwargs = {}
367
+ if parsed_args.name:
368
+ kwargs['name'] = parsed_args.name
369
+ if parsed_args.description:
370
+ kwargs['description'] = parsed_args.description
371
+ if kwargs:
372
+ consistency_group_id = utils.find_resource(
373
+ volume_client.consistencygroups, parsed_args.consistency_group
374
+ ).id
375
+ volume_client.consistencygroups.update(
376
+ consistency_group_id, **kwargs
377
+ )
378
+
379
+
380
+ class ShowConsistencyGroup(command.ShowOne):
381
+ _description = _("Display consistency group details.")
382
+
383
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
384
+ parser = super().get_parser(prog_name)
385
+ parser.add_argument(
386
+ "consistency_group",
387
+ metavar="<consistency-group>",
388
+ help=_("Consistency group to display (name or ID)"),
389
+ )
390
+ return parser
391
+
392
+ def take_action(
393
+ self, parsed_args: argparse.Namespace
394
+ ) -> tuple[Sequence[str], Iterable[Any]]:
395
+ volume_client = self.app.client_manager.volume
396
+ consistency_group = utils.find_resource(
397
+ volume_client.consistencygroups, parsed_args.consistency_group
398
+ )
399
+ col_headers, col_data = zip(*sorted(consistency_group._info.items()))
400
+ return col_headers, col_data