python-openstackclient 8.3.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 (292) 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 +126 -114
  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 +251 -171
  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 +103 -41
  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 +26 -12
  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 +71 -50
  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 +115 -92
  64. openstackclient/identity/v3/mapping.py +26 -13
  65. openstackclient/identity/v3/policy.py +23 -12
  66. openstackclient/identity/v3/project.py +211 -122
  67. openstackclient/identity/v3/region.py +36 -16
  68. openstackclient/identity/v3/registered_limit.py +116 -109
  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 -17
  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 +76 -49
  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_limit.py +47 -0
  154. openstackclient/tests/functional/identity/v3/test_project.py +10 -10
  155. openstackclient/tests/functional/identity/v3/test_role.py +18 -18
  156. openstackclient/tests/functional/identity/v3/test_role_assignment.py +12 -12
  157. openstackclient/tests/functional/identity/v3/test_user.py +8 -8
  158. openstackclient/tests/functional/image/base.py +1 -6
  159. openstackclient/tests/functional/image/v2/test_metadef_objects.py +69 -0
  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_snapshot.py +56 -138
  172. openstackclient/tests/functional/volume/v3/test_volume_type.py +2 -2
  173. openstackclient/tests/unit/common/test_availability_zone.py +35 -49
  174. openstackclient/tests/unit/common/test_extension.py +2 -2
  175. openstackclient/tests/unit/common/test_module.py +12 -7
  176. openstackclient/tests/unit/common/test_project_cleanup.py +3 -1
  177. openstackclient/tests/unit/common/test_quota.py +62 -23
  178. openstackclient/tests/unit/compute/v2/fakes.py +25 -0
  179. openstackclient/tests/unit/compute/v2/test_flavor.py +28 -2
  180. openstackclient/tests/unit/compute/v2/test_keypair.py +6 -6
  181. openstackclient/tests/unit/compute/v2/test_server.py +17 -104
  182. openstackclient/tests/unit/compute/v2/test_server_share.py +287 -0
  183. openstackclient/tests/unit/identity/v3/fakes.py +3 -0
  184. openstackclient/tests/unit/identity/v3/test_group.py +4 -14
  185. openstackclient/tests/unit/identity/v3/test_identity_provider.py +303 -299
  186. openstackclient/tests/unit/identity/v3/test_limit.py +197 -145
  187. openstackclient/tests/unit/identity/v3/test_project.py +831 -512
  188. openstackclient/tests/unit/identity/v3/test_protocol.py +97 -88
  189. openstackclient/tests/unit/identity/v3/test_registered_limit.py +355 -220
  190. openstackclient/tests/unit/identity/v3/test_user.py +4 -4
  191. openstackclient/tests/unit/image/v2/test_image.py +16 -16
  192. openstackclient/tests/unit/image/v2/test_metadef_namespaces.py +105 -6
  193. openstackclient/tests/unit/network/test_common.py +0 -155
  194. openstackclient/tests/unit/network/v2/bgpvpn/__init__.py +0 -0
  195. openstackclient/tests/unit/network/v2/bgpvpn/fakes.py +179 -0
  196. openstackclient/tests/unit/network/v2/bgpvpn/test_bgpvpn.py +584 -0
  197. openstackclient/tests/unit/network/v2/bgpvpn/test_network_association.py +285 -0
  198. openstackclient/tests/unit/network/v2/bgpvpn/test_port_association.py +384 -0
  199. openstackclient/tests/unit/network/v2/bgpvpn/test_router_association.py +297 -0
  200. openstackclient/tests/unit/network/v2/fwaas/__init__.py +0 -0
  201. openstackclient/tests/unit/network/v2/fwaas/test_group.py +897 -0
  202. openstackclient/tests/unit/network/v2/fwaas/test_policy.py +869 -0
  203. openstackclient/tests/unit/network/v2/fwaas/test_rule.py +980 -0
  204. openstackclient/tests/unit/network/v2/taas/{test_osc_tap_flow.py → test_tap_flow.py} +18 -25
  205. openstackclient/tests/unit/network/v2/taas/{test_osc_tap_mirror.py → test_tap_mirror.py} +19 -29
  206. openstackclient/tests/unit/network/v2/taas/{test_osc_tap_service.py → test_tap_service.py} +19 -29
  207. openstackclient/tests/unit/network/v2/test_address_group.py +2 -2
  208. openstackclient/tests/unit/network/v2/{test_floating_ip_network.py → test_floating_ip.py} +3 -2
  209. openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py +13 -13
  210. openstackclient/tests/unit/network/v2/test_network_agent.py +8 -4
  211. openstackclient/tests/unit/network/v2/test_network_auto_allocated_topology.py +3 -3
  212. openstackclient/tests/unit/network/v2/test_network_flavor.py +2 -2
  213. openstackclient/tests/unit/network/v2/test_network_qos_policy.py +1 -1
  214. openstackclient/tests/unit/network/v2/test_network_qos_rule.py +2 -2
  215. openstackclient/tests/unit/network/v2/test_network_rbac.py +1 -1
  216. openstackclient/tests/unit/network/v2/test_network_segment.py +1 -1
  217. openstackclient/tests/unit/network/v2/test_network_segment_range.py +7 -10
  218. openstackclient/tests/unit/network/v2/test_network_trunk.py +1 -1
  219. openstackclient/tests/unit/network/v2/test_router.py +8 -9
  220. openstackclient/tests/unit/network/v2/{test_security_group_network.py → test_security_group.py} +1 -20
  221. openstackclient/tests/unit/network/v2/{test_security_group_rule_network.py → test_security_group_rule.py} +7 -41
  222. openstackclient/tests/unit/network/v2/test_subnet.py +2 -1
  223. openstackclient/tests/unit/network/v2/test_subnet_pool.py +2 -1
  224. openstackclient/tests/unit/object/v1/fakes.py +8 -7
  225. openstackclient/tests/unit/object/v1/test_container.py +65 -101
  226. openstackclient/tests/unit/object/v1/test_container_all.py +8 -1
  227. openstackclient/tests/unit/object/v1/test_object.py +44 -84
  228. openstackclient/tests/unit/object/v1/test_object_all.py +8 -1
  229. openstackclient/tests/unit/test_hacking.py +108 -0
  230. openstackclient/tests/unit/volume/v2/fakes.py +1 -0
  231. openstackclient/tests/unit/volume/v2/test_consistency_group.py +8 -2
  232. openstackclient/tests/unit/volume/v2/test_volume.py +7 -6
  233. openstackclient/tests/unit/volume/v2/test_volume_backup.py +1 -5
  234. openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +2 -1
  235. openstackclient/tests/unit/volume/v2/test_volume_type.py +2 -4
  236. openstackclient/tests/unit/volume/v3/fakes.py +1 -0
  237. openstackclient/tests/unit/volume/v3/test_volume.py +94 -15
  238. openstackclient/tests/unit/volume/v3/test_volume_attachment.py +1 -1
  239. openstackclient/tests/unit/volume/v3/test_volume_backup.py +1 -5
  240. openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +55 -1
  241. openstackclient/tests/unit/volume/v3/test_volume_type.py +2 -4
  242. openstackclient/volume/client.py +7 -3
  243. openstackclient/volume/v2/backup_record.py +15 -6
  244. openstackclient/volume/v2/consistency_group.py +37 -25
  245. openstackclient/volume/v2/consistency_group_snapshot.py +27 -12
  246. openstackclient/volume/v2/qos_specs.py +30 -19
  247. openstackclient/volume/v2/service.py +17 -6
  248. openstackclient/volume/v2/volume.py +69 -34
  249. openstackclient/volume/v2/volume_backend.py +19 -6
  250. openstackclient/volume/v2/volume_backup.py +48 -22
  251. openstackclient/volume/v2/volume_host.py +6 -4
  252. openstackclient/volume/v2/volume_snapshot.py +52 -26
  253. openstackclient/volume/v2/volume_transfer_request.py +33 -15
  254. openstackclient/volume/v2/volume_type.py +46 -27
  255. openstackclient/volume/v3/block_storage_cleanup.py +11 -3
  256. openstackclient/volume/v3/block_storage_cluster.py +19 -7
  257. openstackclient/volume/v3/block_storage_log_level.py +15 -6
  258. openstackclient/volume/v3/block_storage_manage.py +10 -4
  259. openstackclient/volume/v3/block_storage_resource_filter.py +17 -5
  260. openstackclient/volume/v3/service.py +16 -6
  261. openstackclient/volume/v3/volume.py +103 -46
  262. openstackclient/volume/v3/volume_attachment.py +43 -21
  263. openstackclient/volume/v3/volume_backup.py +55 -26
  264. openstackclient/volume/v3/volume_group.py +23 -13
  265. openstackclient/volume/v3/volume_group_snapshot.py +32 -13
  266. openstackclient/volume/v3/volume_group_type.py +26 -13
  267. openstackclient/volume/v3/volume_message.py +15 -7
  268. openstackclient/volume/v3/volume_snapshot.py +71 -34
  269. openstackclient/volume/v3/volume_transfer_request.py +33 -15
  270. openstackclient/volume/v3/volume_type.py +45 -27
  271. {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/METADATA +6 -6
  272. {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/RECORD +279 -267
  273. {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/WHEEL +1 -1
  274. {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/entry_points.txt +53 -1
  275. {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/licenses/AUTHORS +9 -0
  276. python_openstackclient-10.0.0.dist-info/pbr.json +1 -0
  277. openstackclient/api/image_v1.py +0 -69
  278. openstackclient/api/image_v2.py +0 -79
  279. openstackclient/network/v2/floating_ip_pool.py +0 -38
  280. openstackclient/tests/functional/image/v1/test_image.py +0 -97
  281. openstackclient/tests/unit/api/test_image_v1.py +0 -96
  282. openstackclient/tests/unit/api/test_image_v2.py +0 -96
  283. openstackclient/tests/unit/network/v2/test_floating_ip_compute.py +0 -248
  284. openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py +0 -49
  285. openstackclient/tests/unit/network/v2/test_floating_ip_pool_network.py +0 -39
  286. openstackclient/tests/unit/network/v2/test_network_compute.py +0 -404
  287. openstackclient/tests/unit/network/v2/test_security_group_compute.py +0 -392
  288. openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +0 -555
  289. python_openstackclient-8.3.0.dist-info/pbr.json +0 -1
  290. /openstackclient/{tests/functional/image/v1 → network/v2/bgpvpn}/__init__.py +0 -0
  291. {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/licenses/LICENSE +0 -0
  292. {python_openstackclient-8.3.0.dist-info → python_openstackclient-10.0.0.dist-info}/top_level.txt +0 -0
@@ -14,21 +14,27 @@
14
14
  """Security Group action implementations"""
15
15
 
16
16
  import argparse
17
- import typing as ty
17
+ from collections.abc import Iterable, Sequence
18
+ import logging
19
+ from typing import Any, cast
18
20
 
19
21
  from cliff import columns as cliff_columns
22
+ from osc_lib import exceptions
20
23
  from osc_lib import utils
21
24
  from osc_lib.utils import tags as _tag
22
25
 
23
- from openstackclient.api import compute_v2
24
26
  from openstackclient import command
25
27
  from openstackclient.i18n import _
26
28
  from openstackclient.identity import common as identity_common
27
29
  from openstackclient.network import common
28
30
  from openstackclient.network import utils as network_utils
29
31
 
32
+ LOG = logging.getLogger(__name__)
30
33
 
31
- def _format_network_security_group_rules(sg_rules):
34
+
35
+ def _format_network_security_group_rules(
36
+ sg_rules: list[dict[str, Any]],
37
+ ) -> str:
32
38
  # For readability and to align with formatting compute security group
33
39
  # rules, trim keys with caller known (e.g. security group and tenant ID)
34
40
  # or empty values.
@@ -39,10 +45,10 @@ def _format_network_security_group_rules(sg_rules):
39
45
  sg_rule.pop('security_group_id', None)
40
46
  sg_rule.pop('tenant_id', None)
41
47
  sg_rule.pop('project_id', None)
42
- return utils.format_list_of_dicts(sg_rules)
48
+ return utils.format_list_of_dicts(sg_rules) or ""
43
49
 
44
50
 
45
- def _format_compute_security_group_rule(sg_rule):
51
+ def _format_compute_security_group_rule(sg_rule: dict[str, Any]) -> str:
46
52
  info = network_utils.transform_compute_security_group_rule(sg_rule)
47
53
  # Trim parent security group ID since caller has this information.
48
54
  info.pop('parent_group_id', None)
@@ -59,20 +65,22 @@ def _format_compute_security_group_rule(sg_rule):
59
65
  return utils.format_dict(info)
60
66
 
61
67
 
62
- def _format_compute_security_group_rules(sg_rules):
68
+ def _format_compute_security_group_rules(
69
+ sg_rules: list[dict[str, Any]],
70
+ ) -> str:
63
71
  rules = []
64
72
  for sg_rule in sg_rules:
65
73
  rules.append(_format_compute_security_group_rule(sg_rule))
66
- return utils.format_list(rules, separator='\n')
74
+ return utils.format_list(rules, separator='\n') or ""
67
75
 
68
76
 
69
- class NetworkSecurityGroupRulesColumn(cliff_columns.FormattableColumn[ty.Any]):
70
- def human_readable(self):
77
+ class NetworkSecurityGroupRulesColumn(cliff_columns.FormattableColumn[Any]):
78
+ def human_readable(self) -> str:
71
79
  return _format_network_security_group_rules(self._value)
72
80
 
73
81
 
74
- class ComputeSecurityGroupRulesColumn(cliff_columns.FormattableColumn[ty.Any]):
75
- def human_readable(self):
82
+ class ComputeSecurityGroupRulesColumn(cliff_columns.FormattableColumn[Any]):
83
+ def human_readable(self) -> str:
76
84
  return _format_compute_security_group_rules(self._value)
77
85
 
78
86
 
@@ -86,7 +94,7 @@ _formatters_compute = {
86
94
  }
87
95
 
88
96
 
89
- def _get_columns(item):
97
+ def _get_columns(item: Any) -> tuple[tuple[str, ...], tuple[str, ...]]:
90
98
  # We still support Nova managed security groups, where we have tenant_id.
91
99
  column_map = {
92
100
  'security_group_rules': 'rules',
@@ -99,12 +107,11 @@ def _get_columns(item):
99
107
 
100
108
  # TODO(abhiraut): Use the SDK resource mapped attribute names once the
101
109
  # OSC minimum requirements include SDK 1.0.
102
- class CreateSecurityGroup(
103
- common.NetworkAndComputeShowOne, common.NeutronCommandWithExtraArgs
104
- ):
110
+ class CreateSecurityGroup(command.ShowOne, common.NeutronCommandWithExtraArgs):
105
111
  _description = _("Create a new security group")
106
112
 
107
- def update_parser_common(self, parser):
113
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
114
+ parser = super().get_parser(prog_name)
108
115
  parser.add_argument(
109
116
  "name", metavar="<name>", help=_("New security group name")
110
117
  )
@@ -113,13 +120,10 @@ class CreateSecurityGroup(
113
120
  metavar="<description>",
114
121
  help=_("Security group description"),
115
122
  )
116
- return parser
117
-
118
- def update_parser_network(self, parser):
119
123
  parser.add_argument(
120
124
  '--project',
121
125
  metavar='<project>',
122
- help=self.enhance_help_neutron(_("Owner's project (name or ID)")),
126
+ help=_("Owner's project (name or ID)"),
123
127
  )
124
128
  stateful_group = parser.add_mutually_exclusive_group()
125
129
  stateful_group.add_argument(
@@ -134,21 +138,20 @@ class CreateSecurityGroup(
134
138
  default=None,
135
139
  help=_("Security group is stateless"),
136
140
  )
137
- identity_common.add_project_domain_option_to_parser(
138
- parser, enhance_help=self.enhance_help_neutron
139
- )
140
- _tag.add_tag_option_to_parser_for_create(
141
- parser, _('security group'), enhance_help=self.enhance_help_neutron
142
- )
141
+ identity_common.add_project_domain_option_to_parser(parser)
142
+ _tag.add_tag_option_to_parser_for_create(parser, _('security group'))
143
143
  return parser
144
144
 
145
- def _get_description(self, parsed_args):
145
+ def _get_description(self, parsed_args: argparse.Namespace) -> str:
146
146
  if parsed_args.description is not None:
147
- return parsed_args.description
147
+ return cast(str, parsed_args.description)
148
148
  else:
149
- return parsed_args.name
149
+ return cast(str, parsed_args.name)
150
150
 
151
- def take_action_network(self, client, parsed_args):
151
+ def take_action(
152
+ self, parsed_args: argparse.Namespace
153
+ ) -> tuple[Sequence[str], Iterable[Any]]:
154
+ client = self.app.client_manager.network
152
155
  # Build the create attributes.
153
156
  attrs = {}
154
157
  attrs['name'] = parsed_args.name
@@ -179,29 +182,12 @@ class CreateSecurityGroup(
179
182
  )
180
183
  return (display_columns, data)
181
184
 
182
- def take_action_compute(self, client, parsed_args):
183
- description = self._get_description(parsed_args)
184
- obj = compute_v2.create_security_group(
185
- client,
186
- parsed_args.name,
187
- description,
188
- )
189
- display_columns = ('description', 'id', 'name', 'project_id', 'rules')
190
- property_columns = ('description', 'id', 'name', 'tenant_id', 'rules')
191
- data = utils.get_dict_properties(
192
- obj, property_columns, formatters=_formatters_compute
193
- )
194
- return (display_columns, data)
195
185
 
196
-
197
- class DeleteSecurityGroup(common.NetworkAndComputeDelete):
186
+ class DeleteSecurityGroup(command.Command):
198
187
  _description = _("Delete security group(s)")
199
188
 
200
- # Used by base class to find resources in parsed_args.
201
- resource = 'group'
202
- r = None
203
-
204
- def update_parser_common(self, parser):
189
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
190
+ parser = super().get_parser(prog_name)
205
191
  parser.add_argument(
206
192
  'group',
207
193
  metavar='<group>',
@@ -210,18 +196,36 @@ class DeleteSecurityGroup(common.NetworkAndComputeDelete):
210
196
  )
211
197
  return parser
212
198
 
213
- def take_action_network(self, client, parsed_args):
214
- obj = client.find_security_group(self.r, ignore_missing=False)
215
- client.delete_security_group(obj)
199
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
200
+ client = self.app.client_manager.network
201
+ result = 0
202
+
203
+ for group in parsed_args.group:
204
+ try:
205
+ obj = client.find_security_group(group, ignore_missing=False)
206
+ client.delete_security_group(obj)
207
+ except Exception as e:
208
+ result += 1
209
+ LOG.error(
210
+ _(
211
+ "Failed to delete security group with "
212
+ "name or ID '%(group)s': %(e)s"
213
+ ),
214
+ {'group': group, 'e': e},
215
+ )
216
216
 
217
- def take_action_compute(self, client, parsed_args):
218
- security_group = compute_v2.find_security_group(client, self.r)
219
- compute_v2.delete_security_group(client, security_group['id'])
217
+ if result > 0:
218
+ total = len(parsed_args.group)
219
+ msg = _("%(result)s of %(total)s groups failed to delete.") % {
220
+ 'result': result,
221
+ 'total': total,
222
+ }
223
+ raise exceptions.CommandError(msg)
220
224
 
221
225
 
222
226
  # TODO(rauta): Use the SDK resource mapped attribute names once
223
227
  # the OSC minimum requirements include SDK 1.0.
224
- class ListSecurityGroup(common.NetworkAndComputeLister):
228
+ class ListSecurityGroup(command.Lister):
225
229
  _description = _("List security groups")
226
230
  FIELDS_TO_RETRIEVE = [
227
231
  'id',
@@ -232,30 +236,17 @@ class ListSecurityGroup(common.NetworkAndComputeLister):
232
236
  'shared',
233
237
  ]
234
238
 
235
- def update_parser_network(self, parser):
236
- if not self.is_docs_build:
237
- # Maintain and hide the argument for backwards compatibility.
238
- # Network will always return all projects for an admin.
239
- parser.add_argument(
240
- '--all-projects',
241
- action='store_true',
242
- default=False,
243
- help=argparse.SUPPRESS,
244
- )
245
-
239
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
240
+ parser = super().get_parser(prog_name)
246
241
  parser.add_argument(
247
242
  '--project',
248
243
  metavar='<project>',
249
- help=self.enhance_help_neutron(
250
- _(
251
- "List only security groups with the specified project "
252
- "(name or ID)"
253
- )
244
+ help=_(
245
+ "List only security groups with the specified project "
246
+ "(name or ID)"
254
247
  ),
255
248
  )
256
- identity_common.add_project_domain_option_to_parser(
257
- parser, enhance_help=self.enhance_help_neutron
258
- )
249
+ identity_common.add_project_domain_option_to_parser(parser)
259
250
 
260
251
  shared_group = parser.add_mutually_exclusive_group()
261
252
  shared_group.add_argument(
@@ -273,23 +264,13 @@ class ListSecurityGroup(common.NetworkAndComputeLister):
273
264
  help=_("List only security groups not shared between projects"),
274
265
  )
275
266
 
276
- _tag.add_tag_filtering_option_to_parser(
277
- parser, _('security group'), enhance_help=self.enhance_help_neutron
278
- )
267
+ _tag.add_tag_filtering_option_to_parser(parser, _('security group'))
279
268
  return parser
280
269
 
281
- def update_parser_compute(self, parser):
282
- parser.add_argument(
283
- '--all-projects',
284
- action='store_true',
285
- default=False,
286
- help=self.enhance_help_nova_network(
287
- _("Display information from all projects (admin only)")
288
- ),
289
- )
290
- return parser
291
-
292
- def take_action_network(self, client, parsed_args):
270
+ def take_action(
271
+ self, parsed_args: argparse.Namespace
272
+ ) -> tuple[Sequence[str], Iterable[Any]]:
273
+ client = self.app.client_manager.network
293
274
  filters = {}
294
275
  if parsed_args.project:
295
276
  identity_client = self.app.client_manager.identity
@@ -335,36 +316,12 @@ class ListSecurityGroup(common.NetworkAndComputeLister):
335
316
  ),
336
317
  )
337
318
 
338
- def take_action_compute(self, client, parsed_args):
339
- data = compute_v2.list_security_groups(
340
- # TODO(dtroyer): add limit, marker
341
- client,
342
- all_projects=parsed_args.all_projects,
343
- )
344
319
 
345
- columns: tuple[str, ...] = ("id", "name", "description")
346
- column_headers: tuple[str, ...] = ("ID", "Name", "Description")
347
- if parsed_args.all_projects:
348
- columns += ('tenant_id',)
349
- column_headers += ('Project',)
350
- return (
351
- column_headers,
352
- (
353
- utils.get_dict_properties(
354
- s,
355
- columns,
356
- )
357
- for s in data
358
- ),
359
- )
360
-
361
-
362
- class SetSecurityGroup(
363
- common.NetworkAndComputeCommand, common.NeutronCommandWithExtraArgs
364
- ):
320
+ class SetSecurityGroup(common.NeutronCommandWithExtraArgs):
365
321
  _description = _("Set security group properties")
366
322
 
367
- def update_parser_common(self, parser):
323
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
324
+ parser = super().get_parser(prog_name)
368
325
  parser.add_argument(
369
326
  'group',
370
327
  metavar='<group>',
@@ -391,15 +348,11 @@ class SetSecurityGroup(
391
348
  default=None,
392
349
  help=_("Security group is stateless"),
393
350
  )
351
+ _tag.add_tag_option_to_parser_for_set(parser, _('security group'))
394
352
  return parser
395
353
 
396
- def update_parser_network(self, parser):
397
- _tag.add_tag_option_to_parser_for_set(
398
- parser, _('security group'), enhance_help=self.enhance_help_neutron
399
- )
400
- return parser
401
-
402
- def take_action_network(self, client, parsed_args):
354
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
355
+ client = self.app.client_manager.network
403
356
  obj = client.find_security_group(
404
357
  parsed_args.group, ignore_missing=False
405
358
  )
@@ -423,29 +376,12 @@ class SetSecurityGroup(
423
376
  # tags is a subresource and it needs to be updated separately.
424
377
  _tag.update_tags_for_set(client, obj, parsed_args)
425
378
 
426
- def take_action_compute(self, client, parsed_args):
427
- security_group = compute_v2.find_security_group(
428
- client, parsed_args.group
429
- )
430
379
 
431
- params = {}
432
- if parsed_args.name is not None:
433
- params['name'] = parsed_args.name
434
- if parsed_args.description is not None:
435
- params['description'] = parsed_args.description
436
-
437
- # NOTE(rtheis): Previous behavior did not raise a CommandError
438
- # if there were no updates. Maintain this behavior and issue
439
- # the update.
440
- compute_v2.update_security_group(
441
- client, security_group['id'], **params
442
- )
443
-
444
-
445
- class ShowSecurityGroup(common.NetworkAndComputeShowOne):
380
+ class ShowSecurityGroup(command.ShowOne):
446
381
  _description = _("Display security group details")
447
382
 
448
- def update_parser_common(self, parser):
383
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
384
+ parser = super().get_parser(prog_name)
449
385
  parser.add_argument(
450
386
  'group',
451
387
  metavar='<group>',
@@ -453,7 +389,10 @@ class ShowSecurityGroup(common.NetworkAndComputeShowOne):
453
389
  )
454
390
  return parser
455
391
 
456
- def take_action_network(self, client, parsed_args):
392
+ def take_action(
393
+ self, parsed_args: argparse.Namespace
394
+ ) -> tuple[Sequence[str], Iterable[Any]]:
395
+ client = self.app.client_manager.network
457
396
  obj = client.find_security_group(
458
397
  parsed_args.group, ignore_missing=False
459
398
  )
@@ -463,20 +402,11 @@ class ShowSecurityGroup(common.NetworkAndComputeShowOne):
463
402
  )
464
403
  return (display_columns, data)
465
404
 
466
- def take_action_compute(self, client, parsed_args):
467
- obj = compute_v2.find_security_group(client, parsed_args.group)
468
- display_columns = ('description', 'id', 'name', 'project_id', 'rules')
469
- property_columns = ('description', 'id', 'name', 'tenant_id', 'rules')
470
- data = utils.get_dict_properties(
471
- obj, property_columns, formatters=_formatters_compute
472
- )
473
- return (display_columns, data)
474
-
475
405
 
476
406
  class UnsetSecurityGroup(command.Command):
477
407
  _description = _("Unset security group properties")
478
408
 
479
- def get_parser(self, prog_name):
409
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
480
410
  parser = super().get_parser(prog_name)
481
411
  parser.add_argument(
482
412
  'group',
@@ -486,7 +416,7 @@ class UnsetSecurityGroup(command.Command):
486
416
  _tag.add_tag_option_to_parser_for_unset(parser, _('security group'))
487
417
  return parser
488
418
 
489
- def take_action(self, parsed_args):
419
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
490
420
  client = self.app.client_manager.network
491
421
  obj = client.find_security_group(
492
422
  parsed_args.group, ignore_missing=False