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
@@ -18,15 +18,16 @@ import argparse
18
18
  import itertools
19
19
  import logging
20
20
  import sys
21
- import typing as ty
21
+ from collections.abc import Iterable, Sequence
22
+ from typing import Any
22
23
 
23
24
  from openstack import exceptions as sdk_exceptions
25
+ from openstack import utils as sdk_utils
24
26
  from osc_lib import exceptions
25
27
  from osc_lib import utils
26
28
 
27
29
  from openstackclient import command
28
30
  from openstackclient.i18n import _
29
- from openstackclient.network import common
30
31
 
31
32
  LOG = logging.getLogger(__name__)
32
33
 
@@ -61,13 +62,6 @@ IMPACT_VOLUME_TYPE_QUOTAS = [
61
62
  'volumes',
62
63
  ]
63
64
 
64
- NOVA_NETWORK_QUOTAS = {
65
- 'fixed_ips': 'fixed-ips',
66
- 'floating_ips': 'floating-ips',
67
- 'security_group_rules': 'secgroup-rules',
68
- 'security_groups': 'secgroups',
69
- }
70
-
71
65
  NETWORK_QUOTAS = {
72
66
  'floatingip': 'floating-ips',
73
67
  'security_group_rule': 'secgroup-rules',
@@ -93,9 +87,13 @@ NETWORK_KEYS = [
93
87
  ]
94
88
 
95
89
 
96
- def _xform_get_quota(data, value, keys):
97
- res = []
98
- res_info = {}
90
+ def _xform_get_quota(
91
+ data: Any,
92
+ value: str,
93
+ keys: Any,
94
+ ) -> list[dict[str, Any]]:
95
+ res: list[dict[str, Any]] = []
96
+ res_info: dict[str, Any] = {}
99
97
  for key in keys:
100
98
  res_info[key] = getattr(data, key, '')
101
99
 
@@ -104,17 +102,21 @@ def _xform_get_quota(data, value, keys):
104
102
  return res
105
103
 
106
104
 
107
- def get_project(app, project):
105
+ def get_project(app: Any, project: str | None) -> dict[str, str | None]:
108
106
  if project is not None:
109
- identity_client = app.client_manager.sdk_connection.identity
110
- project = identity_client.find_project(project, ignore_missing=False)
111
- project_id = project.id
112
- project_name = project.name
107
+ identity_client = sdk_utils.ensure_service_version(
108
+ app.client_manager.sdk_connection.identity, '3'
109
+ )
110
+ found_project = identity_client.find_project(
111
+ project, ignore_missing=False
112
+ )
113
+ project_id = found_project.id
114
+ project_name = found_project.name
113
115
  elif app.client_manager.auth_ref:
114
116
  # Get the project from the current auth
115
- project = app.client_manager.auth_ref
116
- project_id = project.project_id
117
- project_name = project.project_name
117
+ auth_ref = app.client_manager.auth_ref
118
+ project_id = auth_ref.project_id
119
+ project_name = auth_ref.project_name
118
120
  else:
119
121
  project_id = None
120
122
  project_name = None
@@ -126,12 +128,12 @@ def get_project(app, project):
126
128
 
127
129
 
128
130
  def get_compute_quotas(
129
- app,
130
- project_id,
131
+ app: Any,
132
+ project_id: str | None,
131
133
  *,
132
- detail=False,
133
- default=False,
134
- ):
134
+ detail: bool = False,
135
+ default: bool = False,
136
+ ) -> dict[str, Any]:
135
137
  try:
136
138
  client = app.client_manager.compute
137
139
  if default:
