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
@@ -13,20 +13,24 @@
13
13
 
14
14
  """Floating IP Port Forwarding action implementations"""
15
15
 
16
+ import argparse
16
17
  import logging
17
- import typing as ty
18
+ from collections.abc import Iterable, Sequence
19
+ from typing import Any
18
20
 
21
+ from openstack.network.v2 import port_forwarding as _port_forwarding
19
22
  from osc_lib import exceptions
20
23
  from osc_lib import utils
21
24
 
22
25
  from openstackclient import command
26
+ from openstackclient.common import pagination
23
27
  from openstackclient.i18n import _
24
28
  from openstackclient.network import common
25
29
 
26
30
  LOG = logging.getLogger(__name__)
27
31
 
28
32
 
29
- def validate_ports_diff(ports):
33
+ def validate_ports_diff(ports: list[int]) -> int:
30
34
  if len(ports) == 0:
31
35
  return 0
32
36
 
@@ -40,7 +44,9 @@ def validate_ports_diff(ports):
40
44
  return ports_diff
41
45
 
42
46
 
43
- def validate_ports_match(internal_ports, external_ports):
47
+ def validate_ports_match(
48
+ internal_ports: list[int], external_ports: list[int]
49
+ ) -> None:
44
50
  internal_ports_diff = validate_ports_diff(internal_ports)
45
51
  external_ports_diff = validate_ports_diff(external_ports)
46
52
 
@@ -52,7 +58,9 @@ def validate_ports_match(internal_ports, external_ports):
52
58
  raise exceptions.CommandError(msg)
53
59
 
54
60
 
55
- def validate_and_assign_port_ranges(parsed_args, attrs):
61
+ def validate_and_assign_port_ranges(
62
+ parsed_args: argparse.Namespace, attrs: dict[str, Any]
63
+ ) -> None:
56
64
  internal_port_range = parsed_args.internal_protocol_port
57
65
  external_port_range = parsed_args.external_protocol_port
58
66
  external_ports = internal_ports = []
@@ -79,13 +87,15 @@ def validate_and_assign_port_ranges(parsed_args, attrs):
79
87
  attrs['external_port'] = int(external_port_range)
80
88
 
81
89
 
82
- def validate_port(port):
90
+ def validate_port(port: int) -> None:
83
91
  if port <= 0 or port > 65535:
84
92
  msg = _("The port number range is <1-65535>")
85
93
  raise exceptions.CommandError(msg)
86
94
 
87
95
 
88
- def _get_columns(item):
96
+ def _get_columns(
97
+ item: _port_forwarding.PortForwarding,
98
+ ) -> tuple[tuple[str, ...], tuple[str, ...]]:
89
99
  hidden_columns = ['location', 'tenant_id']
