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
@@ -13,8 +13,12 @@
13
13
 
14
14
  """Identity v3 IdentityProvider action implementations"""
15
15
 
16
+ import argparse
17
+ from collections.abc import Iterable, Sequence
16
18
  import logging
19
+ from typing import Any
17
20
 
21
+ from openstack import utils as sdk_utils
18
22
  from osc_lib.cli import format_columns
19
23
  from osc_lib import exceptions
20
24
  from osc_lib import utils
@@ -27,10 +31,35 @@ from openstackclient.identity import common
27
31
  LOG = logging.getLogger(__name__)
28
32
 
29
33
 
34
+ def _format_identity_provider(idp):
35
+ columns = (
36
+ 'authorization_ttl',
37
+ 'description',
38
+ 'domain_id',
39
+ 'is_enabled',
40
+ 'name',
41
+ 'remote_ids',
42
+ )
43
+ column_headers = (
44
+ 'authorization_ttl',
45
+ 'description',
46
+ 'domain_id',
47
+ 'enabled',
48
+ 'id',
49
+ 'remote_ids',
50
+ )
51
+ return (
52
+ column_headers,
53
+ utils.get_item_properties(
54
+ idp, columns, formatters={'remote_ids': format_columns.ListColumn}
55
+ ),
56
+ )
57
+
58
+
30
59
  class CreateIdentityProvider(command.ShowOne):
31
60
  _description = _("Create new identity provider")
32
61
 
33
- def get_parser(self, prog_name):
62
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
34
63
  parser = super().get_parser(prog_name)
35
64
  parser.add_argument(
36
65
  'identity_provider_id',
@@ -98,26 +127,34 @@ class CreateIdentityProvider(command.ShowOne):
98
127
  )
99
128
  return parser
100
129
 
101
- def take_action(self, parsed_args):
102
- identity_client = self.app.client_manager.identity
103
- remote_ids: list[str] | None = None
130
+ def take_action(
131
+ self, parsed_args: argparse.Namespace
132
+ ) -> tuple[Sequence[str], Iterable[Any]]:
133
+ identity_client = sdk_utils.ensure_service_version(
134
+ self.app.client_manager.sdk_connection.identity, '3'
135
+ )
136
+ kwargs = {'is_enabled': parsed_args.enabled}
137
+ if parsed_args.identity_provider_id:
138
+ kwargs['id'] = parsed_args.identity_provider_id
139
+ if parsed_args.description:
140
+ kwargs['description'] = parsed_args.description
141
+
104
142
  if parsed_args.remote_id_file:
105
143
  file_content = utils.read_blob_file_contents(
106
144
  parsed_args.remote_id_file
107
145
  )
108
146
  remote_ids = file_content.splitlines()
109
- remote_ids = list(map(str.strip, remote_ids))
147
+ kwargs['remote_ids'] = list(map(str.strip, remote_ids))
110
148
  elif parsed_args.remote_ids:
111
- remote_ids = parsed_args.remote_ids
149
+ kwargs['remote_ids'] = parsed_args.remote_ids
112
150
 
113
- domain_id = None
114
151
  if parsed_args.domain:
115
- domain_id = common.find_domain(
116
- identity_client, parsed_args.domain
117
- ).id
152
+ kwargs['domain_id'] = common.find_domain_id_sdk(
153
+ identity_client,
154
+ parsed_args.domain,
155
+ validate_actor_existence=False,
156
+ )
118
157
 
119
- # TODO(pas-ha) actually check for 3.14 microversion
120
- kwargs = {}
121
158
  auth_ttl = parsed_args.authorization_ttl
122
159
  if auth_ttl is not None:
123
160
  if auth_ttl < 0:
@@ -127,26 +164,15 @@ class CreateIdentityProvider(command.ShowOne):
127
164
  raise exceptions.CommandError(msg)
128
165
  kwargs['authorization_ttl'] = auth_ttl
129
166
 
130
- idp = identity_client.federation.identity_providers.create(
131
- id=parsed_args.identity_provider_id,
132
- remote_ids=remote_ids,
133
- description=parsed_args.description,
134
- domain_id=domain_id,
135
- enabled=parsed_args.enabled,
136
- **kwargs,
137
- )
167
+ idp = identity_client.create_identity_provider(**kwargs)
138
168
 
139
- idp._info.pop('links', None)
140
- idp._info['remote_ids'] = format_columns.ListColumn(
141
- idp._info.pop('remote_ids', [])
142
- )
143
- return zip(*sorted(idp._info.items()))
169
+ return _format_identity_provider(idp)
144
170
 
