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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (284) hide show
  1. openstackclient/__init__.py +2 -6
  2. openstackclient/api/api.py +41 -23
  3. openstackclient/api/compute_v2.py +44 -25
  4. openstackclient/api/object_store_v1.py +75 -97
  5. openstackclient/api/volume_v2.py +2 -1
  6. openstackclient/api/volume_v3.py +2 -1
  7. openstackclient/common/availability_zone.py +58 -42
  8. openstackclient/common/clientmanager.py +56 -29
  9. openstackclient/common/configuration.py +10 -3
  10. openstackclient/common/envvars.py +2 -2
  11. openstackclient/common/extension.py +14 -5
  12. openstackclient/common/limits.py +10 -5
  13. openstackclient/common/module.py +14 -6
  14. openstackclient/common/pagination.py +8 -2
  15. openstackclient/common/progressbar.py +7 -6
  16. openstackclient/common/project_cleanup.py +13 -7
  17. openstackclient/common/quota.py +97 -99
  18. openstackclient/common/versions.py +8 -2
  19. openstackclient/compute/client.py +7 -3
  20. openstackclient/compute/v2/agent.py +17 -10
  21. openstackclient/compute/v2/aggregate.py +36 -22
  22. openstackclient/compute/v2/console.py +14 -8
  23. openstackclient/compute/v2/console_connection.py +11 -3
  24. openstackclient/compute/v2/flavor.py +39 -21
  25. openstackclient/compute/v2/host.py +14 -6
  26. openstackclient/compute/v2/hypervisor.py +14 -5
  27. openstackclient/compute/v2/hypervisor_stats.py +10 -2
  28. openstackclient/compute/v2/keypair.py +29 -14
  29. openstackclient/compute/v2/server.py +249 -169
  30. openstackclient/compute/v2/server_backup.py +10 -4
  31. openstackclient/compute/v2/server_event.py +21 -12
  32. openstackclient/compute/v2/server_group.py +21 -11
  33. openstackclient/compute/v2/server_image.py +19 -10
  34. openstackclient/compute/v2/server_migration.py +24 -10
  35. openstackclient/compute/v2/server_share.py +274 -0
  36. openstackclient/compute/v2/server_volume.py +10 -4
  37. openstackclient/compute/v2/service.py +14 -7
  38. openstackclient/compute/v2/usage.py +26 -21
  39. openstackclient/identity/client.py +8 -3
  40. openstackclient/identity/common.py +78 -47
  41. openstackclient/identity/v2_0/catalog.py +14 -7
  42. openstackclient/identity/v2_0/ec2creds.py +21 -10
  43. openstackclient/identity/v2_0/endpoint.py +23 -11
  44. openstackclient/identity/v2_0/project.py +25 -14
  45. openstackclient/identity/v2_0/role.py +28 -14
  46. openstackclient/identity/v2_0/role_assignment.py +9 -3
  47. openstackclient/identity/v2_0/service.py +23 -11
  48. openstackclient/identity/v2_0/token.py +12 -5
  49. openstackclient/identity/v2_0/user.py +26 -15
  50. openstackclient/identity/v3/access_rule.py +26 -12
  51. openstackclient/identity/v3/application_credential.py +59 -24
  52. openstackclient/identity/v3/catalog.py +14 -7
  53. openstackclient/identity/v3/consumer.py +22 -11
  54. openstackclient/identity/v3/credential.py +36 -16
  55. openstackclient/identity/v3/domain.py +37 -18
  56. openstackclient/identity/v3/ec2creds.py +25 -12
  57. openstackclient/identity/v3/endpoint.py +42 -20
  58. openstackclient/identity/v3/endpoint_group.py +28 -17
  59. openstackclient/identity/v3/federation_protocol.py +38 -16
  60. openstackclient/identity/v3/group.py +55 -32
  61. openstackclient/identity/v3/identity_provider.py +92 -57
  62. openstackclient/identity/v3/implied_role.py +21 -9
  63. openstackclient/identity/v3/limit.py +38 -16
  64. openstackclient/identity/v3/mapping.py +26 -13
  65. openstackclient/identity/v3/policy.py +23 -12
  66. openstackclient/identity/v3/project.py +43 -23
  67. openstackclient/identity/v3/region.py +36 -16
  68. openstackclient/identity/v3/registered_limit.py +40 -16
  69. openstackclient/identity/v3/role.py +61 -31
  70. openstackclient/identity/v3/role_assignment.py +23 -6
  71. openstackclient/identity/v3/service.py +36 -16
  72. openstackclient/identity/v3/service_provider.py +37 -15
  73. openstackclient/identity/v3/tag.py +23 -6
  74. openstackclient/identity/v3/token.py +30 -14
  75. openstackclient/identity/v3/trust.py +32 -14
  76. openstackclient/identity/v3/unscoped_saml.py +10 -2
  77. openstackclient/identity/v3/user.py +49 -26
  78. openstackclient/image/client.py +7 -3
  79. openstackclient/image/v1/image.py +33 -26
  80. openstackclient/image/v2/cache.py +14 -9
  81. openstackclient/image/v2/image.py +74 -48
  82. openstackclient/image/v2/info.py +7 -1
  83. openstackclient/image/v2/metadef_namespaces.py +109 -13
  84. openstackclient/image/v2/metadef_objects.py +28 -15
  85. openstackclient/image/v2/metadef_properties.py +24 -13
  86. openstackclient/image/v2/metadef_resource_type_association.py +14 -7
  87. openstackclient/image/v2/metadef_resource_types.py +7 -1
  88. openstackclient/image/v2/task.py +15 -6
  89. openstackclient/locale/tr_TR/LC_MESSAGES/openstackclient.po +7 -192
  90. openstackclient/network/client.py +7 -2
  91. openstackclient/network/common.py +16 -241
  92. openstackclient/network/utils.py +36 -22
  93. openstackclient/network/v2/address_group.py +27 -16
  94. openstackclient/network/v2/address_scope.py +24 -13
  95. openstackclient/network/v2/bgpvpn/bgpvpn.py +463 -0
  96. openstackclient/network/v2/bgpvpn/constants.py +30 -0
  97. openstackclient/network/v2/bgpvpn/network_association.py +214 -0
  98. openstackclient/network/v2/bgpvpn/port_association.py +490 -0
  99. openstackclient/network/v2/bgpvpn/router_association.py +288 -0
  100. openstackclient/network/v2/default_security_group_rule.py +19 -10
  101. openstackclient/network/v2/floating_ip.py +110 -159
  102. openstackclient/network/v2/floating_ip_port_forwarding.py +30 -18
  103. openstackclient/network/v2/fwaas/__init__.py +0 -0
  104. openstackclient/network/v2/fwaas/group.py +466 -0
  105. openstackclient/network/v2/fwaas/policy.py +518 -0
  106. openstackclient/network/v2/fwaas/rule.py +574 -0
  107. openstackclient/network/v2/ip_availability.py +13 -5
  108. openstackclient/network/v2/l3_conntrack_helper.py +22 -13
  109. openstackclient/network/v2/local_ip.py +24 -13
  110. openstackclient/network/v2/local_ip_association.py +14 -7
  111. openstackclient/network/v2/ndp_proxy.py +20 -11
  112. openstackclient/network/v2/network.py +129 -196
  113. openstackclient/network/v2/network_agent.py +46 -25
  114. openstackclient/network/v2/network_auto_allocated_topology.py +22 -11
  115. openstackclient/network/v2/network_flavor.py +27 -16
  116. openstackclient/network/v2/network_flavor_profile.py +23 -12
  117. openstackclient/network/v2/network_meter.py +21 -10
  118. openstackclient/network/v2/network_meter_rule.py +21 -11
  119. openstackclient/network/v2/network_qos_policy.py +25 -15
  120. openstackclient/network/v2/network_qos_rule.py +32 -17
  121. openstackclient/network/v2/network_qos_rule_type.py +13 -5
  122. openstackclient/network/v2/network_rbac.py +23 -12
  123. openstackclient/network/v2/network_segment.py +20 -11
  124. openstackclient/network/v2/network_segment_range.py +56 -29
  125. openstackclient/network/v2/network_service_provider.py +7 -1
  126. openstackclient/network/v2/network_trunk.py +38 -22
  127. openstackclient/network/v2/port.py +54 -29
  128. openstackclient/network/v2/router.py +75 -52
  129. openstackclient/network/v2/security_group.py +87 -157
  130. openstackclient/network/v2/security_group_rule.py +100 -280
  131. openstackclient/network/v2/subnet.py +49 -28
  132. openstackclient/network/v2/subnet_pool.py +30 -17
  133. openstackclient/network/v2/taas/tap_flow.py +22 -11
  134. openstackclient/network/v2/taas/tap_mirror.py +22 -11
  135. openstackclient/network/v2/taas/tap_service.py +23 -12
  136. openstackclient/object/client.py +7 -2
  137. openstackclient/object/v1/account.py +13 -6
  138. openstackclient/object/v1/container.py +25 -15
  139. openstackclient/object/v1/object.py +25 -15
  140. openstackclient/py.typed +0 -0
  141. openstackclient/shell.py +46 -10
  142. openstackclient/tests/functional/base.py +55 -20
  143. openstackclient/tests/functional/common/test_extension.py +4 -0
  144. openstackclient/tests/functional/common/test_quota.py +3 -1
  145. openstackclient/tests/functional/compute/v2/common.py +14 -13
  146. openstackclient/tests/functional/compute/v2/test_flavor.py +3 -1
  147. openstackclient/tests/functional/compute/v2/test_server.py +3 -0
  148. openstackclient/tests/functional/identity/v2/common.py +10 -6
  149. openstackclient/tests/functional/identity/v2/test_role.py +4 -4
  150. openstackclient/tests/functional/identity/v3/common.py +25 -19
  151. openstackclient/tests/functional/identity/v3/test_group.py +20 -20
  152. openstackclient/tests/functional/identity/v3/test_idp.py +3 -1
  153. openstackclient/tests/functional/identity/v3/test_project.py +10 -10
  154. openstackclient/tests/functional/identity/v3/test_role.py +18 -18
  155. openstackclient/tests/functional/identity/v3/test_role_assignment.py +12 -12
  156. openstackclient/tests/functional/identity/v3/test_user.py +8 -8
  157. openstackclient/tests/functional/image/base.py +1 -6
  158. openstackclient/tests/functional/network/v2/common.py +5 -2
  159. openstackclient/tests/functional/network/v2/test_floating_ip.py +10 -4
  160. openstackclient/tests/functional/network/v2/test_ip_availability.py +4 -0
  161. openstackclient/tests/functional/network/v2/test_network_meter_rule.py +3 -2
  162. openstackclient/tests/functional/network/v2/test_network_segment.py +5 -0
  163. openstackclient/tests/functional/network/v2/test_subnet.py +13 -9
  164. openstackclient/tests/functional/object/v1/common.py +4 -0
  165. openstackclient/tests/functional/volume/v2/common.py +4 -0
  166. openstackclient/tests/functional/volume/v2/test_volume_snapshot.py +27 -11
  167. openstackclient/tests/functional/volume/v2/test_volume_type.py +2 -2
  168. openstackclient/tests/functional/volume/v3/common.py +4 -0
  169. openstackclient/tests/functional/volume/v3/test_volume_snapshot.py +11 -7
  170. openstackclient/tests/functional/volume/v3/test_volume_type.py +2 -2
  171. openstackclient/tests/unit/common/test_availability_zone.py +35 -49
  172. openstackclient/tests/unit/common/test_extension.py +2 -2
  173. openstackclient/tests/unit/common/test_module.py +12 -7
  174. openstackclient/tests/unit/common/test_project_cleanup.py +3 -1
  175. openstackclient/tests/unit/common/test_quota.py +6 -26
  176. openstackclient/tests/unit/compute/v2/fakes.py +25 -0
  177. openstackclient/tests/unit/compute/v2/test_flavor.py +28 -2
  178. openstackclient/tests/unit/compute/v2/test_keypair.py +6 -6
  179. openstackclient/tests/unit/compute/v2/test_server.py +11 -96
  180. openstackclient/tests/unit/compute/v2/test_server_share.py +287 -0
  181. openstackclient/tests/unit/identity/v3/fakes.py +3 -0
  182. openstackclient/tests/unit/identity/v3/test_group.py +4 -14
  183. openstackclient/tests/unit/identity/v3/test_identity_provider.py +303 -299
  184. openstackclient/tests/unit/identity/v3/test_user.py +4 -4
  185. openstackclient/tests/unit/image/v2/test_image.py +11 -11
  186. openstackclient/tests/unit/image/v2/test_metadef_namespaces.py +105 -6
  187. openstackclient/tests/unit/network/test_common.py +0 -155
  188. openstackclient/tests/unit/network/v2/bgpvpn/__init__.py +0 -0
  189. openstackclient/tests/unit/network/v2/bgpvpn/fakes.py +179 -0
  190. openstackclient/tests/unit/network/v2/bgpvpn/test_bgpvpn.py +584 -0
  191. openstackclient/tests/unit/network/v2/bgpvpn/test_network_association.py +285 -0
  192. openstackclient/tests/unit/network/v2/bgpvpn/test_port_association.py +384 -0
  193. openstackclient/tests/unit/network/v2/bgpvpn/test_router_association.py +297 -0
  194. openstackclient/tests/unit/network/v2/fwaas/__init__.py +0 -0
  195. openstackclient/tests/unit/network/v2/fwaas/test_group.py +897 -0
  196. openstackclient/tests/unit/network/v2/fwaas/test_policy.py +869 -0
  197. openstackclient/tests/unit/network/v2/fwaas/test_rule.py +980 -0
  198. openstackclient/tests/unit/network/v2/taas/{test_osc_tap_flow.py → test_tap_flow.py} +18 -25
  199. openstackclient/tests/unit/network/v2/taas/{test_osc_tap_mirror.py → test_tap_mirror.py} +19 -29
  200. openstackclient/tests/unit/network/v2/taas/{test_osc_tap_service.py → test_tap_service.py} +19 -29
  201. openstackclient/tests/unit/network/v2/test_address_group.py +2 -2
  202. openstackclient/tests/unit/network/v2/{test_floating_ip_network.py → test_floating_ip.py} +3 -2
  203. openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py +13 -13
  204. openstackclient/tests/unit/network/v2/test_network_agent.py +8 -4
  205. openstackclient/tests/unit/network/v2/test_network_auto_allocated_topology.py +3 -3
  206. openstackclient/tests/unit/network/v2/test_network_flavor.py +2 -2
  207. openstackclient/tests/unit/network/v2/test_network_qos_policy.py +1 -1
  208. openstackclient/tests/unit/network/v2/test_network_qos_rule.py +2 -2
  209. openstackclient/tests/unit/network/v2/test_network_rbac.py +1 -1
  210. openstackclient/tests/unit/network/v2/test_network_segment.py +1 -1
  211. openstackclient/tests/unit/network/v2/test_network_segment_range.py +7 -10
  212. openstackclient/tests/unit/network/v2/test_network_trunk.py +1 -1
  213. openstackclient/tests/unit/network/v2/test_router.py +8 -9
  214. openstackclient/tests/unit/network/v2/{test_security_group_network.py → test_security_group.py} +1 -20
  215. openstackclient/tests/unit/network/v2/{test_security_group_rule_network.py → test_security_group_rule.py} +7 -41
  216. openstackclient/tests/unit/network/v2/test_subnet.py +2 -1
  217. openstackclient/tests/unit/network/v2/test_subnet_pool.py +2 -1
  218. openstackclient/tests/unit/object/v1/fakes.py +8 -7
  219. openstackclient/tests/unit/object/v1/test_container.py +65 -101
  220. openstackclient/tests/unit/object/v1/test_container_all.py +8 -1
  221. openstackclient/tests/unit/object/v1/test_object.py +44 -84
  222. openstackclient/tests/unit/object/v1/test_object_all.py +8 -1
  223. openstackclient/tests/unit/test_hacking.py +108 -0
  224. openstackclient/tests/unit/volume/v2/fakes.py +1 -0
  225. openstackclient/tests/unit/volume/v2/test_volume_backup.py +1 -5
  226. openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +2 -1
  227. openstackclient/tests/unit/volume/v2/test_volume_type.py +2 -4
  228. openstackclient/tests/unit/volume/v3/fakes.py +1 -0
  229. openstackclient/tests/unit/volume/v3/test_volume.py +60 -3
  230. openstackclient/tests/unit/volume/v3/test_volume_attachment.py +1 -1
  231. openstackclient/tests/unit/volume/v3/test_volume_backup.py +1 -5
  232. openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +55 -1
  233. openstackclient/tests/unit/volume/v3/test_volume_type.py +2 -4
  234. openstackclient/volume/client.py +7 -3
  235. openstackclient/volume/v2/backup_record.py +15 -6
  236. openstackclient/volume/v2/consistency_group.py +29 -17
  237. openstackclient/volume/v2/consistency_group_snapshot.py +25 -10
  238. openstackclient/volume/v2/qos_specs.py +28 -17
  239. openstackclient/volume/v2/service.py +17 -6
  240. openstackclient/volume/v2/volume.py +57 -29
  241. openstackclient/volume/v2/volume_backend.py +19 -6
  242. openstackclient/volume/v2/volume_backup.py +46 -20
  243. openstackclient/volume/v2/volume_host.py +6 -4
  244. openstackclient/volume/v2/volume_snapshot.py +50 -24
  245. openstackclient/volume/v2/volume_transfer_request.py +31 -13
  246. openstackclient/volume/v2/volume_type.py +43 -24
  247. openstackclient/volume/v3/block_storage_cleanup.py +11 -3
  248. openstackclient/volume/v3/block_storage_cluster.py +19 -7
  249. openstackclient/volume/v3/block_storage_log_level.py +15 -6
  250. openstackclient/volume/v3/block_storage_manage.py +10 -4
  251. openstackclient/volume/v3/block_storage_resource_filter.py +17 -5
  252. openstackclient/volume/v3/service.py +16 -6
  253. openstackclient/volume/v3/volume.py +89 -39
  254. openstackclient/volume/v3/volume_attachment.py +43 -21
  255. openstackclient/volume/v3/volume_backup.py +53 -24
  256. openstackclient/volume/v3/volume_group.py +23 -13
  257. openstackclient/volume/v3/volume_group_snapshot.py +32 -13
  258. openstackclient/volume/v3/volume_group_type.py +26 -13
  259. openstackclient/volume/v3/volume_message.py +15 -7
  260. openstackclient/volume/v3/volume_snapshot.py +69 -32
  261. openstackclient/volume/v3/volume_transfer_request.py +31 -13
  262. openstackclient/volume/v3/volume_type.py +42 -24
  263. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/METADATA +6 -6
  264. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/RECORD +271 -260
  265. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/WHEEL +1 -1
  266. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/entry_points.txt +53 -1
  267. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/licenses/AUTHORS +4 -0
  268. python_openstackclient-10.0.0.dist-info/pbr.json +1 -0
  269. openstackclient/api/image_v1.py +0 -69
  270. openstackclient/api/image_v2.py +0 -79
  271. openstackclient/network/v2/floating_ip_pool.py +0 -38
  272. openstackclient/tests/functional/image/v1/test_image.py +0 -97
  273. openstackclient/tests/unit/api/test_image_v1.py +0 -96
  274. openstackclient/tests/unit/api/test_image_v2.py +0 -96
  275. openstackclient/tests/unit/network/v2/test_floating_ip_compute.py +0 -248
  276. openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py +0 -49
  277. openstackclient/tests/unit/network/v2/test_floating_ip_pool_network.py +0 -39
  278. openstackclient/tests/unit/network/v2/test_network_compute.py +0 -404
  279. openstackclient/tests/unit/network/v2/test_security_group_compute.py +0 -392
  280. openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +0 -555
  281. python_openstackclient-9.0.0.dist-info/pbr.json +0 -1
  282. /openstackclient/{tests/functional/image/v1 → network/v2/bgpvpn}/__init__.py +0 -0
  283. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/licenses/LICENSE +0 -0
  284. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.0.0.dist-info}/top_level.txt +0 -0