90
100
  return utils.get_osc_show_columns_for_sdk_resource(
91
101
  item, {}, hidden_columns
@@ -97,7 +107,7 @@ class CreateFloatingIPPortForwarding(
97
107
  ):
98
108
  _description = _("Create floating IP port forwarding")
99
109
 
100
- def get_parser(self, prog_name):
110
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
101
111
  parser = super().get_parser(prog_name)
102
112
  parser.add_argument(
103
113
  '--internal-ip-address',
@@ -164,8 +174,10 @@ class CreateFloatingIPPortForwarding(
164
174
 
165
175
  return parser
166
176
 
167
- def take_action(self, parsed_args):
168
- attrs: dict[str, ty.Any] = {}
177
+ def take_action(
178
+ self, parsed_args: argparse.Namespace
179
+ ) -> tuple[Sequence[str], Iterable[Any]]:
180
+ attrs: dict[str, Any] = {}
169
181
  client = self.app.client_manager.network
170
182
  floating_ip = client.find_ip(
171
183
  parsed_args.floating_ip,
@@ -198,7 +210,7 @@ class CreateFloatingIPPortForwarding(
198
210
  class DeleteFloatingIPPortForwarding(command.Command):
199
211
  _description = _("Delete floating IP port forwarding")
200
212
 
201
- def get_parser(self, prog_name):
213
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
202
214
  parser = super().get_parser(prog_name)
203
215
  parser.add_argument(
204
216
  'floating_ip',
@@ -216,7 +228,7 @@ class DeleteFloatingIPPortForwarding(command.Command):
216
228
  )
217
229
  return parser
218
230
 
219
- def take_action(self, parsed_args):
231
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
220
232
  client = self.app.client_manager.network
221
233
  floating_ip = client.find_ip(
222
234
  parsed_args.floating_ip,
@@ -251,7 +263,7 @@ class DeleteFloatingIPPortForwarding(command.Command):
251
263
  class ListFloatingIPPortForwarding(command.Lister):
252
264
  _description = _("List floating IP port forwarding")
253
265
 
254
- def get_parser(self, prog_name):
266
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
255
267
  parser = super().get_parser(prog_name)
256
268
  parser.add_argument(
257
269
  'floating_ip',
@@ -286,10 +298,12 @@ class ListFloatingIPPortForwarding(command.Lister):
286
298
  "specified protocol number"
287
299
  ),
288
300
  )
289
-
301
+ pagination.add_marker_pagination_option_to_parser(parser)
290
302
  return parser
291
303
 
292
- def take_action(self, parsed_args):
304
+ def take_action(
305
+ self, parsed_args: argparse.Namespace
306
+ ) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
293
307
  client = self.app.client_manager.network
294
308
 
295
309
  columns = (
@@ -315,7 +329,7 @@ class ListFloatingIPPortForwarding(command.Lister):
315
329
  'Description',
316
330
  )
317
331
 
318
- query = {}
332
+ query: dict[str, Any] = {}
319
333
 
320
334
  if parsed_args.port:
321
335
  port = client.find_port(parsed_args.port, ignore_missing=False)
@@ -330,6 +344,12 @@ class ListFloatingIPPortForwarding(command.Lister):
330
344
  )
331
345
  if parsed_args.protocol is not None:
332
346
  query['protocol'] = parsed_args.protocol
347
+ if parsed_args.marker is not None:
348
+ query['marker'] = parsed_args.marker
349
+ if parsed_args.limit is not None:
350
+ query['limit'] = parsed_args.limit
351
+ if parsed_args.max_items is not None:
352
+ query['max_items'] = parsed_args.max_items
333
353
 
334
354
  obj = client.find_ip(
335
355
  parsed_args.floating_ip,
@@ -354,7 +374,7 @@ class ListFloatingIPPortForwarding(command.Lister):
354
374
  class SetFloatingIPPortForwarding(common.NeutronCommandWithExtraArgs):
355
375
  _description = _("Set floating IP Port Forwarding Properties")
356
376
 
357
- def get_parser(self, prog_name):
377
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
358
378
  parser = super().get_parser(prog_name)
359
379
  parser.add_argument(
360
380
  'floating_ip',
@@ -419,7 +439,7 @@ class SetFloatingIPPortForwarding(common.NeutronCommandWithExtraArgs):
419
439
 
420
440
  return parser
421
441
 
422
- def take_action(self, parsed_args):
442
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
423
443
  client = self.app.client_manager.network
424
444
  floating_ip = client.find_ip(
425
445
  parsed_args.floating_ip,
@@ -454,7 +474,7 @@ class SetFloatingIPPortForwarding(common.NeutronCommandWithExtraArgs):
454
474
  class ShowFloatingIPPortForwarding(command.ShowOne):
455
475
  _description = _("Display floating IP Port Forwarding details")
456
476
 
457
- def get_parser(self, prog_name):
477
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
458
478
  parser = super().get_parser(prog_name)
459
479
  parser.add_argument(
460
480
  'floating_ip',
@@ -471,7 +491,9 @@ class ShowFloatingIPPortForwarding(command.ShowOne):
471
491
  )
472
492
  return parser
473
493
 
474
- def take_action(self, parsed_args):
494
+ def take_action(
495
+ self, parsed_args: argparse.Namespace
496
+ ) -> tuple[Sequence[str], Iterable[Any]]:
475
497
  client = self.app.client_manager.network
476
498
  floating_ip = client.find_ip(
477
499
  parsed_args.floating_ip,
File without changes
@@ -0,0 +1,499 @@
1
+ # Copyright 2016-2017 FUJITSU LIMITED
2
+ # All Rights Reserved
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
5
+ # not use this file except in compliance with the License. You may obtain
6
+ # a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations
14
+ # under the License.
15
+
16
+ import argparse
17
+ from collections.abc import Iterable, Sequence
18
+ import logging
19
+ from typing import Any
20
+
21
+ from cliff import columns as cliff_columns
22
+ from osc_lib.cli import identity as identity_utils
23
+ from osc_lib import exceptions
24
+ from osc_lib import utils
25
+ from osc_lib.utils import columns as column_util
26
+
27
+ from openstackclient import command
28
+ from openstackclient.i18n import _
29
+ from openstackclient.identity import common as identity_common
30
+
31
+
32
+ LOG = logging.getLogger(__name__)
33
+
34
+
35
+ class AdminStateColumn(cliff_columns.FormattableColumn[bool]):
36
+ def human_readable(self) -> str:
37
+ return 'UP' if self._value else 'DOWN'
38
+
39
+
40
+ _formatters = {
41
+ 'admin_state_up': AdminStateColumn,
42
+ }
43
+
44
+ _attr_map = (
45
+ ('id', 'ID', column_util.LIST_BOTH),
46
+ ('name', 'Name', column_util.LIST_BOTH),
47
+ ('ingress_firewall_policy_id', 'Ingress Policy ID', column_util.LIST_BOTH),
48
+ ('egress_firewall_policy_id', 'Egress Policy ID', column_util.LIST_BOTH),
49
+ ('description', 'Description', column_util.LIST_LONG_ONLY),
50
+ ('status', 'Status', column_util.LIST_LONG_ONLY),
51
+ ('ports', 'Ports', column_util.LIST_LONG_ONLY),
52
+ ('admin_state_up', 'State', column_util.LIST_LONG_ONLY),
53
+ ('shared', 'Shared', column_util.LIST_LONG_ONLY),
54
+ ('project_id', 'Project', column_util.LIST_LONG_ONLY),
55
+ )
56
+
57
+ _attr_map_dict = {x[0]: x[1] for x in _attr_map}
58
+
59
+
60
+ def _get_common_parser(
61
+ parser: argparse.ArgumentParser,
62
+ ) -> argparse.ArgumentParser:
63
+ parser.add_argument(
64
+ '--description',
65
+ metavar='<description>',
66
+ help=_('Description of the firewall group'),
67
+ )
68
+ ingress_group = parser.add_mutually_exclusive_group()
69
+ ingress_group.add_argument(
70
+ '--ingress-firewall-policy',
71
+ metavar='<ingress-firewall-policy>',
72
+ dest='ingress_firewall_policy',
73
+ help=_('Ingress firewall policy (name or ID)'),
74
+ )
75
+ ingress_group.add_argument(
76
+ '--no-ingress-firewall-policy',
77
+ dest='no_ingress_firewall_policy',
78
+ action='store_true',
79
+ help=_('Detach ingress firewall policy from the firewall group'),
80
+ )
81
+ egress_group = parser.add_mutually_exclusive_group()
82
+ egress_group.add_argument(
83
+ '--egress-firewall-policy',
84
+ metavar='<egress-firewall-policy>',
85
+ dest='egress_firewall_policy',
86
+ help=_('Egress firewall policy (name or ID)'),
87
+ )
88
+ egress_group.add_argument(
89
+ '--no-egress-firewall-policy',
90
+ dest='no_egress_firewall_policy',
91
+ action='store_true',
92
+ help=_('Detach egress firewall policy from the firewall group'),
93
+ )
94
+ shared_group = parser.add_mutually_exclusive_group()
95
+ shared_group.add_argument(
96
+ '--share',
97
+ action='store_true',
98
+ default=None,
99
+ dest='shared',
100
+ help=_(
101
+ 'Share the firewall group to be used in all projects '
102
+ '(by default, it is restricted to be used by the '
103
+ 'current project).'
104
+ ),
105
+ )
106
+ shared_group.add_argument(
107
+ '--no-share',
108
+ action='store_false',
109
+ dest='shared',
110
+ help=_('Restrict use of the firewall group to the current project'),
111
+ )
112
+ admin_group = parser.add_mutually_exclusive_group()
113
+ admin_group.add_argument(
114
+ '--enable',
115
+ action='store_true',
116
+ default=None,
117
+ dest='admin_state_up',
118
+ help=_('Enable firewall group'),
119
+ )
120
+ admin_group.add_argument(
121
+ '--disable',
122
+ action='store_false',
123
+ dest='admin_state_up',
124
+ help=_('Disable firewall group'),
125
+ )
126
+ return parser
127
+
128
+
129
+ def _get_common_attrs(
130
+ client_manager: Any,
131
+ parsed_args: argparse.Namespace,
132
+ is_create: bool = True,
133
+ ) -> dict[str, Any]:
134
+ attrs: dict[str, Any] = {}
135
+ client = client_manager.network
136
+
137
+ if parsed_args.ingress_firewall_policy:
138
+ attrs['ingress_firewall_policy_id'] = client.find_firewall_policy(
139
+ parsed_args.ingress_firewall_policy, ignore_missing=False
140
+ ).id
141
+ elif parsed_args.no_ingress_firewall_policy:
142
+ attrs['ingress_firewall_policy_id'] = None
143
+
144
+ if parsed_args.egress_firewall_policy:
145
+ attrs['egress_firewall_policy_id'] = client.find_firewall_policy(
146
+ parsed_args.egress_firewall_policy, ignore_missing=False
147
+ ).id
148
+ elif parsed_args.no_egress_firewall_policy:
149
+ attrs['egress_firewall_policy_id'] = None
150
+
151
+ if parsed_args.shared is not None:
152
+ attrs['shared'] = parsed_args.shared
153
+ if parsed_args.admin_state_up is not None:
154
+ attrs['admin_state_up'] = parsed_args.admin_state_up
155
+ if parsed_args.name:
156
+ attrs['name'] = parsed_args.name
157
+ if parsed_args.description:
158
+ attrs['description'] = parsed_args.description
159
+ if parsed_args.port and parsed_args.no_port:
160
+ attrs['ports'] = sorted(
161
+ [
162
+ client.find_port(p, ignore_missing=False).id
163
+ for p in set(parsed_args.port)
164
+ ]
165
+ )
166
+ elif parsed_args.port:
167
+ ports = []
168
+ for p in set(parsed_args.port):
169
+ ports.append(client.find_port(p, ignore_missing=False).id)
170
+ if not is_create:
171
+ ports += client.find_firewall_group(
172
+ parsed_args.firewall_group, ignore_missing=False
173
+ ).ports
174
+ attrs['ports'] = sorted(set(ports))
175
+ elif parsed_args.no_port:
176
+ attrs['ports'] = []
177
+ return attrs
178
+
179
+
180
+ class CreateFirewallGroup(command.ShowOne):
181
+ _description = _("Create a new firewall group")
182
+
183
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
184
+ parser = super().get_parser(prog_name)
185
+ _get_common_parser(parser)
186
+ # TODO(slaweq): Remove the deprecated --name option and make the
187
+ # positional name argument required (remove nargs='?') once the
188
+ # deprecation period is over.
189
+ parser.add_argument(
190
+ 'positional_name',
191
+ nargs='?',
192
+ metavar='<name>',
193
+ default=None,
194
+ help=_('Name for the firewall group'),
195
+ )
196
+ parser.add_argument(
197
+ '--name',
198
+ help=_(
199
+ '(Deprecated, please pass name as a positional argument) '
200
+ 'Name for the firewall group'
201
+ ),
202
+ )
203
+ identity_utils.add_project_owner_option_to_parser(parser)
204
+ port_group = parser.add_mutually_exclusive_group()
205
+ port_group.add_argument(
206
+ '--port',
207
+ metavar='<port>',
208
+ action='append',
209
+ help=_(
210
+ 'Port(s) (name or ID) to apply firewall group. This '
211
+ 'option can be repeated'
212
+ ),
213
+ )
214
+ port_group.add_argument(
215
+ '--no-port',
216
+ dest='no_port',
217
+ action='store_true',
218
+ help=_('Detach all port from the firewall group'),
219
+ )
220
+ return parser
221
+
222
+ def take_action(
223
+ self, parsed_args: argparse.Namespace
224
+ ) -> tuple[Sequence[str], Iterable[Any]]:
225
+ client = self.app.client_manager.network
226
+ # TODO(slaweq): Remove this --name deprecation handling once the
227
+ # deprecation period is over.
228
+ if parsed_args.positional_name and parsed_args.name:
229
+ msg = _(
230
+ "Cannot specify name as both a positional argument "
231
+ "and with the --name option."
232
+ )
233
+ raise exceptions.CommandError(msg)
234
+ if parsed_args.name:
235
+ LOG.warning(
236
+ 'The --name option is deprecated for the "firewall group '
237
+ 'create" command, please pass the name as a positional '
238
+ 'argument instead.'
239
+ )
240
+ elif parsed_args.positional_name:
241
+ parsed_args.name = parsed_args.positional_name
242
+ attrs = _get_common_attrs(self.app.client_manager, parsed_args)
243
+ if 'project' in parsed_args and parsed_args.project is not None:
244
+ attrs['project_id'] = identity_common.find_project(
245
+ self.app.client_manager.identity,
246
+ parsed_args.project,
247
+ parsed_args.project_domain,
248
+ ).id
249
+ obj = client.create_firewall_group(**attrs)
250
+ display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
251
+ obj, _attr_map_dict, ['location', 'tenant_id']
252
+ )
253
+ data = utils.get_dict_properties(obj, columns, formatters=_formatters)
254
+ return (display_columns, data)
255
+
256
+
257
+ class DeleteFirewallGroup(command.Command):
258
+ _description = _("Delete firewall group(s)")
259
+
260
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
261
+ parser = super().get_parser(prog_name)
262
+ parser.add_argument(
263
+ 'firewall_group',
264
+ metavar='<firewall-group>',
265
+ nargs='+',
266
+ help=_('Firewall group(s) to delete (name or ID)'),
267
+ )
268
+ return parser
269
+
270
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
271
+ client = self.app.client_manager.network
272
+ result = 0
273
+ for fwg in parsed_args.firewall_group:
274
+ try:
275
+ fwg = client.find_firewall_group(fwg, ignore_missing=False)
276
+ client.delete_firewall_group(fwg.id)
277
+ except Exception as e:
278
+ result += 1
279
+ LOG.error(
280
+ _(
281
+ "Failed to delete firewall group with "
282
+ "name or ID '%(firewall_group)s': %(e)s"
283
+ ),
284
+ {'firewall_group': fwg, 'e': e},
285
+ )
286
+
287
+ if result > 0:
288
+ total = len(parsed_args.firewall_group)
289
+ msg = _(
290
+ "%(result)s of %(total)s firewall group(s) failed to delete."
291
+ ) % {'result': result, 'total': total}
292
+ raise exceptions.CommandError(msg)
293
+
294
+
295
+ class ListFirewallGroup(command.Lister):
296
+ _description = _("List firewall groups")
297
+
298
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
299
+ parser = super().get_parser(prog_name)
300
+ parser.add_argument(
301
+ '--long',
302
+ action='store_true',
303
+ help=_("List additional fields in output"),
304
+ )
305
+ return parser
306
+
307
+ def take_action(
308
+ self, parsed_args: argparse.Namespace
309
+ ) -> tuple[Sequence[str], Iterable[tuple[Any, ...]]]:
310
+ client = self.app.client_manager.network
311
+ obj = client.firewall_groups()
312
+ headers, columns = column_util.get_column_definitions(
313
+ list(_attr_map), long_listing=parsed_args.long
314
+ )
315
+ return (
316
+ headers,
317
+ (
318
+ utils.get_dict_properties(s, columns, formatters=_formatters)
319
+ for s in obj
320
+ ),
321
+ )
322
+
323
+
324
+ class SetFirewallGroup(command.Command):
325
+ _description = _("Set firewall group properties")
326
+
327
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
328
+ parser = super().get_parser(prog_name)
329
+ _get_common_parser(parser)
330
+ parser.add_argument(
331
+ 'firewall_group',
332
+ metavar='<firewall-group>',
333
+ help=_('Firewall group to update (name or ID)'),
334
+ )
335
+ parser.add_argument('--name', help=_('Name for the firewall group'))
336
+ parser.add_argument(
337
+ '--port',
338
+ metavar='<port>',
339
+ action='append',
340
+ help=_(
341
+ 'Port(s) (name or ID) to apply firewall group. This '
342
+ 'option can be repeated'
343
+ ),
344
+ )
345
+ parser.add_argument(
346
+ '--no-port',
347
+ dest='no_port',
348
+ action='store_true',
349
+ help=_('Detach all port from the firewall group'),
350
+ )
351
+ return parser
352
+
353
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
354
+ client = self.app.client_manager.network
355
+ fwg_id = client.find_firewall_group(
356
+ parsed_args.firewall_group, ignore_missing=False
357
+ ).id
358
+ attrs = _get_common_attrs(
359
+ self.app.client_manager, parsed_args, is_create=False
360
+ )
361
+ try:
362
+ client.update_firewall_group(fwg_id, **attrs)
363
+ except Exception as e:
364
+ msg = _("Failed to set firewall group '%(group)s': %(e)s") % {
365
+ 'group': parsed_args.firewall_group,
366
+ 'e': e,
367
+ }
368
+ raise exceptions.CommandError(msg)
369
+
370
+
371
+ class ShowFirewallGroup(command.ShowOne):
372
+ _description = _("Display firewall group details")
373
+
374
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
375
+ parser = super().get_parser(prog_name)
376
+ parser.add_argument(
377
+ 'firewall_group',
378
+ metavar='<firewall-group>',
379
+ help=_('Firewall group to show (name or ID)'),
380
+ )
381
+ return parser
382
+
383
+ def take_action(
384
+ self, parsed_args: argparse.Namespace
385
+ ) -> tuple[Sequence[str], Iterable[Any]]:
386
+ client = self.app.client_manager.network
387
+ fwg_id = client.find_firewall_group(
388
+ parsed_args.firewall_group, ignore_missing=False
389
+ ).id
390
+ obj = client.get_firewall_group(fwg_id)
391
+ display_columns, columns = utils.get_osc_show_columns_for_sdk_resource(
392
+ obj, _attr_map_dict, ['location', 'tenant_id']
393
+ )
394
+ data = utils.get_dict_properties(obj, columns, formatters=_formatters)
395
+ return (display_columns, data)
396
+
397
+
398
+ class UnsetFirewallGroup(command.Command):
399
+ _description = _("Unset firewall group properties")
400
+
401
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
402
+ parser = super().get_parser(prog_name)
403
+ parser.add_argument(
404
+ 'firewall_group',
405
+ metavar='<firewall-group>',
406
+ help=_('Firewall group to unset (name or ID)'),
407
+ )
408
+ port_group = parser.add_mutually_exclusive_group()
409
+ port_group.add_argument(
410
+ '--port',
411
+ metavar='<port>',
412
+ action='append',
413
+ help=_(
414
+ 'Port(s) (name or ID) to apply firewall group. This '
415
+ 'option can be repeated'
416
+ ),
417
+ )
418
+ port_group.add_argument(
419
+ '--all-port',
420
+ action='store_true',
421
+ help=_('Remove all ports for this firewall group'),
422
+ )
423
+ parser.add_argument(
424
+ '--ingress-firewall-policy',
425
+ action='store_true',
426
+ help=_('Ingress firewall policy (name or ID) to delete'),
427
+ )
428
+ parser.add_argument(
429
+ '--egress-firewall-policy',
430
+ action='store_true',
431
+ dest='egress_firewall_policy',
432
+ help=_('Egress firewall policy (name or ID) to delete'),
433
+ )
434
+ shared_group = parser.add_mutually_exclusive_group()
435
+ shared_group.add_argument(
436
+ '--share',
437
+ action='store_true',
438
+ help=_(
439
+ '(Deprecated) Use "firewall group set --no-share" instead. '
440
+ 'Restrict use of the firewall group to the current project'
441
+ ),
442
+ )
443
+ parser.add_argument(
444
+ '--enable',
445
+ action='store_true',
446
+ help=_(
447
+ '(Deprecated) Use "firewall group set --disable" instead. '
448
+ 'Disable firewall group'
449
+ ),
450
+ )
451
+ return parser
452
+
453
+ def _get_attrs(
454
+ self, client: Any, parsed_args: argparse.Namespace
455
+ ) -> dict[str, Any]:
456
+ attrs: dict[str, Any] = {}
457
+ if parsed_args.ingress_firewall_policy:
458
+ attrs['ingress_firewall_policy_id'] = None
459
+ if parsed_args.egress_firewall_policy:
460
+ attrs['egress_firewall_policy_id'] = None
461
+ if parsed_args.share:
462
+ LOG.warning(
463
+ 'The --share option is deprecated, please use '
464
+ '"firewall group set --no-share" instead.'
465
+ )
466
+ attrs['shared'] = False
467
+ if parsed_args.enable:
468
+ LOG.warning(
469
+ 'The --enable option is deprecated, please use '
470
+ '"firewall group set --disable" instead.'
471
+ )
472
+ attrs['admin_state_up'] = False
473
+ if parsed_args.port:
474
+ old = client.find_firewall_group(
475
+ parsed_args.firewall_group, ignore_missing=False
476
+ ).ports
477
+ new = [
478
+ client.find_port(r, ignore_missing=False).id
479
+ for r in parsed_args.port
480
+ ]
481
+ attrs['ports'] = sorted(list(set(old) - set(new)))
482
+ if parsed_args.all_port:
483
+ attrs['ports'] = []
484
+ return attrs
485
+
486
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
487
+ client = self.app.client_manager.network
488
+ fwg_id = client.find_firewall_group(
489
+ parsed_args.firewall_group, ignore_missing=False
490
+ ).id
491
+ attrs = self._get_attrs(client, parsed_args)
492
+ try:
493
+ client.update_firewall_group(fwg_id, **attrs)
494
+ except Exception as e:
495
+ msg = _("Failed to unset firewall group '%(group)s': %(e)s") % {
496
+ 'group': parsed_args.firewall_group,
497
+ 'e': e,
498
+ }
499
+ raise exceptions.CommandError(msg)