145
171
 
146
172
  class DeleteIdentityProvider(command.Command):
147
173
  _description = _("Delete identity provider(s)")
148
174
 
149
- def get_parser(self, prog_name):
175
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
150
176
  parser = super().get_parser(prog_name)
151
177
  parser.add_argument(
152
178
  'identity_provider',
@@ -156,17 +182,19 @@ class DeleteIdentityProvider(command.Command):
156
182
  )
157
183
  return parser
158
184
 
159
- def take_action(self, parsed_args):
160
- identity_client = self.app.client_manager.identity
185
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
186
+ identity_client = sdk_utils.ensure_service_version(
187
+ self.app.client_manager.sdk_connection.identity, '3'
188
+ )
161
189
  result = 0
162
190
  for i in parsed_args.identity_provider:
163
191
  try:
164
- identity_client.federation.identity_providers.delete(i)
192
+ identity_client.delete_identity_provider(i)
165
193
  except Exception as e:
166
194
  result += 1
167
195
  LOG.error(
168
196
  _(
169
- "Failed to delete identity providers with "
197
+ "Failed to delete identity provider with "
170
198
  "name or ID '%(provider)s': %(e)s"
171
199
  ),
172
200
  {'provider': i, 'e': e},
@@ -183,34 +211,39 @@ class DeleteIdentityProvider(command.Command):
183
211
  class ListIdentityProvider(command.Lister):
184
212
  _description = _("List identity providers")
185
213
 
186
- def get_parser(self, prog_name):
214
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
187
215
  parser = super().get_parser(prog_name)
188
216
  parser.add_argument(
189
217
  '--id',
190
218
  metavar='<id>',
191
- help=_('The Identity Providers’ ID attribute'),
219
+ help=_('Filter identity providers by ID'),
192
220
  )
193
221
  parser.add_argument(
194
222
  '--enabled',
195
223
  dest='enabled',
196
224
  action='store_true',
197
- help=_('The Identity Providers that are enabled will be returned'),
225
+ help=_('List only enabled identity providers'),
198
226
  )
199
227
  return parser
200
228
 
201
- def take_action(self, parsed_args):
202
- columns = ('ID', 'Enabled', 'Domain ID', 'Description')
203
- identity_client = self.app.client_manager.identity
229
+ def take_action(
230
+ self, parsed_args: argparse.Namespace
231
+ ) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
232
+ columns = ('id', 'is_enabled', 'domain_id', 'description')
233
+ column_headers = ('ID', 'Enabled', 'Domain ID', 'Description')
234
+ identity_client = sdk_utils.ensure_service_version(
235
+ self.app.client_manager.sdk_connection.identity, '3'
236
+ )
204
237
 
205
238
  kwargs = {}
206
239
  if parsed_args.id:
207
240
  kwargs['id'] = parsed_args.id
208
241
  if parsed_args.enabled:
209
- kwargs['enabled'] = True
242
+ kwargs['is_enabled'] = True
210
243
 
211
- data = identity_client.federation.identity_providers.list(**kwargs)
244
+ data = identity_client.identity_providers(**kwargs)
212
245
  return (
213
- columns,
246
+ column_headers,
214
247
  (
215
248
  utils.get_item_properties(
216
249
  s,
@@ -225,7 +258,7 @@ class ListIdentityProvider(command.Lister):
225
258
  class SetIdentityProvider(command.Command):
226
259
  _description = _("Set identity provider properties")
227
260
 
228
- def get_parser(self, prog_name):
261
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
229
262
  parser = super().get_parser(prog_name)
230
263
  parser.add_argument(
231
264
  'identity_provider',
@@ -279,8 +312,10 @@ class SetIdentityProvider(command.Command):
279
312
  )
280
313
  return parser
281
314
 
282
- def take_action(self, parsed_args):
283
- federation_client = self.app.client_manager.identity.federation
315
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
316
+ identity_client = sdk_utils.ensure_service_version(
317
+ self.app.client_manager.sdk_connection.identity, '3'
318
+ )
284
319
 
285
320
  # Always set remote_ids if either is passed in
286
321
  if parsed_args.remote_id_file:
@@ -297,13 +332,14 @@ class SetIdentityProvider(command.Command):
297
332
  if parsed_args.description:
298
333
  kwargs['description'] = parsed_args.description
299
334
  if parsed_args.enable:
300
- kwargs['enabled'] = True
335
+ kwargs['is_enabled'] = True
301
336
  if parsed_args.disable:
302
- kwargs['enabled'] = False
337
+ kwargs['is_enabled'] = False
303
338
  if parsed_args.remote_id_file or parsed_args.remote_ids:
304
339
  kwargs['remote_ids'] = remote_ids
305
340
 
306
- # TODO(pas-ha) actually check for 3.14 microversion
341
+ # NOTE(0weng): This is now possible in SDK! An option should be added.
342
+ # Original comment:
307
343
  # TODO(pas-ha) make it possible to reset authorization_ttl
308
344
  # back to None value.
309
345
  # Currently not possible as filter_kwargs decorator in
@@ -318,7 +354,7 @@ class SetIdentityProvider(command.Command):
318
354
  raise exceptions.CommandError(msg)
319
355
  kwargs['authorization_ttl'] = auth_ttl
320
356
 
321
- federation_client.identity_providers.update(
357
+ identity_client.update_identity_provider(
322
358
  parsed_args.identity_provider, **kwargs
323
359
  )
324
360
 
@@ -326,7 +362,7 @@ class SetIdentityProvider(command.Command):
326
362
  class ShowIdentityProvider(command.ShowOne):
327
363
  _description = _("Display identity provider details")
328
364
 
329
- def get_parser(self, prog_name):
365
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
330
366
  parser = super().get_parser(prog_name)
331
367
  parser.add_argument(
332
368
  'identity_provider',
@@ -335,15 +371,14 @@ class ShowIdentityProvider(command.ShowOne):
335
371
  )
336
372
  return parser
337
373
 
338
- def take_action(self, parsed_args):
339
- identity_client = self.app.client_manager.identity
340
- idp = utils.find_resource(
341
- identity_client.federation.identity_providers,
342
- parsed_args.identity_provider,
343
- id=parsed_args.identity_provider,
374
+ def take_action(
375
+ self, parsed_args: argparse.Namespace
376
+ ) -> tuple[Sequence[str], Iterable[Any]]:
377
+ identity_client = sdk_utils.ensure_service_version(
378
+ self.app.client_manager.sdk_connection.identity, '3'
379
+ )
380
+ idp = identity_client.get_identity_provider(
381
+ parsed_args.identity_provider
344
382
  )
345
383
 
346
- idp._info.pop('links', None)
347
- remote_ids = format_columns.ListColumn(idp._info.pop('remote_ids', []))
348
- idp._info['remote_ids'] = remote_ids
349
- return zip(*sorted(idp._info.items()))
384
+ return _format_identity_provider(idp)
@@ -15,7 +15,10 @@
15
15
 
16
16
  """Identity v3 Implied Role action implementations"""
17
17
 
18
+ import argparse
19
+ from collections.abc import Iterable, Sequence
18
20
  import logging
21
+ from typing import Any
19
22
 
20
23
 
21
24
  from openstackclient import command
@@ -25,7 +28,9 @@ from openstackclient.i18n import _
25
28
  LOG = logging.getLogger(__name__)
26
29
 
27
30
 
28
- def _get_role_ids(identity_client, parsed_args):
31
+ def _get_role_ids(
32
+ identity_client: Any, parsed_args: argparse.Namespace
33
+ ) -> tuple[Any, Any]:
29
34
  """Return prior and implied role id(s)
30
35
 
31
36
  If prior and implied role id(s) are retrievable from identity
@@ -50,7 +55,7 @@ def _get_role_ids(identity_client, parsed_args):
50
55
  class CreateImpliedRole(command.ShowOne):
51
56
  _description = _("Creates an association between prior and implied roles")
52
57
 
53
- def get_parser(self, prog_name):
58
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
54
59
  parser = super().get_parser(prog_name)
55
60
  parser.add_argument(
56
61
  'role',
@@ -65,7 +70,9 @@ class CreateImpliedRole(command.ShowOne):
65
70
  )
66
71
  return parser
67
72
 
68
- def take_action(self, parsed_args):
73
+ def take_action(
74
+ self, parsed_args: argparse.Namespace
75
+ ) -> tuple[Sequence[str], Iterable[Any]]:
69
76
  identity_client = self.app.client_manager.identity
70
77
  (prior_role_id, implied_role_id) = _get_role_ids(
71
78
  identity_client, parsed_args
@@ -74,13 +81,16 @@ class CreateImpliedRole(command.ShowOne):
74
81
  prior_role_id, implied_role_id
75
82
  )
76
83
  response._info.pop('links', None)
77
- return zip(*sorted([(k, v['id']) for k, v in response._info.items()]))
84
+ col_headers, col_data = zip(
85
+ *sorted([(k, v['id']) for k, v in response._info.items()])
86
+ )
87
+ return col_headers, col_data
78
88
 
79
89
 
80
90
  class DeleteImpliedRole(command.Command):
81
91
  _description = _("Deletes an association between prior and implied roles")
82
92
 
83
- def get_parser(self, prog_name):
93
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
84
94
  parser = super().get_parser(prog_name)
85
95
  parser.add_argument(
86
96
  'role',
@@ -95,7 +105,7 @@ class DeleteImpliedRole(command.Command):
95
105
  )
96
106
  return parser
97
107
 
98
- def take_action(self, parsed_args):
108
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
99
109
  identity_client = self.app.client_manager.identity
100
110
  (prior_role_id, implied_role_id) = _get_role_ids(
101
111
  identity_client, parsed_args
@@ -112,12 +122,14 @@ class ListImpliedRole(command.Lister):
112
122
  'Implied Role Name',
113
123
  ]
114
124
 
115
- def get_parser(self, prog_name):
125
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
116
126
  parser = super().get_parser(prog_name)
117
127
  return parser
118
128
 
119
- def take_action(self, parsed_args):
120
- def _list_implied(response):
129
+ def take_action(
130
+ self, parsed_args: argparse.Namespace
131
+ ) -> tuple[Sequence[str], Iterable[tuple[Any, ...]]]:
132
+ def _list_implied(response: Any) -> Iterable[tuple[Any, ...]]:
121
133
  for rule in response:
122
134
  for implies in rule.implies:
123
135
  yield (
@@ -13,8 +13,12 @@
13
13
 
14
14
  """Limits action implementations."""
15
15
 
16
+ import argparse
17
+ from collections.abc import Iterable, Sequence
16
18
  import logging
19
+ from typing import Any
17
20
 
21
+ from openstack import utils as sdk_utils
18
22
  from osc_lib import exceptions
19
23
  from osc_lib import utils
20
24
 
@@ -25,10 +29,32 @@ from openstackclient.identity import common as common_utils
25
29
  LOG = logging.getLogger(__name__)
26
30
 
27
31
 
32
+ def _format_limit(limit: Any) -> tuple[tuple[str, ...], Any]:
33
+ columns = (
34
+ "description",
35
+ "id",
36
+ "project_id",
37
+ "region_id",
38
+ "resource_limit",
39
+ "resource_name",
40
+ "service_id",
41
+ )
42
+ column_headers = (
43
+ "description",
44
+ "id",
45
+ "project_id",
46
+ "region_id",
47
+ "resource_limit",
48
+ "resource_name",
49
+ "service_id",
50
+ )
51
+ return (column_headers, utils.get_item_properties(limit, columns))
52
+
53
+
28
54
  class CreateLimit(command.ShowOne):
29
55
  _description = _("Create a limit")
30
56
 
31
- def get_parser(self, prog_name):
57
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
32
58
  parser = super().get_parser(prog_name)
33
59
  parser.add_argument(
34
60
  '--description',
@@ -46,6 +72,7 @@ class CreateLimit(command.ShowOne):
46
72
  required=True,
47
73
  help=_('Project to associate the resource limit to'),
48
74
  )
75
+ common_utils.add_project_domain_option_to_parser(parser)
49
76
  parser.add_argument(
50
77
  '--service',
51
78
  metavar='<service>',
@@ -66,54 +93,44 @@ class CreateLimit(command.ShowOne):
66
93
  )
67
94
  return parser
68
95
 
69
- def take_action(self, parsed_args):
70
- identity_client = self.app.client_manager.identity
96
+ def take_action(
97
+ self, parsed_args: argparse.Namespace
98
+ ) -> tuple[Sequence[str], Iterable[Any]]:
99
+ identity_client = sdk_utils.ensure_service_version(
100
+ self.app.client_manager.sdk_connection.identity, '3'
101
+ )
71
102
 
72
- project = common_utils.find_project(
73
- identity_client, parsed_args.project
103
+ kwargs = {
104
+ "resource_name": parsed_args.resource_name,
105
+ "resource_limit": parsed_args.resource_limit,
106
+ }
107
+ if parsed_args.description:
108
+ kwargs["description"] = parsed_args.description
109
+
110
+ kwargs["project_id"] = common_utils.find_project_id_sdk(
111
+ identity_client,
112
+ parsed_args.project,
113
+ domain_name_or_id=parsed_args.project_domain,
74
114
  )
75
- service = common_utils.find_service(
115
+
116
+ kwargs["service_id"] = common_utils.find_service_sdk(
76
117
  identity_client, parsed_args.service
77
- )
78
- region = None
118
+ ).id
119
+
79
120
  if parsed_args.region:
80
- if 'None' not in parsed_args.region:
81
- # NOTE (vishakha): Due to bug #1799153 and for any another
82
- # related case where GET resource API does not support the
83
- # filter by name, osc_lib.utils.find_resource() method cannot
84
- # be used because that method try to fall back to list all the
85
- # resource if requested resource cannot be get via name. Which
86
- # ends up with NoUniqueMatch error.
87
- # So osc_lib.utils.find_resource() function cannot be used for
88
- # 'regions', using common_utils.get_resource() instead.
89
- region = common_utils.get_resource(
90
- identity_client.regions, parsed_args.region
91
- )
92
- else:
93
- self.log.warning(
94
- _(
95
- "Passing 'None' to indicate no region is deprecated. "
96
- "Instead, don't pass --region."
97
- )
98
- )
121
+ kwargs["region_id"] = identity_client.get_region(
122
+ parsed_args.region
123
+ ).id
99
124
 
100
- limit = identity_client.limits.create(
101
- project,
102
- service,
103
- parsed_args.resource_name,
104
- parsed_args.resource_limit,
105
- description=parsed_args.description,
106
- region=region,
107
- )
125
+ limit = identity_client.create_limit(**kwargs)
108
126
 
109
- limit._info.pop('links', None)
110
- return zip(*sorted(limit._info.items()))
127
+ return _format_limit(limit)
111
128
 
112
129
 
113
130
  class ListLimit(command.Lister):
114
131
  _description = _("List limits")
115
132
 
116
- def get_parser(self, prog_name):
133
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
117
134
  parser = super().get_parser(prog_name)
118
135
  parser.add_argument(
119
136
  '--service',
@@ -136,50 +153,45 @@ class ListLimit(command.Lister):
136
153
  metavar='<project>',
137
154
  help=_('List resource limits associated with project'),
138
155
  )
156
+ common_utils.add_project_domain_option_to_parser(parser)
157
+
139
158
  return parser
140
159
 
141
- def take_action(self, parsed_args):
142
- identity_client = self.app.client_manager.identity
160
+ def take_action(
161
+ self, parsed_args: argparse.Namespace
162
+ ) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
163
+ identity_client = sdk_utils.ensure_service_version(
164
+ self.app.client_manager.sdk_connection.identity, '3'
165
+ )
143
166
 
144
- service = None
167
+ kwargs = {}
145
168
  if parsed_args.service:
146
- service = common_utils.find_service(
169
+ kwargs["service_id"] = common_utils.find_service_sdk(
147
170
  identity_client, parsed_args.service
148
171
  )
149
- region = None
172
+
150
173
  if parsed_args.region:
151
- if 'None' not in parsed_args.region:
152
- # NOTE (vishakha): Due to bug #1799153 and for any another
153
- # related case where GET resource API does not support the
154
- # filter by name, osc_lib.utils.find_resource() method cannot
155
- # be used because that method try to fall back to list all the
156
- # resource if requested resource cannot be get via name. Which
157
- # ends up with NoUniqueMatch error.
158
- # So osc_lib.utils.find_resource() function cannot be used for
159
- # 'regions', using common_utils.get_resource() instead.
160
- region = common_utils.get_resource(
161
- identity_client.regions, parsed_args.region
162
- )
163
- else:
164
- self.log.warning(
165
- _(
166
- "Passing 'None' to indicate no region is deprecated. "
167
- "Instead, don't pass --region."
168
- )
169
- )
174
+ kwargs["region_id"] = identity_client.get_region(
175
+ parsed_args.region
176
+ ).id
170
177
 
171
- project = None
172
178
  if parsed_args.project:
173
- project = utils.find_resource(
174
- identity_client.projects, parsed_args.project
179
+ project_domain_id = None
180
+ if parsed_args.project_domain:
181
+ project_domain_id = common_utils.find_domain_id_sdk(
182
+ identity_client, parsed_args.project_domain
183
+ )
184
+
185
+ kwargs["project_id"] = common_utils._find_sdk_id(
186
+ identity_client.find_project,
187
+ name_or_id=parsed_args.project,
188
+ domain_id=project_domain_id,
175
189
  )
176
190
 
177
- limits = identity_client.limits.list(
178
- service=service,
179
- resource_name=parsed_args.resource_name,
180
- region=region,
181
- project=project,
182
- )
191
+ if parsed_args.resource_name:
192
+ kwargs["resource_name"] = parsed_args.resource_name
193
+
194
+ limits = identity_client.limits(**kwargs)
183
195
 
184
196
  columns = (
185
197
  'ID',
@@ -199,7 +211,7 @@ class ListLimit(command.Lister):
199
211
  class ShowLimit(command.ShowOne):
200
212
  _description = _("Display limit details")
201
213
 
202
- def get_parser(self, prog_name):
214
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
203
215
  parser = super().get_parser(prog_name)
204
216
  parser.add_argument(
205
217
  'limit_id',
@@ -208,17 +220,20 @@ class ShowLimit(command.ShowOne):
208
220
  )
209
221
  return parser
210
222
 
211
- def take_action(self, parsed_args):
212
- identity_client = self.app.client_manager.identity
213
- limit = identity_client.limits.get(parsed_args.limit_id)
214
- limit._info.pop('links', None)
215
- return zip(*sorted(limit._info.items()))
223
+ def take_action(
224
+ self, parsed_args: argparse.Namespace
225
+ ) -> tuple[Sequence[str], Iterable[Any]]:
226
+ identity_client = sdk_utils.ensure_service_version(
227
+ self.app.client_manager.sdk_connection.identity, '3'
228
+ )
229
+ limit = identity_client.get_limit(parsed_args.limit_id)
230
+ return _format_limit(limit)
216
231
 
217
232
 
218
233
  class SetLimit(command.ShowOne):
219
234
  _description = _("Update information about a limit")
220
235
 
221
- def get_parser(self, prog_name):
236
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
222
237
  parser = super().get_parser(prog_name)
223
238
  parser.add_argument(
224
239
  'limit_id',
@@ -239,40 +254,48 @@ class SetLimit(command.ShowOne):
239
254
  )
240
255
  return parser
241
256
 
242
- def take_action(self, parsed_args):
243
- identity_client = self.app.client_manager.identity
244
-
245
- limit = identity_client.limits.update(
246
- parsed_args.limit_id,
247
- description=parsed_args.description,
248
- resource_limit=parsed_args.resource_limit,
257
+ def take_action(
258
+ self, parsed_args: argparse.Namespace
259
+ ) -> tuple[Sequence[str], Iterable[Any]]:
260
+ identity_client = sdk_utils.ensure_service_version(
261
+ self.app.client_manager.sdk_connection.identity, '3'
249
262
  )
250
263
 
251
- limit._info.pop('links', None)
264
+ kwargs = {}
265
+ if parsed_args.description:
266
+ kwargs["description"] = parsed_args.description
267
+ if parsed_args.resource_limit:
268
+ kwargs["resource_limit"] = parsed_args.resource_limit
269
+ limit = identity_client.update_limit(parsed_args.limit_id, **kwargs)
252
270
 
253
- return zip(*sorted(limit._info.items()))
271
+ return _format_limit(limit)
254
272
 
255
273
 
256
274
  class DeleteLimit(command.Command):
257
275
  _description = _("Delete a limit")
258
276
 
259
- def get_parser(self, prog_name):
277
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
260
278
  parser = super().get_parser(prog_name)
261
279
  parser.add_argument(
262
280
  'limit_id',
263
281
  metavar='<limit-id>',
264
282
  nargs="+",
265
- help=_('Limit to delete (ID)'),
283
+ help=_(
284
+ 'Limit to delete (ID) '
285
+ '(repeat option to remove multiple limits)'
286
+ ),
266
287
  )
267
288
  return parser
268
289
 
269
- def take_action(self, parsed_args):
270
- identity_client = self.app.client_manager.identity
290
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
291
+ identity_client = sdk_utils.ensure_service_version(
292
+ self.app.client_manager.sdk_connection.identity, '3'
293
+ )
271
294
 
272
295
  errors = 0
273
296
  for limit_id in parsed_args.limit_id:
274
297
  try:
275
- identity_client.limits.delete(limit_id)
298
+ identity_client.delete_limit(limit_id)
276
299
  except Exception as e:
277
300
  errors += 1
278
301
  LOG.error(