@@ -140,7 +142,7 @@ def get_compute_quotas(
140
142
  quota = client.get_quota_set(project_id, usage=detail)
141
143
  except sdk_exceptions.EndpointNotFound:
142
144
  return {}
143
- data = quota.to_dict()
145
+ data: dict[str, Any] = quota.to_dict()
144
146
  if not detail:
145
147
  del data['usage']
146
148
  del data['reservation']
@@ -148,12 +150,12 @@ def get_compute_quotas(
148
150
 
149
151
 
150
152
  def get_volume_quotas(
151
- app,
152
- project_id,
153
+ app: Any,
154
+ project_id: str | None,
153
155
  *,
154
- detail=False,
155
- default=False,
156
- ):
156
+ detail: bool = False,
157
+ default: bool = False,
158
+ ) -> dict[str, Any]:
157
159
  try:
158
160
  client = app.client_manager.sdk_connection.volume
159
161
  if default:
@@ -162,7 +164,7 @@ def get_volume_quotas(
162
164
  quota = client.get_quota_set(project_id, usage=detail)
163
165
  except sdk_exceptions.EndpointNotFound:
164
166
  return {}
165
- data = quota.to_dict()
167
+ data: dict[str, Any] = quota.to_dict()
166
168
  if not detail:
167
169
  del data['usage']
168
170
  del data['reservation']
@@ -170,17 +172,19 @@ def get_volume_quotas(
170
172
 
171
173
 
172
174
  def get_network_quotas(
173
- app,
174
- project_id,
175
+ app: Any,
176
+ project_id: str | None,
175
177
  *,
176
- detail=False,
177
- default=False,
178
- ):
179
- def _network_quota_to_dict(network_quota, detail=False):
180
- dict_quota = network_quota.to_dict(computed=False)
178
+ detail: bool = False,
179
+ default: bool = False,
180
+ ) -> dict[str, Any]:
181
+ def _network_quota_to_dict(
182
+ network_quota: Any, detail: bool = False
183
+ ) -> dict[str, Any]:
184
+ data: dict[str, Any] = network_quota.to_dict(computed=False)
181
185
 
182
186
  if not detail:
183
- return dict_quota
187
+ return data
184
188
 
185
189
  # Neutron returns quota details in dict which is in format like:
186
190
  # {'resource_name': {'in_use': X, 'limit': Y, 'reserved': Z},
@@ -200,8 +204,8 @@ def get_network_quotas(
200
204
  #
201
205
  # so we need to make conversion to have data in same format from
202
206
  # all of the services
203
- result: dict[str, ty.Any] = {"usage": {}, "reservation": {}}
204
- for key, values in dict_quota.items():
207
+ result: dict[str, Any] = {"usage": {}, "reservation": {}}
208
+ for key, values in data.items():
205
209
  if values is None:
206
210
  continue
207
211
  if isinstance(values, dict):
@@ -232,7 +236,7 @@ class ListQuota(command.Lister):
232
236
  inspected with 'openstack quota show --default'.
233
237
  """
234
238
 
235
- def get_parser(self, prog_name):
239
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
236
240
  parser = super().get_parser(prog_name)
237
241
  option = parser.add_mutually_exclusive_group(required=True)
238
242
  option.add_argument(
@@ -255,7 +259,11 @@ class ListQuota(command.Lister):
255
259
  )
256
260
  return parser
257
261
 
258
- def _list_quota_compute(self, parsed_args, project_ids):
262
+ def _list_quota_compute(
263
+ self,
264
+ parsed_args: argparse.Namespace,
265
+ project_ids: list[str],
266
+ ) -> tuple[tuple[str, ...], Any]:
259
267
  compute_client = self.app.client_manager.compute
260
268
  result = []
261
269
 
@@ -272,7 +280,10 @@ class ListQuota(command.Lister):
272
280
  sdk_exceptions.NotFoundException,
273
281
  ) as exc:
274
282
  # Project not found, move on to next one
275
- LOG.warning(f"Project {project_id} not found: {exc}")
283
+ LOG.warning(
284
+ 'Project %(project_id)s not found: %(exc)s',
285
+ {'project_id': project_id, 'exc': exc},
286
+ )
276
287
  continue
277
288
 
278
289
  project_result = _xform_get_quota(
@@ -322,7 +333,11 @@ class ListQuota(command.Lister):
322
333
  (utils.get_dict_properties(s, columns) for s in result),
323
334
  )
324
335
 
325
- def _list_quota_volume(self, parsed_args, project_ids):
336
+ def _list_quota_volume(
337
+ self,
338
+ parsed_args: argparse.Namespace,
339
+ project_ids: list[str],
340
+ ) -> tuple[tuple[str, ...], Any]:
326
341
  volume_client = self.app.client_manager.sdk_connection.volume
327
342
  result = []
328
343
 
@@ -334,7 +349,10 @@ class ListQuota(command.Lister):
334
349
  sdk_exceptions.NotFoundException,
335
350
  ) as exc:
336
351
  # Project not found, move on to next one
337
- LOG.warning(f"Project {project_id} not found: {exc}")
352
+ LOG.warning(
353
+ 'Project %(project_id)s not found: %(exc)s',
354
+ {'project_id': project_id, 'exc': exc},
355
+ )
338
356
  continue
339
357
 
340
358
  project_result = _xform_get_quota(
@@ -377,7 +395,11 @@ class ListQuota(command.Lister):
377
395
  (utils.get_dict_properties(s, columns) for s in result),
378
396
  )
379
397
 
380
- def _list_quota_network(self, parsed_args, project_ids):
398
+ def _list_quota_network(
399
+ self,
400
+ parsed_args: argparse.Namespace,
401
+ project_ids: list[str],
402
+ ) -> tuple[tuple[str, ...], Any]:
381
403
  network_client = self.app.client_manager.network
382
404
  result = []
383
405
 
@@ -389,7 +411,10 @@ class ListQuota(command.Lister):
389
411
  sdk_exceptions.ForbiddenException,
390
412
  ) as exc:
391
413
  # Project not found, move on to next one
392
- LOG.warning(f"Project {project_id} not found: {exc}")
414
+ LOG.warning(
415
+ 'Project %(project_id)s not found: %(exc)s',
416
+ {'project_id': project_id, 'exc': exc},
417
+ )
393
418
  continue
394
419
 
395
420
  project_result = _xform_get_quota(
@@ -438,11 +463,14 @@ class ListQuota(command.Lister):
438
463
  (utils.get_dict_properties(s, columns) for s in result),
439
464
  )
440
465
 
441
- def take_action(self, parsed_args):
442
- project_ids = [
443
- p.id
444
- for p in self.app.client_manager.sdk_connection.identity.projects()
445
- ]
466
+ def take_action(
467
+ self, parsed_args: argparse.Namespace
468
+ ) -> tuple[Sequence[str], Iterable[tuple[Any, ...]]]:
469
+ identity_client = sdk_utils.ensure_service_version(
470
+ self.app.client_manager.sdk_connection.identity, '3'
471
+ )
472
+
473
+ project_ids = [p.id for p in identity_client.projects()]
446
474
  if parsed_args.compute:
447
475
  return self._list_quota_compute(parsed_args, project_ids)
448
476
  elif parsed_args.volume:
@@ -454,44 +482,23 @@ class ListQuota(command.Lister):
454
482
  return ((), ())
455
483
 
456
484
 
457
- class SetQuota(common.NetDetectionMixin, command.Command):
485
+ class SetQuota(command.Command):
458
486
  _description = _("Set quotas for project or class")
459
487
 
460
- def _build_options_list(self):
488
+ def _build_options_list(self) -> list[tuple[str, str, str]]:
461
489
  help_fmt = _('New value for the %s quota')
462
- # Compute and volume quota options are always the same
490
+ # Compute volume and network quota options are always the same
463
491
  rets = [
464
492
  (k, v, help_fmt % v)
465
493
  for k, v in itertools.chain(
466
494
  COMPUTE_QUOTAS.items(),
467
495
  VOLUME_QUOTAS.items(),
496
+ NETWORK_QUOTAS.items(),
468
497
  )
469
498
  ]
470
- # For docs build, we want to produce helps for both neutron and
471
- # nova-network options. They overlap, so we have to figure out which
472
- # need to be tagged as specific to one network type or the other.
473
- if self.is_docs_build:
474
- # NOTE(efried): This takes advantage of the fact that we know the
475
- # nova-net options are a subset of the neutron options. If that
476
- # ever changes, this algorithm will need to be adjusted accordingly
477
- inv_compute = set(NOVA_NETWORK_QUOTAS.values())
478
- for k, v in NETWORK_QUOTAS.items():
479
- _help = help_fmt % v
480
- if v not in inv_compute:
481
- # This one is unique to neutron
482
- _help = self.enhance_help_neutron(_help)
483
- rets.append((k, v, _help))
484
- elif self.is_neutron:
485
- rets.extend(
486
- [(k, v, help_fmt % v) for k, v in NETWORK_QUOTAS.items()]
487
- )
488
- elif self.is_nova_network:
489
- rets.extend(
490
- [(k, v, help_fmt % v) for k, v in NOVA_NETWORK_QUOTAS.items()]
491
- )
492
499
  return rets
493
500
 
494
- def get_parser(self, prog_name):
501
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
495
502
  parser = super().get_parser(prog_name)
496
503
  parser.add_argument(
497
504
  'project',
@@ -566,7 +573,7 @@ class SetQuota(common.NetDetectionMixin, command.Command):
566
573
  )
567
574
  return parser
568
575
 
569
- def take_action(self, parsed_args):
576
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
570
577
  if parsed_args.quota_class:
571
578
  msg = _(
572
579
  "The '--class' option has been deprecated. Quota classes were "
@@ -586,6 +593,9 @@ class SetQuota(common.NetDetectionMixin, command.Command):
586
593
  compute_kwargs = {}
587
594
  volume_kwargs = {}
588
595
  network_kwargs = {}
596
+ compute_client = None
597
+ volume_client = None
598
+ network_client = None
589
599
 
590
600
  if self.app.client_manager.is_compute_endpoint_enabled():
591
601
  compute_client = self.app.client_manager.compute
@@ -618,11 +628,6 @@ class SetQuota(common.NetDetectionMixin, command.Command):
618
628
  value = getattr(parsed_args, k, None)
619
629
  if value is not None:
620
630
  network_kwargs[k] = value
621
- elif self.app.client_manager.is_compute_endpoint_enabled():
622
- for k, v in NOVA_NETWORK_QUOTAS.items():
623
- value = getattr(parsed_args, k, None)
624
- if value is not None:
625
- compute_kwargs[k] = value
626
631
 
627
632
  if network_kwargs:
628
633
  if parsed_args.force is True:
@@ -634,12 +639,12 @@ class SetQuota(common.NetDetectionMixin, command.Command):
634
639
  network_kwargs['check_limit'] = True
635
640
 
636
641
  if parsed_args.quota_class or parsed_args.default:
637
- if compute_kwargs:
642
+ if compute_kwargs and compute_client:
638
643
  compute_client.update_quota_class_set(
639
644
  parsed_args.project or 'default',
640
645
  **compute_kwargs,
641
646
  )
642
- if volume_kwargs:
647
+ if volume_kwargs and volume_client:
643
648
  volume_client.update_quota_class_set(
644
649
  parsed_args.project or 'default',
645
650
  **volume_kwargs,
@@ -655,11 +660,11 @@ class SetQuota(common.NetDetectionMixin, command.Command):
655
660
  project_info = get_project(self.app, parsed_args.project)
656
661
  project = project_info['id']
657
662
 
658
- if compute_kwargs:
663
+ if compute_kwargs and compute_client:
659
664
  compute_client.update_quota_set(project, **compute_kwargs)
660
- if volume_kwargs:
665
+ if volume_kwargs and volume_client:
661
666
  volume_client.update_quota_set(project, **volume_kwargs)
662
- if network_kwargs:
667
+ if network_kwargs and network_client:
663
668
  network_client.update_quota(project, **network_kwargs)
664
669
 
665
670
 
@@ -671,7 +676,7 @@ Specify ``--os-compute-api-version 2.50`` or higher to see ``server-groups``
671
676
  and ``server-group-members`` output for a given quota class."""
672
677
  )
673
678
 
674
- def get_parser(self, prog_name):
679
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
675
680
  parser = super().get_parser(prog_name)
676
681
  parser.add_argument(
677
682
  'project',
@@ -733,7 +738,9 @@ and ``server-group-members`` output for a given quota class."""
733
738
 
734
739
  return parser
735
740
 
736
- def take_action(self, parsed_args):
741
+ def take_action(
742
+ self, parsed_args: argparse.Namespace
743
+ ) -> tuple[Sequence[str], Iterable[tuple[Any, ...]]]:
737
744
  project_info = get_project(self.app, parsed_args.project)
738
745
  project = project_info['id']
739
746
 
@@ -797,29 +804,31 @@ and ``server-group-members`` output for a given quota class."""
797
804
  info.update(volume_quota_info)
798
805
  info.update(network_quota_info)
799
806
 
800
- # Map the internal quota names to the external ones
801
- # COMPUTE_QUOTAS and NETWORK_QUOTAS share floating-ips,
802
- # secgroup-rules and secgroups as dict value, so when
803
- # neutron is enabled, quotas of these three resources
804
- # in nova will be replaced by neutron's.
805
- for k, v in itertools.chain(
806
- COMPUTE_QUOTAS.items(),
807
- NOVA_NETWORK_QUOTAS.items(),
808
- VOLUME_QUOTAS.items(),
809
- NETWORK_QUOTAS.items(),
810
- ):
811
- if not k == v and info.get(k) is not None:
812
- info[v] = info[k]
813
- info.pop(k)
807
+ def _normalize_names(section: dict[str, Any]) -> None:
808
+ # Map the internal quota names to the external ones
809
+ # COMPUTE_QUOTAS and NETWORK_QUOTAS share floating-ips,
810
+ # secgroup-rules and secgroups as dict value, so when
811
+ # neutron is enabled, quotas of these three resources
812
+ # in nova will be replaced by neutron's.
813
+ for k, v in itertools.chain(
814
+ COMPUTE_QUOTAS.items(),
815
+ VOLUME_QUOTAS.items(),
816
+ NETWORK_QUOTAS.items(),
817
+ ):
818
+ if not k == v and section.get(k) is not None:
819
+ section[v] = section.pop(k)
820
+
821
+ _normalize_names(info)
822
+ if parsed_args.usage:
823
+ _normalize_names(info["reservation"])
824
+ _normalize_names(info["usage"])
814
825
 
815
826
  # Remove the 'id' field since it's not very useful
816
- if 'id' in info:
817
- del info['id']
827
+ info.pop('id', None)
818
828
 
819
829
  # Remove the sdk-derived fields
820
830
  for field in ('location', 'name', 'force'):
821
- if field in info:
822
- del info[field]
831
+ info.pop(field, None)
823
832
 
824
833
  if not parsed_args.usage:
825
834
  result = [{'resource': k, 'limit': v} for k, v in info.items()]
@@ -865,7 +874,7 @@ class DeleteQuota(command.Command):
865
874
  "Delete configured quota for a project and revert to defaults."
866
875
  )
867
876
 
868
- def get_parser(self, prog_name):
877
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
869
878
  parser = super().get_parser(prog_name)
870
879
  parser.add_argument(
871
880
  'project',
@@ -910,8 +919,11 @@ class DeleteQuota(command.Command):
910
919
  )
911
920
  return parser
912
921
 
913
- def take_action(self, parsed_args):
914
- identity_client = self.app.client_manager.sdk_connection.identity
922
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
923
+ identity_client = sdk_utils.ensure_service_version(
924
+ self.app.client_manager.sdk_connection.identity, '3'
925
+ )
926
+
915
927
  project = identity_client.find_project(
916
928
  parsed_args.project, ignore_missing=False
917
929
  )
@@ -14,6 +14,10 @@
14
14
 
15
15
  """Versions Action Implementation"""
16
16
 
17
+ import argparse
18
+ from collections.abc import Iterable, Sequence
19
+ from typing import Any
20
+
17
21
  from openstackclient import command
18
22
  from openstackclient.i18n import _
19
23
 
@@ -21,7 +25,7 @@ from openstackclient.i18n import _
21
25
  class ShowVersions(command.Lister):
22
26
  _description = _("Show available versions of services")
23
27
 
24
- def get_parser(self, prog_name):
28
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
25
29
  parser = super().get_parser(prog_name)
26
30
  interface_group = parser.add_mutually_exclusive_group()
27
31
  interface_group.add_argument(
@@ -67,7 +71,9 @@ class ShowVersions(command.Lister):
67
71
  )
68
72
  return parser
69
73
 
70
- def take_action(self, parsed_args):
74
+ def take_action(
75
+ self, parsed_args: argparse.Namespace
76
+ ) -> tuple[Sequence[str], Iterable[tuple[Any, ...]]]:
71
77
  interface = parsed_args.interface
72
78
  if parsed_args.is_all_interfaces:
73
79
  interface = None
@@ -12,7 +12,9 @@
12
12
  # License for the specific language governing permissions and limitations
13
13
  # under the License.
14
14
 
15
+ import argparse
15
16
  import logging
17
+ from typing import Any
16
18
 
17
19
  from osc_lib import utils
18
20
 
@@ -27,7 +29,7 @@ API_NAME = 'compute'
27
29
  API_VERSIONS = ('2', '2.1')
28
30
 
29
31
 
30
- def make_client(instance):
32
+ def make_client(instance: Any) -> Any:
31
33
  """Returns a compute service client."""
32
34
  LOG.debug(
33
35
  'Compute client initialized using OpenStack SDK: %s',
@@ -36,7 +38,9 @@ def make_client(instance):
36
38
  return instance.sdk_connection.compute
37
39
 
38
40
 
39
- def build_option_parser(parser):
41
+ def build_option_parser(
42
+ parser: argparse.ArgumentParser,
43
+ ) -> argparse.ArgumentParser:
40
44
  """Hook to add global options"""
41
45
  parser.add_argument(
42
46
  '--os-compute-api-version',
@@ -48,6 +52,6 @@ def build_option_parser(parser):
48
52
  return parser
49
53
 
50
54
 
51
- def check_api_version(check_version):
55
+ def check_api_version(check_version: str) -> bool:
52
56
  # SDK supports auto-negotiation for us: always return True
53
57
  return True
@@ -11,11 +11,13 @@
11
11
  # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
12
  # License for the specific language governing permissions and limitations
13
13
  # under the License.
14
- #
15
14
 
16
15
  """Agent action implementations"""
17
16
 
17
+ import argparse
18
+ from collections.abc import Iterable, Sequence
18
19
  import logging
20
+ from typing import Any
19
21
 
20
22
  from openstack import exceptions as sdk_exceptions
21
23
  from osc_lib import exceptions
@@ -36,7 +38,7 @@ class CreateAgent(command.ShowOne):
36
38
  23.0.0 (Wallaby) release.
37
39
  """
38
40
 
39
- def get_parser(self, prog_name):
41
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
40
42
  parser = super().get_parser(prog_name)
41
43
  parser.add_argument("os", metavar="<os>", help=_("Type of OS"))
42
44
  parser.add_argument(
@@ -55,7 +57,9 @@ class CreateAgent(command.ShowOne):
55
57
  )
56
58
  return parser
57
59
 
58
- def take_action(self, parsed_args):
60
+ def take_action(
61
+ self, parsed_args: argparse.Namespace
62
+ ) -> tuple[Sequence[str], Iterable[Any]]:
59
63
  compute_client = self.app.client_manager.compute
60
64
 
61
65
  # doing this since openstacksdk has decided not to support this
@@ -76,7 +80,8 @@ class CreateAgent(command.ShowOne):
76
80
  sdk_exceptions.raise_from_response(response)
77
81
  agent = response.json().get('agent')
78
82
 
79
- return zip(*sorted(agent.items()))
83
+ col_headers, col_data = zip(*sorted(agent.items()))
84
+ return col_headers, col_data
80
85
 
81
86
 
82
87
  class DeleteAgent(command.Command):
@@ -87,14 +92,14 @@ class DeleteAgent(command.Command):
87
92
  23.0.0 (Wallaby) release.
88
93
  """
89
94
 
90
- def get_parser(self, prog_name):
95
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
91
96
  parser = super().get_parser(prog_name)
92
97
  parser.add_argument(
93
98
  "id", metavar="<id>", nargs='+', help=_("ID of agent(s) to delete")
94
99
  )
95
100
  return parser
96
101
 
97
- def take_action(self, parsed_args):
102
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
98
103
  compute_client = self.app.client_manager.compute
99
104
  result = 0
100
105
  for id in parsed_args.id:
@@ -129,7 +134,7 @@ class ListAgent(command.Lister):
129
134
  23.0.0 (Wallaby) release.
130
135
  """
131
136
 
132
- def get_parser(self, prog_name):
137
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
133
138
  parser = super().get_parser(prog_name)
134
139
  parser.add_argument(
135
140
  "--hypervisor",
@@ -138,7 +143,9 @@ class ListAgent(command.Lister):
138
143
  )
139
144
  return parser
140
145
 
141
- def take_action(self, parsed_args):
146
+ def take_action(
147
+ self, parsed_args: argparse.Namespace
148
+ ) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
142
149
  compute_client = self.app.client_manager.compute
143
150
  columns = (
144
151
  "Agent ID",
@@ -171,7 +178,7 @@ class SetAgent(command.Command):
171
178
  23.0.0 (Wallaby) release.
172
179
  """
173
180
 
174
- def get_parser(self, prog_name):
181
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
175
182
  parser = super().get_parser(prog_name)
176
183
  parser.add_argument(
177
184
  "id",
@@ -193,7 +200,7 @@ class SetAgent(command.Command):
193
200
  )
194
201
  return parser
195
202
 
196
- def take_action(self, parsed_args):
203
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
197
204
  compute_client = self.app.client_manager.compute
198
205
 
199
206
  response = compute_client.get('/os-agents', microversion='2.1')