@@ -14,13 +14,15 @@
14
14
  """Security Group Rule action implementations"""
15
15
 
16
16
  import argparse
17
+ from collections.abc import Iterable, Sequence
17
18
  import logging
19
+ from typing import Any
18
20
 
19
21
  from osc_lib.cli import parseractions
20
22
  from osc_lib import exceptions
21
23
  from osc_lib import utils
22
24
 
23
- from openstackclient.api import compute_v2
25
+ from openstackclient import command
24
26
  from openstackclient.i18n import _
25
27
  from openstackclient.identity import common as identity_common
26
28
  from openstackclient.network import common
@@ -29,7 +31,7 @@ from openstackclient.network import utils as network_utils
29
31
  LOG = logging.getLogger(__name__)
30
32
 
31
33
 
32
- def _get_columns(item):
34
+ def _get_columns(item: Any) -> tuple[tuple[str, ...], tuple[str, ...]]:
33
35
  hidden_columns = ['location', 'name', 'tenant_id', 'tags']
34
36
  return utils.get_osc_show_columns_for_sdk_resource(
35
37
  item, {}, hidden_columns
@@ -39,11 +41,12 @@ def _get_columns(item):
39
41
  # TODO(abhiraut): Use the SDK resource mapped attribute names once the
40
42
  # OSC minimum requirements include SDK 1.0.
41
43
  class CreateSecurityGroupRule(
42
- common.NetworkAndComputeShowOne, common.NeutronCommandWithExtraArgs
44
+ command.ShowOne, common.NeutronCommandWithExtraArgs
43
45
  ):
44
46
  _description = _("Create a new security group rule")
45
47
 
46
- def update_parser_common(self, parser):
48
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
49
+ parser = super().get_parser(prog_name)
47
50
  parser.add_argument(
48
51
  'group',
49
52
  metavar='<group>',
@@ -64,24 +67,11 @@ class CreateSecurityGroupRule(
64
67
  metavar="<group>",
65
68
  help=_("Remote security group (name or ID)"),
66
69
  )
67
- if self.is_neutron:
68
- remote_group.add_argument(
69
- "--remote-address-group",
70
- metavar="<group>",
71
- help=_("Remote address group (name or ID)"),
72
- )
73
-
74
- # NOTE(efried): The --dst-port, --protocol, and --proto options exist
75
- # for both nova-network and neutron, but differ slightly. For the sake
76
- # of the docs build, which has to account for both variants, but only
77
- # add each to the parser once, they are handled here rather than in the
78
- # _network- or _compute-specific methods below.
79
-
80
- # --dst-port has a default for nova-net only
81
- if self.is_nova_network:
82
- dst_port_default = dict(default=(0, 0))
83
- else:
84
- dst_port_default = {}
70
+ remote_group.add_argument(
71
+ "--remote-address-group",
72
+ metavar="<group>",
73
+ help=_("Remote address group (name or ID)"),
74
+ )
85
75
  parser.add_argument(
86
76
  '--dst-port',
87
77
  metavar='<port-range>',
@@ -91,115 +81,69 @@ class CreateSecurityGroupRule(
91
81
  "ending port range: 137:139. Required for IP protocols TCP "
92
82
  "and UDP. Ignored for ICMP IP protocols."
93
83
  ),
94
- **dst_port_default,
95
84
  )
96
-
97
- # NOTE(rtheis): Support either protocol option name for now.
98
- # However, consider deprecating and then removing --proto in
99
- # a future release.
100
- protocol_group = parser.add_mutually_exclusive_group()
101
- # --proto[col] has choices for nova-network only
102
- if self.is_nova_network:
103
- proto_choices = dict(choices=['icmp', 'tcp', 'udp'])
104
- else:
105
- proto_choices = {}
106
- protocol_help_compute = _("IP protocol (icmp, tcp, udp; default: tcp)")
107
- protocol_help_network = _(
108
- "IP protocol (ah, dccp, egp, esp, gre, icmp, igmp, ipv6-encap, "
109
- "ipv6-frag, ipv6-icmp, ipv6-nonxt, ipv6-opts, ipv6-route, ospf, "
110
- "pgm, rsvp, sctp, tcp, udp, udplite, vrrp and integer "
111
- "representations [0-255] or any; default: any (all protocols))"
112
- )
113
- if self.is_nova_network:
114
- protocol_help = protocol_help_compute
115
- elif self.is_neutron:
116
- protocol_help = protocol_help_network
117
- else:
118
- # Docs build: compose help for both nova-network and neutron
119
- protocol_help = self.split_help(
120
- protocol_help_network, protocol_help_compute
121
- )
122
-
123
- protocol_group.add_argument(
85
+ parser.add_argument(
124
86
  '--protocol',
125
87
  metavar='<protocol>',
126
88
  type=network_utils.convert_to_lowercase,
127
- help=protocol_help,
128
- **proto_choices,
89
+ help=_(
90
+ "IP protocol (ah, dccp, egp, esp, gre, icmp, igmp, "
91
+ "ipv6-encap, ipv6-frag, ipv6-icmp, ipv6-nonxt, ipv6-opts, "
92
+ "ipv6-route, ospf, pgm, rsvp, sctp, tcp, udp, udplite, vrrp "
93
+ "and integer representations [0-255] or any; "
94
+ "default: any (all protocols))"
95
+ ),
129
96
  )
130
- if not self.is_docs_build:
131
- protocol_group.add_argument(
132
- '--proto',
133
- metavar='<proto>',
134
- type=network_utils.convert_to_lowercase,
135
- help=argparse.SUPPRESS,
136
- **proto_choices,
137
- )
138
-
139
- return parser
140
-
141
- def update_parser_network(self, parser):
142
97
  parser.add_argument(
143
98
  '--description',
144
99
  metavar='<description>',
145
- help=self.enhance_help_neutron(
146
- _("Set security group rule description")
147
- ),
100
+ help=_("Set security group rule description"),
148
101
  )
149
102
  parser.add_argument(
150
103
  '--icmp-type',
151
104
  metavar='<icmp-type>',
152
105
  type=int,
153
- help=self.enhance_help_neutron(
154
- _("ICMP type for ICMP IP protocols")
155
- ),
106
+ help=_("ICMP type for ICMP IP protocols"),
156
107
  )
157
108
  parser.add_argument(
158
109
  '--icmp-code',
159
110
  metavar='<icmp-code>',
160
111
  type=int,
161
- help=self.enhance_help_neutron(
162
- _("ICMP code for ICMP IP protocols")
163
- ),
112
+ help=_("ICMP code for ICMP IP protocols"),
164
113
  )
165
114
  direction_group = parser.add_mutually_exclusive_group()
166
115
  direction_group.add_argument(
167
116
  '--ingress',
168
117
  action='store_true',
169
- help=self.enhance_help_neutron(
170
- _("Rule applies to incoming network traffic (default)")
171
- ),
118
+ help=_("Rule applies to incoming network traffic (default)"),
172
119
  )
173
120
  direction_group.add_argument(
174
121
  '--egress',
175
122
  action='store_true',
176
- help=self.enhance_help_neutron(
177
- _("Rule applies to outgoing network traffic")
178
- ),
123
+ help=_("Rule applies to outgoing network traffic"),
179
124
  )
180
125
  parser.add_argument(
181
126
  '--ethertype',
182
127
  metavar='<ethertype>',
183
128
  choices=['IPv4', 'IPv6'],
184
129
  type=network_utils.convert_ipvx_case,
185
- help=self.enhance_help_neutron(
186
- _(
187
- "Ethertype of network traffic "
188
- "(IPv4, IPv6; default: based on IP protocol)"
189
- )
130
+ help=_(
131
+ "Ethertype of network traffic "
132
+ "(IPv4, IPv6; default: based on IP protocol)"
190
133
  ),
191
134
  )
192
135
  parser.add_argument(
193
136
  '--project',
194
137
  metavar='<project>',
195
- help=self.enhance_help_neutron(_("Owner's project (name or ID)")),
196
- )
197
- identity_common.add_project_domain_option_to_parser(
198
- parser, enhance_help=self.enhance_help_neutron
138
+ help=_("Owner's project (name or ID)"),
199
139
  )
140
+ identity_common.add_project_domain_option_to_parser(parser)
200
141
  return parser
201
142
 
202
- def take_action_network(self, client, parsed_args):
143
+ def take_action(
144
+ self, parsed_args: argparse.Namespace
145
+ ) -> tuple[Sequence[str], Iterable[Any]]:
146
+ client = self.app.client_manager.network
203
147
  # Get the security group ID to hold the rule.
204
148
  security_group_id = client.find_security_group(
205
149
  parsed_args.group, ignore_missing=False
@@ -291,46 +235,12 @@ class CreateSecurityGroupRule(
291
235
  data = utils.get_item_properties(obj, columns)
292
236
  return (display_columns, data)
293
237
 
294
- def take_action_compute(self, client, parsed_args):
295
- group = compute_v2.find_security_group(client, parsed_args.group)
296
- protocol = network_utils.get_protocol(
297
- parsed_args, default_protocol='tcp'
298
- )
299
- if protocol == 'icmp':
300
- from_port, to_port = -1, -1
301
- else:
302
- from_port, to_port = parsed_args.dst_port
303
238
 
304
- remote_ip = None
305
- if parsed_args.remote_group is not None:
306
- parsed_args.remote_group = compute_v2.find_security_group(
307
- client, parsed_args.remote_group
308
- )['id']
309
- if parsed_args.remote_ip is not None:
310
- remote_ip = parsed_args.remote_ip
311
- else:
312
- remote_ip = '0.0.0.0/0'
313
-
314
- obj = compute_v2.create_security_group_rule(
315
- client,
316
- security_group_id=group['id'],
317
- ip_protocol=protocol,
318
- from_port=from_port,
319
- to_port=to_port,
320
- remote_ip=remote_ip,
321
- remote_group=parsed_args.remote_group,
322
- )
323
- return network_utils.format_security_group_rule_show(obj)
324
-
325
-
326
- class DeleteSecurityGroupRule(common.NetworkAndComputeDelete):
239
+ class DeleteSecurityGroupRule(command.Command):
327
240
  _description = _("Delete security group rule(s)")
328
241
 
329
- # Used by base class to find resources in parsed_args.
330
- resource = 'rule'
331
- r = None
332
-
333
- def update_parser_common(self, parser):
242
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
243
+ parser = super().get_parser(prog_name)
334
244
  parser.add_argument(
335
245
  'rule',
336
246
  metavar='<rule>',
@@ -339,131 +249,106 @@ class DeleteSecurityGroupRule(common.NetworkAndComputeDelete):
339
249
  )
340
250
  return parser
341
251
 
342
- def take_action_network(self, client, parsed_args):
343
- obj = client.find_security_group_rule(self.r, ignore_missing=False)
344
- client.delete_security_group_rule(obj)
252
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
253
+ client = self.app.client_manager.network
254
+ result = 0
255
+
256
+ for rule in parsed_args.rule:
257
+ try:
258
+ obj = client.find_security_group_rule(
259
+ rule, ignore_missing=False
260
+ )
261
+ client.delete_security_group_rule(obj)
262
+ except Exception as e:
263
+ result += 1
264
+ LOG.error(
265
+ _(
266
+ "Failed to delete security group rule with "
267
+ "name or ID '%(rule)s': %(e)s"
268
+ ),
269
+ {'rule': rule, 'e': e},
270
+ )
345
271
 
346
- def take_action_compute(self, client, parsed_args):
347
- compute_v2.delete_security_group_rule(client, self.r)
272
+ if result > 0:
273
+ total = len(parsed_args.rule)
274
+ msg = _("%(result)s of %(total)s rules failed to delete.") % {
275
+ 'result': result,
276
+ 'total': total,
277
+ }
278
+ raise exceptions.CommandError(msg)
348
279
 
349
280
 
350
- class ListSecurityGroupRule(common.NetworkAndComputeLister):
281
+ class ListSecurityGroupRule(command.Lister):
351
282
  _description = _("List security group rules")
352
283
 
353
- def _format_network_security_group_rule(self, rule):
284
+ def _format_network_security_group_rule(self, rule: Any) -> dict[str, Any]:
354
285
  """Transform the SDK SecurityGroupRule object to a dict
355
286
 
356
287
  The SDK object gets in the way of reformatting columns...
357
288
  Create port_range column from port_range_min and port_range_max
358
289
  """
359
- rule = rule.to_dict()
360
- rule['port_range'] = network_utils.format_network_port_range(rule)
361
- rule['remote_ip_prefix'] = network_utils.format_remote_ip_prefix(rule)
362
- return rule
290
+ data: dict[str, Any] = rule.to_dict()
291
+ data['port_range'] = network_utils.format_network_port_range(data)
292
+ data['remote_ip_prefix'] = network_utils.format_remote_ip_prefix(data)
293
+ return data
363
294
 
364
- def update_parser_common(self, parser):
295
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
296
+ parser = super().get_parser(prog_name)
365
297
  parser.add_argument(
366
298
  'group',
367
299
  metavar='<group>',
368
300
  nargs='?',
369
301
  help=_("List all rules in this security group (name or ID)"),
370
302
  )
371
- return parser
372
-
373
- def update_parser_network(self, parser):
374
- if not self.is_docs_build:
375
- # Accept but hide the argument for consistency with compute.
376
- # Network will always return all projects for an admin.
377
- parser.add_argument(
378
- '--all-projects',
379
- action='store_true',
380
- default=False,
381
- help=argparse.SUPPRESS,
382
- )
383
-
384
303
  parser.add_argument(
385
304
  '--protocol',
386
305
  metavar='<protocol>',
387
306
  type=network_utils.convert_to_lowercase,
388
- help=self.enhance_help_neutron(
389
- _(
390
- "List only rules with the specified IP protocol "
391
- "(ah, dhcp, egp, esp, gre, "
392
- "icmp, igmp, ipv6-encap, ipv6-frag, ipv6-icmp, "
393
- "ipv6-nonxt, ipv6-opts, ipv6-route, ospf, pgm, rsvp, "
394
- "sctp, tcp, udp, udplite, vrrp and integer "
395
- "representations [0-255] or any; "
396
- "default: any (all protocols))"
397
- )
307
+ help=_(
308
+ "List only rules with the specified IP protocol "
309
+ "(ah, dhcp, egp, esp, gre, icmp, igmp, ipv6-encap, "
310
+ "ipv6-frag, ipv6-icmp, ipv6-nonxt, ipv6-opts, ipv6-route, "
311
+ "ospf, pgm, rsvp, sctp, tcp, udp, udplite, vrrp and integer "
312
+ "representations [0-255] or any; "
313
+ "default: any (all protocols))"
398
314
  ),
399
315
  )
400
316
  parser.add_argument(
401
317
  '--ethertype',
402
318
  metavar='<ethertype>',
403
319
  type=network_utils.convert_to_lowercase,
404
- help=self.enhance_help_neutron(
405
- _(
406
- "List only rules with the specified Ethertype "
407
- "(IPv4 or IPv6)"
408
- )
320
+ help=_(
321
+ "List only rules with the specified Ethertype (IPv4 or IPv6)"
409
322
  ),
410
323
  )
411
324
  direction_group = parser.add_mutually_exclusive_group()
412
325
  direction_group.add_argument(
413
326
  '--ingress',
414
327
  action='store_true',
415
- help=self.enhance_help_neutron(
416
- _("List only rules applied to incoming network traffic")
417
- ),
328
+ help=_("List only rules applied to incoming network traffic"),
418
329
  )
419
330
  direction_group.add_argument(
420
331
  '--egress',
421
332
  action='store_true',
422
- help=self.enhance_help_neutron(
423
- _("List only rules applied to outgoing network traffic")
424
- ),
333
+ help=_("List only rules applied to outgoing network traffic"),
425
334
  )
426
335
  parser.add_argument(
427
336
  '--long',
428
337
  action='store_true',
429
338
  default=False,
430
- help=self.enhance_help_neutron(
431
- _("**Deprecated** This argument is no longer needed")
432
- ),
339
+ help=_("**Deprecated** This argument is no longer needed"),
433
340
  )
434
341
  parser.add_argument(
435
342
  '--project',
436
343
  metavar='<project>',
437
- help=self.enhance_help_neutron(
438
- _("List only rules with the specified project (name or ID)")
439
- ),
440
- )
441
- identity_common.add_project_domain_option_to_parser(
442
- parser, enhance_help=self.enhance_help_neutron
344
+ help=_("List only rules with the specified project (name or ID)"),
443
345
  )
346
+ identity_common.add_project_domain_option_to_parser(parser)
444
347
  return parser
445
348
 
446
- def update_parser_compute(self, parser):
447
- parser.add_argument(
448
- '--all-projects',
449
- action='store_true',
450
- default=False,
451
- help=self.enhance_help_nova_network(
452
- _("Display information from all projects (admin only)")
453
- ),
454
- )
455
- if not self.is_docs_build:
456
- # Accept but hide the argument for consistency with network.
457
- # There are no additional fields to display at this time.
458
- parser.add_argument(
459
- '--long',
460
- action='store_false',
461
- default=False,
462
- help=argparse.SUPPRESS,
463
- )
464
- return parser
465
-
466
- def _get_column_headers(self, parsed_args):
349
+ def _get_column_headers(
350
+ self, parsed_args: argparse.Namespace
351
+ ) -> tuple[str, ...]:
467
352
  column_headers: tuple[str, ...] = (
468
353
  'ID',
469
354
  'IP Protocol',
@@ -472,14 +357,16 @@ class ListSecurityGroupRule(common.NetworkAndComputeLister):
472
357
  'Port Range',
473
358
  'Direction',
474
359
  'Remote Security Group',
360
+ 'Remote Address Group',
475
361
  )
476
- if self.is_neutron:
477
- column_headers += ('Remote Address Group',)
478
362
  if parsed_args.group is None:
479
363
  column_headers += ('Security Group',)
480
364
  return column_headers
481
365
 
482
- def take_action_network(self, client, parsed_args):
366
+ def take_action(
367
+ self, parsed_args: argparse.Namespace
368
+ ) -> tuple[Sequence[str], Iterable[Any]]:
369
+ client = self.app.client_manager.network
483
370
  if parsed_args.long:
484
371
  msg = _(
485
372
  "The --long option has been deprecated and is no longer needed"
@@ -524,7 +411,6 @@ class ListSecurityGroupRule(common.NetworkAndComputeLister):
524
411
  parsed_args.project,
525
412
  parsed_args.project_domain,
526
413
  ).id
527
- query['tenant_id'] = project_id
528
414
  query['project_id'] = project_id
529
415
 
530
416
  rules = [
@@ -543,57 +429,12 @@ class ListSecurityGroupRule(common.NetworkAndComputeLister):
543
429
  ),
544
430
  )
545
431
 
546
- def take_action_compute(self, client, parsed_args):
547
- column_headers = self._get_column_headers(parsed_args)
548
- columns: tuple[str, ...] = (
549
- "ID",
550
- "IP Protocol",
551
- "Ethertype",
552
- "IP Range",
553
- "Port Range",
554
- "Remote Security Group",
555
- )
556
-
557
- rules_to_list = []
558
- if parsed_args.group is not None:
559
- security_group = compute_v2.find_security_group(
560
- client, parsed_args.group
561
- )
562
- rules_to_list = security_group['rules']
563
- else:
564
- columns += ('parent_group_id',)
565
- for security_group in compute_v2.list_security_groups(
566
- client, all_projects=parsed_args.all_projects
567
- ):
568
- rules_to_list.extend(security_group['rules'])
569
-
570
- # NOTE(rtheis): Turn the raw rules into resources.
571
- rules = []
572
- for rule in rules_to_list:
573
- rules.append(
574
- network_utils.transform_compute_security_group_rule(rule),
575
- )
576
- # rules.append(compute_secgroup_rules.SecurityGroupRule(
577
- # client.security_group_rules,
578
- # network_utils.transform_compute_security_group_rule(rule),
579
- # ))
580
-
581
- return (
582
- column_headers,
583
- (
584
- utils.get_dict_properties(
585
- s,
586
- columns,
587
- )
588
- for s in rules
589
- ),
590
- )
591
-
592
432
 
593
- class ShowSecurityGroupRule(common.NetworkAndComputeShowOne):
433
+ class ShowSecurityGroupRule(command.ShowOne):
594
434
  _description = _("Display security group rule details")
595
435
 
596
- def update_parser_common(self, parser):
436
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
437
+ parser = super().get_parser(prog_name)
597
438
  parser.add_argument(
598
439
  'rule',
599
440
  metavar="<rule>",
@@ -601,7 +442,10 @@ class ShowSecurityGroupRule(common.NetworkAndComputeShowOne):
601
442
  )
602
443
  return parser
603
444
 
604
- def take_action_network(self, client, parsed_args):
445
+ def take_action(
446
+ self, parsed_args: argparse.Namespace
447
+ ) -> tuple[Sequence[str], Iterable[Any]]:
448
+ client = self.app.client_manager.network
605
449
  obj = client.find_security_group_rule(
606
450
  parsed_args.rule, ignore_missing=False
607
451
  )
@@ -613,27 +457,3 @@ class ShowSecurityGroupRule(common.NetworkAndComputeShowOne):
613
457
  display_columns, columns = _get_columns(obj)
614
458
  data = utils.get_item_properties(obj, columns)
615
459
  return (display_columns, data)
616
-
617
- def take_action_compute(self, client, parsed_args):
618
- # NOTE(rtheis): Unfortunately, compute does not have an API
619
- # to get or list security group rules so parse through the
620
- # security groups to find all accessible rules in search of
621
- # the requested rule.
622
- obj = None
623
- security_group_rules = []
624
- for security_group in compute_v2.list_security_groups(client):
625
- security_group_rules.extend(security_group['rules'])
626
- for security_group_rule in security_group_rules:
627
- if parsed_args.rule == str(security_group_rule.get('id')):
628
- obj = security_group_rule
629
- break
630
-
631
- if obj is None:
632
- msg = (
633
- _("Could not find security group rule with ID '%s'")
634
- % parsed_args.rule
635
- )
636
- raise exceptions.CommandError(msg)
637
-
638
- # NOTE(rtheis): Format security group rule
639
- return network_utils.format_security_group_rule_show(obj)