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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (352) hide show
  1. openstackclient/__init__.py +2 -6
  2. openstackclient/api/api.py +41 -23
  3. openstackclient/api/compute_v2.py +44 -25
  4. openstackclient/api/object_store_v1.py +75 -97
  5. openstackclient/api/volume_v2.py +2 -1
  6. openstackclient/api/volume_v3.py +2 -1
  7. openstackclient/common/availability_zone.py +59 -43
  8. openstackclient/common/clientmanager.py +56 -29
  9. openstackclient/common/configuration.py +10 -3
  10. openstackclient/common/envvars.py +2 -2
  11. openstackclient/common/extension.py +14 -5
  12. openstackclient/common/limits.py +10 -5
  13. openstackclient/common/module.py +36 -34
  14. openstackclient/common/pagination.py +50 -6
  15. openstackclient/common/progressbar.py +7 -6
  16. openstackclient/common/project_cleanup.py +11 -6
  17. openstackclient/common/quota.py +105 -103
  18. openstackclient/common/versions.py +8 -2
  19. openstackclient/compute/client.py +7 -3
  20. openstackclient/compute/v2/agent.py +17 -10
  21. openstackclient/compute/v2/aggregate.py +36 -22
  22. openstackclient/compute/v2/console.py +14 -8
  23. openstackclient/compute/v2/console_connection.py +11 -3
  24. openstackclient/compute/v2/flavor.py +42 -22
  25. openstackclient/compute/v2/host.py +14 -6
  26. openstackclient/compute/v2/hypervisor.py +16 -5
  27. openstackclient/compute/v2/hypervisor_stats.py +10 -2
  28. openstackclient/compute/v2/keypair.py +35 -16
  29. openstackclient/compute/v2/server.py +268 -179
  30. openstackclient/compute/v2/server_backup.py +10 -4
  31. openstackclient/compute/v2/server_event.py +28 -12
  32. openstackclient/compute/v2/server_group.py +23 -11
  33. openstackclient/compute/v2/server_image.py +19 -10
  34. openstackclient/compute/v2/server_migration.py +27 -10
  35. openstackclient/compute/v2/server_share.py +274 -0
  36. openstackclient/compute/v2/server_volume.py +13 -5
  37. openstackclient/compute/v2/service.py +17 -8
  38. openstackclient/compute/v2/usage.py +28 -23
  39. openstackclient/identity/client.py +8 -3
  40. openstackclient/identity/common.py +82 -47
  41. openstackclient/identity/v2_0/catalog.py +14 -7
  42. openstackclient/identity/v2_0/ec2creds.py +21 -10
  43. openstackclient/identity/v2_0/endpoint.py +23 -11
  44. openstackclient/identity/v2_0/project.py +25 -14
  45. openstackclient/identity/v2_0/role.py +28 -14
  46. openstackclient/identity/v2_0/role_assignment.py +9 -3
  47. openstackclient/identity/v2_0/service.py +23 -11
  48. openstackclient/identity/v2_0/token.py +12 -5
  49. openstackclient/identity/v2_0/user.py +26 -15
  50. openstackclient/identity/v3/access_rule.py +32 -12
  51. openstackclient/identity/v3/application_credential.py +66 -24
  52. openstackclient/identity/v3/catalog.py +14 -7
  53. openstackclient/identity/v3/consumer.py +22 -11
  54. openstackclient/identity/v3/credential.py +39 -17
  55. openstackclient/identity/v3/domain.py +40 -19
  56. openstackclient/identity/v3/ec2creds.py +25 -12
  57. openstackclient/identity/v3/endpoint.py +98 -64
  58. openstackclient/identity/v3/endpoint_group.py +28 -17
  59. openstackclient/identity/v3/federation_protocol.py +44 -20
  60. openstackclient/identity/v3/group.py +64 -40
  61. openstackclient/identity/v3/identity_provider.py +95 -57
  62. openstackclient/identity/v3/implied_role.py +21 -9
  63. openstackclient/identity/v3/limit.py +42 -17
  64. openstackclient/identity/v3/mapping.py +58 -28
  65. openstackclient/identity/v3/policy.py +23 -12
  66. openstackclient/identity/v3/project.py +59 -26
  67. openstackclient/identity/v3/region.py +39 -17
  68. openstackclient/identity/v3/registered_limit.py +41 -16
  69. openstackclient/identity/v3/role.py +62 -31
  70. openstackclient/identity/v3/role_assignment.py +25 -7
  71. openstackclient/identity/v3/service.py +39 -17
  72. openstackclient/identity/v3/service_provider.py +40 -16
  73. openstackclient/identity/v3/tag.py +23 -6
  74. openstackclient/identity/v3/token.py +30 -14
  75. openstackclient/identity/v3/trust.py +39 -18
  76. openstackclient/identity/v3/unscoped_saml.py +10 -2
  77. openstackclient/identity/v3/user.py +86 -36
  78. openstackclient/image/client.py +7 -3
  79. openstackclient/image/v1/image.py +33 -26
  80. openstackclient/image/v2/cache.py +16 -11
  81. openstackclient/image/v2/image.py +88 -56
  82. openstackclient/image/v2/info.py +7 -1
  83. openstackclient/image/v2/metadef_namespaces.py +117 -20
  84. openstackclient/image/v2/metadef_objects.py +32 -19
  85. openstackclient/image/v2/metadef_properties.py +30 -16
  86. openstackclient/image/v2/metadef_resource_type_association.py +14 -7
  87. openstackclient/image/v2/metadef_resource_types.py +7 -1
  88. openstackclient/image/v2/task.py +25 -27
  89. openstackclient/locale/tr_TR/LC_MESSAGES/openstackclient.po +7 -192
  90. openstackclient/network/client.py +7 -2
  91. openstackclient/network/common.py +16 -241
  92. openstackclient/network/utils.py +27 -54
  93. openstackclient/network/v2/address_group.py +39 -16
  94. openstackclient/network/v2/address_scope.py +36 -20
  95. openstackclient/network/v2/bgpvpn/bgpvpn.py +477 -0
  96. openstackclient/network/v2/bgpvpn/constants.py +30 -0
  97. openstackclient/network/v2/bgpvpn/network_association.py +226 -0
  98. openstackclient/network/v2/bgpvpn/port_association.py +504 -0
  99. openstackclient/network/v2/bgpvpn/router_association.py +301 -0
  100. openstackclient/network/v2/default_security_group_rule.py +31 -14
  101. openstackclient/network/v2/floating_ip.py +121 -162
  102. openstackclient/network/v2/floating_ip_port_forwarding.py +41 -19
  103. openstackclient/network/v2/fwaas/__init__.py +0 -0
  104. openstackclient/network/v2/fwaas/group.py +499 -0
  105. openstackclient/network/v2/fwaas/policy.py +518 -0
  106. openstackclient/network/v2/fwaas/rule.py +610 -0
  107. openstackclient/network/v2/ip_availability.py +25 -8
  108. openstackclient/network/v2/l3_conntrack_helper.py +35 -13
  109. openstackclient/network/v2/local_ip.py +27 -13
  110. openstackclient/network/v2/local_ip_association.py +17 -7
  111. openstackclient/network/v2/ndp_proxy.py +23 -11
  112. openstackclient/network/v2/network.py +213 -213
  113. openstackclient/network/v2/network_agent.py +77 -34
  114. openstackclient/network/v2/network_auto_allocated_topology.py +27 -15
  115. openstackclient/network/v2/network_flavor.py +45 -21
  116. openstackclient/network/v2/network_flavor_profile.py +42 -17
  117. openstackclient/network/v2/network_meter.py +39 -15
  118. openstackclient/network/v2/network_meter_rule.py +40 -12
  119. openstackclient/network/v2/network_qos_policy.py +39 -21
  120. openstackclient/network/v2/network_qos_rule.py +48 -18
  121. openstackclient/network/v2/network_qos_rule_type.py +28 -9
  122. openstackclient/network/v2/network_rbac.py +34 -16
  123. openstackclient/network/v2/network_segment.py +32 -11
  124. openstackclient/network/v2/network_segment_range.py +70 -31
  125. openstackclient/network/v2/network_service_provider.py +7 -1
  126. openstackclient/network/v2/network_trunk.py +41 -22
  127. openstackclient/network/v2/port.py +141 -40
  128. openstackclient/network/v2/router.py +101 -67
  129. openstackclient/network/v2/security_group.py +97 -198
  130. openstackclient/network/v2/security_group_rule.py +115 -282
  131. openstackclient/network/v2/subnet.py +63 -34
  132. openstackclient/network/v2/subnet_pool.py +42 -24
  133. openstackclient/network/v2/taas/tap_flow.py +35 -14
  134. openstackclient/network/v2/taas/tap_mirror.py +28 -14
  135. openstackclient/network/v2/taas/tap_service.py +26 -12
  136. openstackclient/object/client.py +7 -2
  137. openstackclient/object/v1/account.py +13 -6
  138. openstackclient/object/v1/container.py +28 -16
  139. openstackclient/object/v1/object.py +28 -16
  140. openstackclient/py.typed +0 -0
  141. openstackclient/shell.py +46 -10
  142. openstackclient/tests/functional/base.py +55 -20
  143. openstackclient/tests/functional/common/test_extension.py +4 -0
  144. openstackclient/tests/functional/common/test_quota.py +3 -1
  145. openstackclient/tests/functional/compute/v2/common.py +14 -13
  146. openstackclient/tests/functional/compute/v2/test_flavor.py +3 -1
  147. openstackclient/tests/functional/compute/v2/test_server.py +3 -0
  148. openstackclient/tests/functional/identity/v2/common.py +10 -6
  149. openstackclient/tests/functional/identity/v2/test_role.py +4 -4
  150. openstackclient/tests/functional/identity/v3/common.py +59 -19
  151. openstackclient/tests/functional/identity/v3/test_application_credential.py +1 -1
  152. openstackclient/tests/functional/identity/v3/test_group.py +20 -20
  153. openstackclient/tests/functional/identity/v3/test_idp.py +3 -1
  154. openstackclient/tests/functional/identity/v3/test_mapping.py +81 -0
  155. openstackclient/tests/functional/identity/v3/test_project.py +10 -10
  156. openstackclient/tests/functional/identity/v3/test_role.py +18 -18
  157. openstackclient/tests/functional/identity/v3/test_role_assignment.py +12 -12
  158. openstackclient/tests/functional/identity/v3/test_user.py +8 -8
  159. openstackclient/tests/functional/image/base.py +1 -6
  160. openstackclient/tests/functional/network/v2/common.py +5 -2
  161. openstackclient/tests/functional/network/v2/test_floating_ip.py +10 -4
  162. openstackclient/tests/functional/network/v2/test_ip_availability.py +4 -0
  163. openstackclient/tests/functional/network/v2/test_network_meter_rule.py +3 -2
  164. openstackclient/tests/functional/network/v2/test_network_segment.py +5 -0
  165. openstackclient/tests/functional/network/v2/test_subnet.py +13 -9
  166. openstackclient/tests/functional/object/v1/common.py +4 -0
  167. openstackclient/tests/functional/volume/v2/common.py +4 -0
  168. openstackclient/tests/functional/volume/v2/test_volume_snapshot.py +27 -11
  169. openstackclient/tests/functional/volume/v2/test_volume_type.py +2 -2
  170. openstackclient/tests/functional/volume/v3/common.py +4 -0
  171. openstackclient/tests/functional/volume/v3/test_volume_group.py +163 -0
  172. openstackclient/tests/functional/volume/v3/test_volume_snapshot.py +11 -7
  173. openstackclient/tests/functional/volume/v3/test_volume_type.py +2 -2
  174. openstackclient/tests/unit/common/test_availability_zone.py +35 -49
  175. openstackclient/tests/unit/common/test_extension.py +2 -2
  176. openstackclient/tests/unit/common/test_limits.py +1 -1
  177. openstackclient/tests/unit/common/test_module.py +82 -44
  178. openstackclient/tests/unit/common/test_project_cleanup.py +3 -1
  179. openstackclient/tests/unit/common/test_quota.py +15 -26
  180. openstackclient/tests/unit/compute/v2/fakes.py +26 -57
  181. openstackclient/tests/unit/compute/v2/test_agent.py +4 -4
  182. openstackclient/tests/unit/compute/v2/test_aggregate.py +1 -1
  183. openstackclient/tests/unit/compute/v2/test_console.py +2 -2
  184. openstackclient/tests/unit/compute/v2/test_console_connection.py +1 -1
  185. openstackclient/tests/unit/compute/v2/test_flavor.py +29 -3
  186. openstackclient/tests/unit/compute/v2/test_host.py +3 -3
  187. openstackclient/tests/unit/compute/v2/test_hypervisor.py +2 -2
  188. openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py +1 -1
  189. openstackclient/tests/unit/compute/v2/test_keypair.py +7 -7
  190. openstackclient/tests/unit/compute/v2/test_server.py +26 -111
  191. openstackclient/tests/unit/compute/v2/test_server_backup.py +1 -1
  192. openstackclient/tests/unit/compute/v2/test_server_event.py +2 -2
  193. openstackclient/tests/unit/compute/v2/test_server_group.py +1 -1
  194. openstackclient/tests/unit/compute/v2/test_server_image.py +1 -1
  195. openstackclient/tests/unit/compute/v2/test_server_migration.py +4 -4
  196. openstackclient/tests/unit/compute/v2/test_server_share.py +287 -0
  197. openstackclient/tests/unit/compute/v2/test_server_volume.py +2 -2
  198. openstackclient/tests/unit/compute/v2/test_service.py +3 -3
  199. openstackclient/tests/unit/compute/v2/test_usage.py +1 -1
  200. openstackclient/tests/unit/identity/v2_0/fakes.py +3 -7
  201. openstackclient/tests/unit/identity/v2_0/test_endpoint.py +1 -1
  202. openstackclient/tests/unit/identity/v2_0/test_project.py +1 -1
  203. openstackclient/tests/unit/identity/v2_0/test_role.py +1 -1
  204. openstackclient/tests/unit/identity/v2_0/test_role_assignment.py +1 -1
  205. openstackclient/tests/unit/identity/v2_0/test_service.py +1 -1
  206. openstackclient/tests/unit/identity/v2_0/test_token.py +2 -2
  207. openstackclient/tests/unit/identity/v2_0/test_user.py +1 -1
  208. openstackclient/tests/unit/identity/v3/fakes.py +8 -38
  209. openstackclient/tests/unit/identity/v3/test_access_rule.py +3 -3
  210. openstackclient/tests/unit/identity/v3/test_application_credential.py +4 -4
  211. openstackclient/tests/unit/identity/v3/test_credential.py +5 -5
  212. openstackclient/tests/unit/identity/v3/test_domain.py +5 -5
  213. openstackclient/tests/unit/identity/v3/test_endpoint.py +6 -6
  214. openstackclient/tests/unit/identity/v3/test_endpoint_group.py +1 -1
  215. openstackclient/tests/unit/identity/v3/test_group.py +12 -22
  216. openstackclient/tests/unit/identity/v3/test_identity_provider.py +303 -299
  217. openstackclient/tests/unit/identity/v3/test_implied_role.py +1 -1
  218. openstackclient/tests/unit/identity/v3/test_limit.py +5 -5
  219. openstackclient/tests/unit/identity/v3/test_mappings.py +163 -79
  220. openstackclient/tests/unit/identity/v3/test_project.py +28 -5
  221. openstackclient/tests/unit/identity/v3/test_protocol.py +3 -3
  222. openstackclient/tests/unit/identity/v3/test_region.py +5 -5
  223. openstackclient/tests/unit/identity/v3/test_registered_limit.py +5 -5
  224. openstackclient/tests/unit/identity/v3/test_role.py +8 -8
  225. openstackclient/tests/unit/identity/v3/test_role_assignment.py +1 -1
  226. openstackclient/tests/unit/identity/v3/test_service.py +5 -5
  227. openstackclient/tests/unit/identity/v3/test_token.py +2 -2
  228. openstackclient/tests/unit/identity/v3/test_trust.py +4 -4
  229. openstackclient/tests/unit/identity/v3/test_user.py +77 -10
  230. openstackclient/tests/unit/image/v2/test_image.py +11 -11
  231. openstackclient/tests/unit/image/v2/test_metadef_namespaces.py +105 -6
  232. openstackclient/tests/unit/network/test_common.py +0 -155
  233. openstackclient/tests/unit/network/v2/bgpvpn/__init__.py +0 -0
  234. openstackclient/tests/unit/network/v2/bgpvpn/fakes.py +179 -0
  235. openstackclient/tests/unit/network/v2/bgpvpn/test_bgpvpn.py +584 -0
  236. openstackclient/tests/unit/network/v2/bgpvpn/test_network_association.py +285 -0
  237. openstackclient/tests/unit/network/v2/bgpvpn/test_port_association.py +384 -0
  238. openstackclient/tests/unit/network/v2/bgpvpn/test_router_association.py +297 -0
  239. openstackclient/tests/unit/network/v2/fakes.py +5 -77
  240. openstackclient/tests/unit/network/v2/fwaas/__init__.py +0 -0
  241. openstackclient/tests/unit/network/v2/fwaas/test_group.py +923 -0
  242. openstackclient/tests/unit/network/v2/fwaas/test_policy.py +869 -0
  243. openstackclient/tests/unit/network/v2/fwaas/test_rule.py +1005 -0
  244. openstackclient/tests/unit/network/v2/taas/{test_osc_tap_flow.py → test_tap_flow.py} +18 -25
  245. openstackclient/tests/unit/network/v2/taas/{test_osc_tap_mirror.py → test_tap_mirror.py} +19 -29
  246. openstackclient/tests/unit/network/v2/taas/{test_osc_tap_service.py → test_tap_service.py} +19 -29
  247. openstackclient/tests/unit/network/v2/test_address_group.py +26 -2
  248. openstackclient/tests/unit/network/v2/test_address_scope.py +24 -0
  249. openstackclient/tests/unit/network/v2/{test_floating_ip_network.py → test_floating_ip.py} +27 -2
  250. openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py +37 -13
  251. openstackclient/tests/unit/network/v2/test_ip_availability.py +25 -0
  252. openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py +29 -3
  253. openstackclient/tests/unit/network/v2/test_network.py +74 -12
  254. openstackclient/tests/unit/network/v2/test_network_agent.py +58 -5
  255. openstackclient/tests/unit/network/v2/test_network_auto_allocated_topology.py +3 -3
  256. openstackclient/tests/unit/network/v2/test_network_flavor.py +26 -2
  257. openstackclient/tests/unit/network/v2/test_network_flavor_profile.py +24 -0
  258. openstackclient/tests/unit/network/v2/test_network_meter.py +24 -0
  259. openstackclient/tests/unit/network/v2/test_network_qos_policy.py +25 -1
  260. openstackclient/tests/unit/network/v2/test_network_qos_rule.py +2 -2
  261. openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py +24 -0
  262. openstackclient/tests/unit/network/v2/test_network_rbac.py +25 -1
  263. openstackclient/tests/unit/network/v2/test_network_segment.py +25 -1
  264. openstackclient/tests/unit/network/v2/test_network_segment_range.py +31 -10
  265. openstackclient/tests/unit/network/v2/test_network_trunk.py +1 -1
  266. openstackclient/tests/unit/network/v2/test_port.py +166 -0
  267. openstackclient/tests/unit/network/v2/test_router.py +36 -16
  268. openstackclient/tests/unit/network/v2/{test_security_group_network.py → test_security_group.py} +11 -8
  269. openstackclient/tests/unit/network/v2/{test_security_group_rule_network.py → test_security_group_rule.py} +28 -37
  270. openstackclient/tests/unit/network/v2/test_subnet.py +30 -5
  271. openstackclient/tests/unit/network/v2/test_subnet_pool.py +26 -1
  272. openstackclient/tests/unit/object/v1/fakes.py +8 -7
  273. openstackclient/tests/unit/object/v1/test_container.py +65 -101
  274. openstackclient/tests/unit/object/v1/test_container_all.py +8 -1
  275. openstackclient/tests/unit/object/v1/test_object.py +44 -84
  276. openstackclient/tests/unit/object/v1/test_object_all.py +8 -1
  277. openstackclient/tests/unit/test_hacking.py +108 -0
  278. openstackclient/tests/unit/volume/v2/fakes.py +21 -140
  279. openstackclient/tests/unit/volume/v2/test_volume_backup.py +6 -14
  280. openstackclient/tests/unit/volume/v2/test_volume_snapshot.py +8 -1
  281. openstackclient/tests/unit/volume/v2/test_volume_type.py +2 -4
  282. openstackclient/tests/unit/volume/v3/fakes.py +205 -100
  283. openstackclient/tests/unit/volume/v3/test_backup_record.py +114 -0
  284. openstackclient/tests/unit/volume/v3/test_consistency_group.py +720 -0
  285. openstackclient/tests/unit/volume/v3/test_consistency_group_snapshot.py +354 -0
  286. openstackclient/tests/unit/volume/v3/test_qos_specs.py +455 -0
  287. openstackclient/tests/unit/volume/v3/test_volume.py +60 -3
  288. openstackclient/tests/unit/volume/v3/test_volume_attachment.py +3 -1
  289. openstackclient/tests/unit/volume/v3/test_volume_backend.py +158 -0
  290. openstackclient/tests/unit/volume/v3/test_volume_backup.py +6 -14
  291. openstackclient/tests/unit/volume/v3/test_volume_group_type.py +65 -0
  292. openstackclient/tests/unit/volume/v3/test_volume_host.py +115 -0
  293. openstackclient/tests/unit/volume/v3/test_volume_snapshot.py +61 -1
  294. openstackclient/tests/unit/volume/v3/test_volume_type.py +2 -4
  295. openstackclient/volume/client.py +7 -3
  296. openstackclient/volume/v2/backup_record.py +15 -6
  297. openstackclient/volume/v2/consistency_group.py +29 -17
  298. openstackclient/volume/v2/consistency_group_snapshot.py +25 -10
  299. openstackclient/volume/v2/qos_specs.py +28 -17
  300. openstackclient/volume/v2/service.py +17 -6
  301. openstackclient/volume/v2/volume.py +60 -30
  302. openstackclient/volume/v2/volume_backend.py +19 -6
  303. openstackclient/volume/v2/volume_backup.py +48 -23
  304. openstackclient/volume/v2/volume_host.py +6 -4
  305. openstackclient/volume/v2/volume_snapshot.py +49 -24
  306. openstackclient/volume/v2/volume_transfer_request.py +31 -13
  307. openstackclient/volume/v2/volume_type.py +43 -24
  308. openstackclient/volume/v3/backup_record.py +94 -0
  309. openstackclient/volume/v3/block_storage_cleanup.py +11 -3
  310. openstackclient/volume/v3/block_storage_cluster.py +19 -7
  311. openstackclient/volume/v3/block_storage_log_level.py +15 -6
  312. openstackclient/volume/v3/block_storage_manage.py +10 -4
  313. openstackclient/volume/v3/block_storage_resource_filter.py +17 -5
  314. openstackclient/volume/v3/consistency_group.py +400 -0
  315. openstackclient/volume/v3/consistency_group_snapshot.py +225 -0
  316. openstackclient/volume/v3/qos_specs.py +389 -0
  317. openstackclient/volume/v3/service.py +16 -6
  318. openstackclient/volume/v3/volume.py +92 -40
  319. openstackclient/volume/v3/volume_attachment.py +47 -21
  320. openstackclient/volume/v3/volume_backend.py +130 -0
  321. openstackclient/volume/v3/volume_backup.py +55 -27
  322. openstackclient/volume/v3/volume_group.py +23 -13
  323. openstackclient/volume/v3/volume_group_snapshot.py +34 -17
  324. openstackclient/volume/v3/volume_group_type.py +27 -14
  325. openstackclient/volume/v3/volume_host.py +74 -0
  326. openstackclient/volume/v3/volume_message.py +18 -8
  327. openstackclient/volume/v3/volume_snapshot.py +70 -32
  328. openstackclient/volume/v3/volume_transfer_request.py +31 -13
  329. openstackclient/volume/v3/volume_type.py +42 -24
  330. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/METADATA +7 -8
  331. python_openstackclient-10.1.0.dist-info/RECORD +524 -0
  332. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/WHEEL +1 -1
  333. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/entry_points.txt +77 -25
  334. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/licenses/AUTHORS +9 -0
  335. python_openstackclient-10.1.0.dist-info/pbr.json +1 -0
  336. openstackclient/api/image_v1.py +0 -69
  337. openstackclient/api/image_v2.py +0 -79
  338. openstackclient/network/v2/floating_ip_pool.py +0 -38
  339. openstackclient/tests/functional/image/v1/test_image.py +0 -97
  340. openstackclient/tests/unit/api/test_image_v1.py +0 -96
  341. openstackclient/tests/unit/api/test_image_v2.py +0 -96
  342. openstackclient/tests/unit/network/v2/test_floating_ip_compute.py +0 -248
  343. openstackclient/tests/unit/network/v2/test_floating_ip_pool_compute.py +0 -49
  344. openstackclient/tests/unit/network/v2/test_floating_ip_pool_network.py +0 -39
  345. openstackclient/tests/unit/network/v2/test_network_compute.py +0 -404
  346. openstackclient/tests/unit/network/v2/test_security_group_compute.py +0 -392
  347. openstackclient/tests/unit/network/v2/test_security_group_rule_compute.py +0 -555
  348. python_openstackclient-9.0.0.dist-info/RECORD +0 -499
  349. python_openstackclient-9.0.0.dist-info/pbr.json +0 -1
  350. /openstackclient/{tests/functional/image/v1 → network/v2/bgpvpn}/__init__.py +0 -0
  351. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/licenses/LICENSE +0 -0
  352. {python_openstackclient-9.0.0.dist-info → python_openstackclient-10.1.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,274 @@
1
+ # Copyright 2020, Red Hat Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
4
+ # not use this file except in compliance with the License. You may obtain
5
+ # a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ # License for the specific language governing permissions and limitations
13
+ # under the License.
14
+
15
+ """Compute v2 Server action implementations"""
16
+
17
+ import argparse
18
+ from collections.abc import Iterable, Sequence
19
+ from typing import Any
20
+
21
+ from openstack import utils as sdk_utils
22
+ from osc_lib import exceptions
23
+ from osc_lib import utils
24
+
25
+ from openstackclient import command
26
+ from openstackclient.i18n import _
27
+
28
+
29
+ def _get_server_share_columns(
30
+ item: Any,
31
+ ) -> tuple[tuple[str, ...], tuple[str, ...]]:
32
+ # Non admin cannot see uuid and export location, so hide them
33
+ if item.uuid is None:
34
+ column_map = {
35
+ 'share_id': 'Share ID',
36
+ 'status': 'Status',
37
+ 'tag': 'Tag',
38
+ }
39
+ hidden_columns = [
40
+ 'id',
41
+ 'location',
42
+ 'name',
43
+ 'uuid',
44
+ 'export_location',
45
+ 'share_proto',
46
+ ]
47
+ else:
48
+ column_map = {
49
+ 'uuid': 'UUID',
50
+ 'share_id': 'Share ID',
51
+ 'status': 'Status',
52
+ 'tag': 'Tag',
53
+ 'export_location': 'Export Location',
54
+ }
55
+ hidden_columns = ['id', 'location', 'name', 'share_proto']
56
+
57
+ return utils.get_osc_show_columns_for_sdk_resource(
58
+ item, column_map, hidden_columns
59
+ )
60
+
61
+
62
+ class ListServerShare(command.Lister):
63
+ """List all the shares attached to a server.
64
+
65
+ Requires ``--os-compute-api-version 2.97`` or later.
66
+ """
67
+
68
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
69
+ parser = super().get_parser(prog_name)
70
+ parser.add_argument(
71
+ 'server',
72
+ metavar='<server>',
73
+ help=_('Server to list share mapping for (name or ID)'),
74
+ )
75
+ return parser
76
+
77
+ def take_action(
78
+ self, parsed_args: argparse.Namespace
79
+ ) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
80
+ compute_client = self.app.client_manager.compute
81
+
82
+ if not sdk_utils.supports_microversion(compute_client, '2.97'):
83
+ msg = _(
84
+ '--os-compute-api-version 2.97 or greater is required '
85
+ 'to support share attachments'
86
+ )
87
+ raise exceptions.CommandError(msg)
88
+
89
+ server = compute_client.find_server(
90
+ parsed_args.server,
91
+ ignore_missing=False,
92
+ )
93
+ shares = compute_client.share_attachments(server)
94
+
95
+ columns = (
96
+ 'share_id',
97
+ 'status',
98
+ 'tag',
99
+ )
100
+ column_headers = (
101
+ 'Share ID',
102
+ 'Status',
103
+ 'Tag',
104
+ )
105
+
106
+ return (
107
+ column_headers,
108
+ (utils.get_item_properties(s, columns) for s in shares),
109
+ )
110
+
111
+
112
+ class ShowServerShare(command.ShowOne):
113
+ """Show detail of a share attachment to a server.
114
+
115
+ Requires ``--os-compute-api-version 2.97`` or later.
116
+ """
117
+
118
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
119
+ parser = super().get_parser(prog_name)
120
+ parser.add_argument(
121
+ 'server',
122
+ metavar='<server>',
123
+ help=_('Server to show share mapping for (name or ID)'),
124
+ )
125
+ parser.add_argument(
126
+ 'share',
127
+ metavar='<share>',
128
+ help=_('Share to show details for (name or ID)'),
129
+ )
130
+ return parser
131
+
132
+ def take_action(
133
+ self, parsed_args: argparse.Namespace
134
+ ) -> tuple[Sequence[str], Iterable[Any]]:
135
+ compute_client = self.app.client_manager.compute
136
+ shared_file_system_client = (
137
+ self.app.client_manager.sdk_connection.shared_file_system
138
+ )
139
+
140
+ if not sdk_utils.supports_microversion(compute_client, '2.97'):
141
+ msg = _(
142
+ '--os-compute-api-version 2.97 or greater is required '
143
+ 'to support share attachments'
144
+ )
145
+ raise exceptions.CommandError(msg)
146
+
147
+ server = compute_client.find_server(
148
+ parsed_args.server,
149
+ ignore_missing=False,
150
+ )
151
+ share = shared_file_system_client.find_share(
152
+ parsed_args.share,
153
+ ignore_missing=False,
154
+ )
155
+ share_attachment = compute_client.get_share_attachment(
156
+ server, share.id
157
+ )
158
+
159
+ display_columns, columns = _get_server_share_columns(
160
+ share_attachment,
161
+ )
162
+ data = utils.get_item_properties(share_attachment, columns)
163
+ return display_columns, data
164
+
165
+
166
+ class AddServerShare(command.ShowOne):
167
+ """Add a share to a server.
168
+
169
+ Requires ``--os-compute-api-version 2.97`` or later.
170
+ """
171
+
172
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
173
+ parser = super().get_parser(prog_name)
174
+ parser.add_argument(
175
+ 'server',
176
+ metavar='<server>',
177
+ help=_('Server to add share to (name or ID)'),
178
+ )
179
+ parser.add_argument(
180
+ 'share',
181
+ metavar='<share>',
182
+ help=_('Share to add (name or ID)'),
183
+ )
184
+ parser.add_argument(
185
+ '--tag',
186
+ metavar='<tag>',
187
+ help=_(
188
+ 'Optional tag used to mount the share, '
189
+ 'if not provided the share uuid is used as tag by default'
190
+ ),
191
+ )
192
+ return parser
193
+
194
+ def take_action(
195
+ self, parsed_args: argparse.Namespace
196
+ ) -> tuple[Sequence[str], Iterable[Any]]:
197
+ compute_client = self.app.client_manager.compute
198
+ shared_file_system_client = (
199
+ self.app.client_manager.sdk_connection.shared_file_system
200
+ )
201
+
202
+ if not sdk_utils.supports_microversion(compute_client, '2.97'):
203
+ msg = _(
204
+ '--os-compute-api-version 2.97 or greater is required '
205
+ 'to support share attachments'
206
+ )
207
+ raise exceptions.CommandError(msg)
208
+
209
+ server = compute_client.find_server(
210
+ parsed_args.server,
211
+ ignore_missing=False,
212
+ )
213
+ share = shared_file_system_client.find_share(
214
+ parsed_args.share,
215
+ ignore_missing=False,
216
+ )
217
+
218
+ kwargs: dict[str, Any] = {}
219
+ if parsed_args.tag:
220
+ kwargs['tag'] = parsed_args.tag
221
+
222
+ share_attachment = compute_client.create_share_attachment(
223
+ server, share.id, **kwargs
224
+ )
225
+
226
+ display_columns, columns = _get_server_share_columns(
227
+ share_attachment,
228
+ )
229
+ data = utils.get_item_properties(share_attachment, columns)
230
+ return display_columns, data
231
+
232
+
233
+ class RemoveServerShare(command.Command):
234
+ """Remove a share from a server.
235
+
236
+ Requires ``--os-compute-api-version 2.97`` or later.
237
+ """
238
+
239
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
240
+ parser = super().get_parser(prog_name)
241
+ parser.add_argument(
242
+ 'server',
243
+ metavar='<server>',
244
+ help=_('Server to remove share from (name or ID)'),
245
+ )
246
+ parser.add_argument(
247
+ 'share',
248
+ metavar='<share>',
249
+ help=_('Share to remove (name or ID)'),
250
+ )
251
+ return parser
252
+
253
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
254
+ compute_client = self.app.client_manager.compute
255
+ shared_file_system_client = (
256
+ self.app.client_manager.sdk_connection.shared_file_system
257
+ )
258
+
259
+ if not sdk_utils.supports_microversion(compute_client, '2.97'):
260
+ msg = _(
261
+ '--os-compute-api-version 2.97 or greater is required '
262
+ 'to support share attachments'
263
+ )
264
+ raise exceptions.CommandError(msg)
265
+
266
+ server = compute_client.find_server(
267
+ parsed_args.server,
268
+ ignore_missing=False,
269
+ )
270
+ share = shared_file_system_client.find_share(
271
+ parsed_args.share,
272
+ ignore_missing=False,
273
+ )
274
+ compute_client.delete_share_attachment(server, share.id)
@@ -14,6 +14,10 @@
14
14
 
15
15
  """Compute v2 Server action implementations"""
16
16
 
17
+ import argparse
18
+ from collections.abc import Iterable
19
+ from typing import Any
20
+
17
21
  from openstack import utils as sdk_utils
18
22
  from osc_lib import exceptions
19
23
  from osc_lib import utils
@@ -25,7 +29,7 @@ from openstackclient.i18n import _
25
29
  class ListServerVolume(command.Lister):
26
30
  """List all the volumes attached to a server."""
27
31
 
28
- def get_parser(self, prog_name):
32
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
29
33
  parser = super().get_parser(prog_name)
30
34
  parser.add_argument(
31
35
  'server',
@@ -33,7 +37,9 @@ class ListServerVolume(command.Lister):
33
37
  )
34
38
  return parser
35
39
 
36
- def take_action(self, parsed_args):
40
+ def take_action(
41
+ self, parsed_args: argparse.Namespace
42
+ ) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
37
43
  compute_client = self.app.client_manager.compute
38
44
 
39
45
  server = compute_client.find_server(
@@ -81,7 +87,7 @@ class ListServerVolume(command.Lister):
81
87
  class SetServerVolume(command.Command):
82
88
  """Update a volume attachment on the server."""
83
89
 
84
- def get_parser(self, prog_name):
90
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
85
91
  parser = super().get_parser(prog_name)
86
92
  parser.add_argument(
87
93
  'server',
@@ -113,9 +119,11 @@ class SetServerVolume(command.Command):
113
119
  )
114
120
  return parser
115
121
 
116
- def take_action(self, parsed_args):
122
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
117
123
  compute_client = self.app.client_manager.compute
118
- volume_client = self.app.client_manager.sdk_connection.volume
124
+ volume_client = sdk_utils.ensure_service_version(
125
+ self.app.client_manager.sdk_connection.volume, '3'
126
+ )
119
127
 
120
128
  if parsed_args.delete_on_termination is not None:
121
129
  if not sdk_utils.supports_microversion(compute_client, '2.85'):
@@ -15,7 +15,10 @@
15
15
 
16
16
  """Service action implementations"""
17
17
 
18
+ import argparse
19
+ from collections.abc import Iterable
18
20
  import logging
21
+ from typing import Any
19
22
 
20
23
  from openstack import utils as sdk_utils
21
24
  from osc_lib import exceptions
@@ -31,7 +34,7 @@ LOG = logging.getLogger(__name__)
31
34
  class DeleteService(command.Command):
32
35
  _description = _("Delete compute service(s)")
33
36
 
34
- def get_parser(self, prog_name):
37
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
35
38
  parser = super().get_parser(prog_name)
36
39
  parser.add_argument(
37
40
  "service",
@@ -51,7 +54,7 @@ class DeleteService(command.Command):
51
54
  )
52
55
  return parser
53
56
 
54
- def take_action(self, parsed_args):
57
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
55
58
  compute_client = self.app.client_manager.compute
56
59
  result = 0
57
60
  for s in parsed_args.service:
@@ -84,7 +87,7 @@ value which can be used to uniquely identify the service in a multi-cell
84
87
  deployment."""
85
88
  )
86
89
 
87
- def get_parser(self, prog_name):
90
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
88
91
  parser = super().get_parser(prog_name)
89
92
  parser.add_argument(
90
93
  "--host",
@@ -107,7 +110,9 @@ deployment."""
107
110
  )
108
111
  return parser
109
112
 
110
- def take_action(self, parsed_args):
113
+ def take_action(
114
+ self, parsed_args: argparse.Namespace
115
+ ) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
111
116
  compute_client = self.app.client_manager.compute
112
117
  columns: tuple[str, ...] = (
113
118
  "id",
@@ -146,7 +151,7 @@ deployment."""
146
151
  class SetService(command.Command):
147
152
  _description = _("Set compute service properties")
148
153
 
149
- def get_parser(self, prog_name):
154
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
150
155
  parser = super().get_parser(prog_name)
151
156
  parser.add_argument("host", metavar="<host>", help=_("Name of host"))
152
157
  parser.add_argument(
@@ -192,7 +197,9 @@ class SetService(command.Command):
192
197
  return parser
193
198
 
194
199
  @staticmethod
195
- def _find_service_by_host_and_binary(compute_client, host, binary):
200
+ def _find_service_by_host_and_binary(
201
+ compute_client: Any, host: str, binary: str
202
+ ) -> Any:
196
203
  """Utility method to find a compute service by host and binary
197
204
 
198
205
  :param host: the name of the compute service host
@@ -220,7 +227,7 @@ class SetService(command.Command):
220
227
  raise exceptions.CommandError(msg)
221
228
  return services[0]
222
229
 
223
- def take_action(self, parsed_args):
230
+ def take_action(self, parsed_args: argparse.Namespace) -> None:
224
231
  compute_client = self.app.client_manager.compute
225
232
 
226
233
  if (
@@ -283,8 +290,10 @@ class SetService(command.Command):
283
290
  msg = _('--os-compute-api-version 2.11 or later is required')
284
291
  raise exceptions.CommandError(msg)
285
292
  try:
293
+ # FIXME(stephenfin): This is broken between 2.11 and 2.53. What
294
+ # is the expected ID here?
286
295
  compute_client.update_service_forced_down(
287
- service_id,
296
+ service_id, # type: ignore[arg-type]
288
297
  parsed_args.host,
289
298
  parsed_args.service,
290
299
  force_down,
@@ -15,10 +15,11 @@
15
15
 
16
16
  """Usage action implementations"""
17
17
 
18
- from collections.abc import Collection
18
+ import argparse
19
+ from collections.abc import Collection, Iterable, Sequence
19
20
  import datetime
20
21
  import functools
21
- import typing as ty
22
+ from typing import Any, cast
22
23
 
23
24
  from cliff import columns as cliff_columns
24
25
  from osc_lib import utils
@@ -40,32 +41,32 @@ class ProjectColumn(cliff_columns.FormattableColumn[str]):
40
41
  project_cache)`` to use this.
41
42
  """
42
43
 
43
- def __init__(self, value, project_cache=None):
44
+ def __init__(self, value: str, project_cache: Any = None) -> None:
44
45
  super().__init__(value)
45
46
  self.project_cache = project_cache or {}
46
47
 
47
- def human_readable(self):
48
+ def human_readable(self) -> str:
48
49
  project = self._value
49
50
  if not project:
50
51
  return ''
51
52
 
52
53
  if project in self.project_cache.keys():
53
- return self.project_cache[project].name
54
+ return cast(str, self.project_cache[project].name)
54
55
 
55
56
  return project
56
57
 
57
58
 
58
- class CountColumn(cliff_columns.FormattableColumn[Collection[ty.Any]]):
59
- def human_readable(self):
60
- return len(self._value) if self._value is not None else None
59
+ class CountColumn(cliff_columns.FormattableColumn[Collection[Any]]):
60
+ def human_readable(self) -> str:
61
+ return str(len(self._value)) if self._value is not None else ""
61
62
 
62
63
 
63
64
  class FloatColumn(cliff_columns.FormattableColumn[float]):
64
- def human_readable(self):
65
- return float(f"{self._value:.2f}")
65
+ def human_readable(self) -> str:
66
+ return f"{self._value:.2f}"
66
67
 
67
68
 
68
- def _formatters(project_cache):
69
+ def _formatters(project_cache: Any) -> dict[str, Any]:
69
70
  return {
70
71
  'project_id': functools.partial(
71
72
  ProjectColumn, project_cache=project_cache
@@ -77,21 +78,21 @@ def _formatters(project_cache):
77
78
  }
78
79
 
79
80
 
80
- def _get_usage_marker(usage):
81
+ def _get_usage_marker(usage: Any) -> str | None:
81
82
  marker = None
82
83
  if hasattr(usage, 'server_usages') and usage.server_usages:
83
84
  marker = usage.server_usages[-1]['instance_id']
84
85
  return marker
85
86
 
86
87
 
87
- def _get_usage_list_marker(usage_list):
88
+ def _get_usage_list_marker(usage_list: Any) -> str | None:
88
89
  marker = None
89
90
  if usage_list:
90
91
  marker = _get_usage_marker(usage_list[-1])
91
92
  return marker
92
93
 
93
94
 
94
- def _merge_usage(usage, next_usage):
95
+ def _merge_usage(usage: Any, next_usage: Any) -> None:
95
96
  usage.server_usages.extend(next_usage.server_usages)
96
97
  usage.total_hours += next_usage.total_hours
97
98
  usage.total_memory_mb_usage += next_usage.total_memory_mb_usage
@@ -99,7 +100,7 @@ def _merge_usage(usage, next_usage):
99
100
  usage.total_local_gb_usage += next_usage.total_local_gb_usage
100
101
 
101
102
 
102
- def _merge_usage_list(usages, next_usage_list):
103
+ def _merge_usage_list(usages: Any, next_usage_list: Any) -> None:
103
104
  for next_usage in next_usage_list:
104
105
  if next_usage.project_id in usages:
105
106
  _merge_usage(usages[next_usage.project_id], next_usage)
@@ -110,7 +111,7 @@ def _merge_usage_list(usages, next_usage_list):
110
111
  class ListUsage(command.Lister):
111
112
  _description = _("List resource usage per project")
112
113
 
113
- def get_parser(self, prog_name):
114
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
114
115
  parser = super().get_parser(prog_name)
115
116
  parser.add_argument(
116
117
  "--start",
@@ -128,12 +129,14 @@ class ListUsage(command.Lister):
128
129
  )
129
130
  return parser
130
131
 
131
- def take_action(self, parsed_args):
132
- def _format_project(project):
132
+ def take_action(
133
+ self, parsed_args: argparse.Namespace
134
+ ) -> tuple[tuple[str, ...], Iterable[tuple[Any, ...]]]:
135
+ def _format_project(project: str) -> str:
133
136
  if not project:
134
137
  return ""
135
138
  if project in project_cache.keys():
136
- return project_cache[project].name
139
+ return cast(str, project_cache[project].name)
137
140
  else:
138
141
  return project
139
142
 
@@ -154,7 +157,7 @@ class ListUsage(command.Lister):
154
157
  )
155
158
 
156
159
  date_cli_format = "%Y-%m-%d"
157
- now = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
160
+ now = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
158
161
 
159
162
  if parsed_args.start:
160
163
  start = datetime.datetime.strptime(
@@ -210,7 +213,7 @@ class ListUsage(command.Lister):
210
213
  class ShowUsage(command.ShowOne):
211
214
  _description = _("Show resource usage for a single project")
212
215
 
213
- def get_parser(self, prog_name):
216
+ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
214
217
  parser = super().get_parser(prog_name)
215
218
  parser.add_argument(
216
219
  "--project",
@@ -234,11 +237,13 @@ class ShowUsage(command.ShowOne):
234
237
  )
235
238
  return parser
236
239
 
237
- def take_action(self, parsed_args):
240
+ def take_action(
241
+ self, parsed_args: argparse.Namespace
242
+ ) -> tuple[Sequence[str], Iterable[Any]]:
238
243
  identity_client = self.app.client_manager.identity
239
244
  compute_client = self.app.client_manager.compute
240
245
  date_cli_format = "%Y-%m-%d"
241
- now = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
246
+ now = datetime.datetime.now(datetime.UTC).replace(tzinfo=None)
242
247
 
243
248
  if parsed_args.start:
244
249
  start = datetime.datetime.strptime(
@@ -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 keystoneclient.v2_0 import client as identity_client_v2
18
20
  from osc_lib import utils
@@ -39,7 +41,7 @@ AUTH_VERSIONS = {
39
41
  }
40
42
 
41
43
 
42
- def make_client(instance):
44
+ def make_client(instance: Any) -> Any:
43
45
  """Returns an identity service client."""
44
46
  identity_client = utils.get_client_class(
45
47
  API_NAME, instance._api_version[API_NAME], API_VERSIONS
@@ -56,7 +58,9 @@ def make_client(instance):
56
58
  return client
57
59
 
58
60
 
59
- def build_option_parser(parser):
61
+ def build_option_parser(
62
+ parser: argparse.ArgumentParser,
63
+ ) -> argparse.ArgumentParser:
60
64
  """Hook to add global options"""
61
65
  parser.add_argument(
62
66
  '--os-identity-api-version',
@@ -70,10 +74,11 @@ def build_option_parser(parser):
70
74
  return parser
71
75
 
72
76
 
77
+ # We're not going to add type hints to this at this point
73
78
  class IdentityClientv2(identity_client_v2.Client):
74
79
  """Tweak the earlier client class to deal with some changes"""
75
80
 
76
- def __getattr__(self, name):
81
+ def __getattr__(self, name: str) -> Any:
77
82
  # Map v3 'projects' back to v2 'tenants'
78
83
  if name == "projects":
79
84
  return self.tenants