python-openstackclient 8.2.0__py3-none-any.whl → 9.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 (233) hide show
  1. openstackclient/api/object_store_v1.py +4 -1
  2. openstackclient/command.py +27 -0
  3. openstackclient/common/availability_zone.py +1 -1
  4. openstackclient/common/clientmanager.py +59 -21
  5. openstackclient/common/configuration.py +1 -1
  6. openstackclient/common/extension.py +1 -1
  7. openstackclient/common/limits.py +1 -1
  8. openstackclient/common/module.py +5 -3
  9. openstackclient/common/project_cleanup.py +10 -8
  10. openstackclient/common/quota.py +54 -23
  11. openstackclient/common/versions.py +1 -2
  12. openstackclient/compute/v2/agent.py +1 -1
  13. openstackclient/compute/v2/aggregate.py +6 -5
  14. openstackclient/compute/v2/console.py +5 -3
  15. openstackclient/compute/v2/console_connection.py +1 -1
  16. openstackclient/compute/v2/flavor.py +1 -1
  17. openstackclient/compute/v2/host.py +1 -1
  18. openstackclient/compute/v2/hypervisor.py +1 -1
  19. openstackclient/compute/v2/hypervisor_stats.py +1 -1
  20. openstackclient/compute/v2/keypair.py +1 -1
  21. openstackclient/compute/v2/server.py +78 -29
  22. openstackclient/compute/v2/server_backup.py +1 -1
  23. openstackclient/compute/v2/server_event.py +1 -1
  24. openstackclient/compute/v2/server_group.py +4 -2
  25. openstackclient/compute/v2/server_image.py +1 -1
  26. openstackclient/compute/v2/server_migration.py +1 -1
  27. openstackclient/compute/v2/server_volume.py +1 -1
  28. openstackclient/compute/v2/service.py +1 -1
  29. openstackclient/compute/v2/usage.py +6 -4
  30. openstackclient/identity/common.py +33 -1
  31. openstackclient/identity/v2_0/catalog.py +3 -2
  32. openstackclient/identity/v2_0/ec2creds.py +1 -1
  33. openstackclient/identity/v2_0/endpoint.py +1 -1
  34. openstackclient/identity/v2_0/project.py +17 -7
  35. openstackclient/identity/v2_0/role.py +1 -1
  36. openstackclient/identity/v2_0/role_assignment.py +3 -3
  37. openstackclient/identity/v2_0/service.py +4 -2
  38. openstackclient/identity/v2_0/token.py +1 -1
  39. openstackclient/identity/v2_0/user.py +2 -2
  40. openstackclient/identity/v3/access_rule.py +16 -4
  41. openstackclient/identity/v3/application_credential.py +30 -10
  42. openstackclient/identity/v3/catalog.py +3 -3
  43. openstackclient/identity/v3/consumer.py +1 -1
  44. openstackclient/identity/v3/credential.py +1 -1
  45. openstackclient/identity/v3/domain.py +10 -4
  46. openstackclient/identity/v3/ec2creds.py +1 -1
  47. openstackclient/identity/v3/endpoint.py +33 -12
  48. openstackclient/identity/v3/endpoint_group.py +1 -1
  49. openstackclient/identity/v3/federation_protocol.py +40 -41
  50. openstackclient/identity/v3/group.py +11 -5
  51. openstackclient/identity/v3/identity_provider.py +12 -10
  52. openstackclient/identity/v3/implied_role.py +1 -1
  53. openstackclient/identity/v3/limit.py +86 -85
  54. openstackclient/identity/v3/mapping.py +1 -1
  55. openstackclient/identity/v3/policy.py +1 -1
  56. openstackclient/identity/v3/project.py +191 -115
  57. openstackclient/identity/v3/region.py +1 -1
  58. openstackclient/identity/v3/registered_limit.py +97 -109
  59. openstackclient/identity/v3/role.py +20 -39
  60. openstackclient/identity/v3/role_assignment.py +12 -23
  61. openstackclient/identity/v3/service.py +1 -1
  62. openstackclient/identity/v3/service_provider.py +1 -1
  63. openstackclient/identity/v3/tag.py +1 -11
  64. openstackclient/identity/v3/token.py +3 -2
  65. openstackclient/identity/v3/trust.py +4 -2
  66. openstackclient/identity/v3/unscoped_saml.py +1 -1
  67. openstackclient/identity/v3/user.py +22 -13
  68. openstackclient/image/v1/image.py +19 -16
  69. openstackclient/image/v2/cache.py +1 -1
  70. openstackclient/image/v2/image.py +16 -12
  71. openstackclient/image/v2/info.py +1 -1
  72. openstackclient/image/v2/metadef_namespaces.py +1 -1
  73. openstackclient/image/v2/metadef_objects.py +1 -1
  74. openstackclient/image/v2/metadef_properties.py +3 -2
  75. openstackclient/image/v2/metadef_resource_type_association.py +1 -1
  76. openstackclient/image/v2/metadef_resource_types.py +1 -1
  77. openstackclient/image/v2/task.py +1 -1
  78. openstackclient/network/common.py +10 -9
  79. openstackclient/network/v2/address_group.py +4 -3
  80. openstackclient/network/v2/address_scope.py +8 -6
  81. openstackclient/network/v2/default_security_group_rule.py +9 -8
  82. openstackclient/network/v2/floating_ip.py +16 -9
  83. openstackclient/network/v2/floating_ip_port_forwarding.py +9 -6
  84. openstackclient/network/v2/ip_availability.py +7 -4
  85. openstackclient/network/v2/l3_conntrack_helper.py +11 -4
  86. openstackclient/network/v2/local_ip.py +13 -7
  87. openstackclient/network/v2/local_ip_association.py +7 -4
  88. openstackclient/network/v2/ndp_proxy.py +13 -6
  89. openstackclient/network/v2/network.py +33 -16
  90. openstackclient/network/v2/network_agent.py +5 -5
  91. openstackclient/network/v2/network_auto_allocated_topology.py +1 -1
  92. openstackclient/network/v2/network_flavor.py +1 -1
  93. openstackclient/network/v2/network_flavor_profile.py +1 -1
  94. openstackclient/network/v2/network_meter.py +1 -1
  95. openstackclient/network/v2/network_meter_rule.py +1 -1
  96. openstackclient/network/v2/network_qos_policy.py +7 -5
  97. openstackclient/network/v2/network_qos_rule.py +1 -1
  98. openstackclient/network/v2/network_qos_rule_type.py +1 -1
  99. openstackclient/network/v2/network_rbac.py +8 -5
  100. openstackclient/network/v2/network_segment.py +2 -2
  101. openstackclient/network/v2/network_segment_range.py +13 -6
  102. openstackclient/network/v2/network_service_provider.py +1 -1
  103. openstackclient/network/v2/network_trunk.py +65 -42
  104. openstackclient/network/v2/port.py +22 -20
  105. openstackclient/network/v2/router.py +19 -8
  106. openstackclient/network/v2/security_group.py +10 -6
  107. openstackclient/network/v2/security_group_rule.py +11 -5
  108. openstackclient/network/v2/subnet.py +17 -18
  109. openstackclient/network/v2/subnet_pool.py +11 -9
  110. openstackclient/network/v2/taas/__init__.py +0 -0
  111. openstackclient/network/v2/taas/tap_flow.py +245 -0
  112. openstackclient/network/v2/taas/tap_mirror.py +237 -0
  113. openstackclient/network/v2/taas/tap_service.py +211 -0
  114. openstackclient/object/v1/account.py +1 -1
  115. openstackclient/object/v1/container.py +1 -1
  116. openstackclient/object/v1/object.py +1 -1
  117. openstackclient/shell.py +18 -8
  118. openstackclient/tests/functional/identity/v3/test_catalog.py +42 -23
  119. openstackclient/tests/functional/identity/v3/test_limit.py +47 -0
  120. openstackclient/tests/functional/identity/v3/test_role_assignment.py +174 -0
  121. openstackclient/tests/functional/image/v2/test_cache.py +54 -0
  122. openstackclient/tests/functional/image/v2/test_metadef_objects.py +69 -0
  123. openstackclient/tests/functional/image/v2/test_metadef_resource_type.py +55 -0
  124. openstackclient/tests/functional/volume/v3/test_volume_snapshot.py +46 -132
  125. openstackclient/tests/unit/common/test_command.py +1 -1
  126. openstackclient/tests/unit/common/test_extension.py +2 -3
  127. openstackclient/tests/unit/common/test_module.py +14 -7
  128. openstackclient/tests/unit/common/test_quota.py +79 -0
  129. openstackclient/tests/unit/compute/v2/test_aggregate.py +5 -3
  130. openstackclient/tests/unit/compute/v2/test_console.py +1 -4
  131. openstackclient/tests/unit/compute/v2/test_flavor.py +1 -3
  132. openstackclient/tests/unit/compute/v2/test_hypervisor_stats.py +1 -9
  133. openstackclient/tests/unit/compute/v2/test_server.py +370 -38
  134. openstackclient/tests/unit/compute/v2/test_server_backup.py +1 -3
  135. openstackclient/tests/unit/compute/v2/test_service.py +1 -3
  136. openstackclient/tests/unit/fakes.py +35 -134
  137. openstackclient/tests/unit/identity/test_common.py +100 -0
  138. openstackclient/tests/unit/identity/v2_0/test_project.py +4 -4
  139. openstackclient/tests/unit/identity/v3/fakes.py +10 -2
  140. openstackclient/tests/unit/identity/v3/test_application_credential.py +3 -3
  141. openstackclient/tests/unit/identity/v3/test_domain.py +1 -1
  142. openstackclient/tests/unit/identity/v3/test_endpoint.py +1 -1
  143. openstackclient/tests/unit/identity/v3/test_group.py +4 -2
  144. openstackclient/tests/unit/identity/v3/test_identity_provider.py +10 -10
  145. openstackclient/tests/unit/identity/v3/test_limit.py +197 -145
  146. openstackclient/tests/unit/identity/v3/test_oauth.py +1 -1
  147. openstackclient/tests/unit/identity/v3/test_project.py +832 -513
  148. openstackclient/tests/unit/identity/v3/test_protocol.py +97 -88
  149. openstackclient/tests/unit/identity/v3/test_registered_limit.py +356 -221
  150. openstackclient/tests/unit/identity/v3/test_role.py +1 -82
  151. openstackclient/tests/unit/identity/v3/test_user.py +7 -51
  152. openstackclient/tests/unit/image/v2/test_image.py +116 -5
  153. openstackclient/tests/unit/network/test_common.py +9 -13
  154. openstackclient/tests/unit/network/v2/taas/__init__.py +0 -0
  155. openstackclient/tests/unit/network/v2/taas/test_osc_tap_flow.py +276 -0
  156. openstackclient/tests/unit/network/v2/taas/test_osc_tap_mirror.py +288 -0
  157. openstackclient/tests/unit/network/v2/taas/test_osc_tap_service.py +271 -0
  158. openstackclient/tests/unit/network/v2/test_address_group.py +19 -22
  159. openstackclient/tests/unit/network/v2/test_address_scope.py +10 -15
  160. openstackclient/tests/unit/network/v2/test_default_security_group_rule.py +38 -49
  161. openstackclient/tests/unit/network/v2/test_floating_ip_network.py +21 -27
  162. openstackclient/tests/unit/network/v2/test_floating_ip_port_forwarding.py +21 -18
  163. openstackclient/tests/unit/network/v2/test_ip_availability.py +6 -8
  164. openstackclient/tests/unit/network/v2/test_l3_conntrack_helper.py +6 -15
  165. openstackclient/tests/unit/network/v2/test_local_ip.py +12 -23
  166. openstackclient/tests/unit/network/v2/test_local_ip_association.py +13 -18
  167. openstackclient/tests/unit/network/v2/test_ndp_proxy.py +11 -21
  168. openstackclient/tests/unit/network/v2/test_network.py +41 -37
  169. openstackclient/tests/unit/network/v2/test_network_agent.py +13 -20
  170. openstackclient/tests/unit/network/v2/test_network_auto_allocated_topology.py +5 -8
  171. openstackclient/tests/unit/network/v2/test_network_flavor.py +14 -26
  172. openstackclient/tests/unit/network/v2/test_network_flavor_profile.py +14 -17
  173. openstackclient/tests/unit/network/v2/test_network_meter.py +7 -17
  174. openstackclient/tests/unit/network/v2/test_network_meter_rule.py +10 -20
  175. openstackclient/tests/unit/network/v2/test_network_qos_policy.py +7 -13
  176. openstackclient/tests/unit/network/v2/test_network_qos_rule.py +44 -54
  177. openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py +2 -7
  178. openstackclient/tests/unit/network/v2/test_network_rbac.py +21 -36
  179. openstackclient/tests/unit/network/v2/test_network_segment.py +13 -29
  180. openstackclient/tests/unit/network/v2/test_network_segment_range.py +20 -19
  181. openstackclient/tests/unit/network/v2/test_network_service_provider.py +1 -4
  182. openstackclient/tests/unit/network/v2/test_network_trunk.py +52 -47
  183. openstackclient/tests/unit/network/v2/test_port.py +75 -86
  184. openstackclient/tests/unit/network/v2/test_router.py +104 -126
  185. openstackclient/tests/unit/network/v2/test_security_group_network.py +19 -26
  186. openstackclient/tests/unit/network/v2/test_security_group_rule_network.py +17 -18
  187. openstackclient/tests/unit/network/v2/test_subnet.py +35 -46
  188. openstackclient/tests/unit/network/v2/test_subnet_pool.py +21 -33
  189. openstackclient/tests/unit/volume/test_find_resource.py +4 -13
  190. openstackclient/tests/unit/volume/v2/test_consistency_group.py +8 -2
  191. openstackclient/tests/unit/volume/v2/test_volume.py +7 -6
  192. openstackclient/tests/unit/volume/v2/test_volume_backup.py +3 -1
  193. openstackclient/tests/unit/volume/v3/test_volume.py +38 -12
  194. openstackclient/tests/unit/volume/v3/test_volume_backup.py +9 -0
  195. openstackclient/volume/client.py +7 -17
  196. openstackclient/volume/v2/backup_record.py +1 -1
  197. openstackclient/volume/v2/consistency_group.py +9 -9
  198. openstackclient/volume/v2/consistency_group_snapshot.py +3 -3
  199. openstackclient/volume/v2/qos_specs.py +3 -3
  200. openstackclient/volume/v2/service.py +1 -1
  201. openstackclient/volume/v2/volume.py +14 -7
  202. openstackclient/volume/v2/volume_backend.py +1 -1
  203. openstackclient/volume/v2/volume_backup.py +7 -5
  204. openstackclient/volume/v2/volume_host.py +1 -2
  205. openstackclient/volume/v2/volume_snapshot.py +4 -4
  206. openstackclient/volume/v2/volume_transfer_request.py +3 -3
  207. openstackclient/volume/v2/volume_type.py +16 -11
  208. openstackclient/volume/v3/block_storage_cleanup.py +1 -1
  209. openstackclient/volume/v3/block_storage_cluster.py +1 -1
  210. openstackclient/volume/v3/block_storage_log_level.py +1 -1
  211. openstackclient/volume/v3/block_storage_manage.py +1 -1
  212. openstackclient/volume/v3/block_storage_resource_filter.py +1 -1
  213. openstackclient/volume/v3/service.py +1 -1
  214. openstackclient/volume/v3/volume.py +16 -9
  215. openstackclient/volume/v3/volume_attachment.py +6 -5
  216. openstackclient/volume/v3/volume_backup.py +20 -5
  217. openstackclient/volume/v3/volume_group.py +1 -1
  218. openstackclient/volume/v3/volume_group_snapshot.py +1 -1
  219. openstackclient/volume/v3/volume_group_type.py +1 -1
  220. openstackclient/volume/v3/volume_message.py +1 -1
  221. openstackclient/volume/v3/volume_snapshot.py +4 -4
  222. openstackclient/volume/v3/volume_transfer_request.py +3 -3
  223. openstackclient/volume/v3/volume_type.py +20 -14
  224. {python_openstackclient-8.2.0.dist-info → python_openstackclient-9.0.0.dist-info}/METADATA +15 -13
  225. {python_openstackclient-8.2.0.dist-info → python_openstackclient-9.0.0.dist-info}/RECORD +231 -219
  226. {python_openstackclient-8.2.0.dist-info → python_openstackclient-9.0.0.dist-info}/WHEEL +1 -1
  227. {python_openstackclient-8.2.0.dist-info → python_openstackclient-9.0.0.dist-info}/entry_points.txt +15 -0
  228. {python_openstackclient-8.2.0.dist-info → python_openstackclient-9.0.0.dist-info/licenses}/AUTHORS +15 -0
  229. python_openstackclient-9.0.0.dist-info/pbr.json +1 -0
  230. openstackclient/tests/unit/common/test_logs.py +0 -221
  231. python_openstackclient-8.2.0.dist-info/pbr.json +0 -1
  232. {python_openstackclient-8.2.0.dist-info → python_openstackclient-9.0.0.dist-info/licenses}/LICENSE +0 -0
  233. {python_openstackclient-8.2.0.dist-info → python_openstackclient-9.0.0.dist-info}/top_level.txt +0 -0
@@ -256,7 +256,10 @@ class APIv1(api.BaseAPI):
256
256
  # object's name in the container.
257
257
  object_name_str = name if name else object
258
258
 
259
- full_url = f"{urllib.parse.quote(container)}/{urllib.parse.quote(object_name_str)}"
259
+ full_url = (
260
+ f"{urllib.parse.quote(container)}/"
261
+ f"{urllib.parse.quote(object_name_str)}"
262
+ )
260
263
  with open(object, 'rb') as f:
261
264
  response = self.create(
262
265
  full_url,
@@ -0,0 +1,27 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may
2
+ # not use this file except in compliance with the License. You may obtain
3
+ # a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10
+ # License for the specific language governing permissions and limitations
11
+ # under the License.
12
+
13
+ from cliff import lister
14
+ from cliff import show
15
+ from osc_lib.command import command
16
+
17
+ from openstackclient import shell
18
+
19
+
20
+ class Command(command.Command):
21
+ app: shell.OpenStackShell
22
+
23
+
24
+ class Lister(Command, lister.Lister): ...
25
+
26
+
27
+ class ShowOne(Command, show.ShowOne): ...
@@ -17,9 +17,9 @@ import copy
17
17
  import logging
18
18
 
19
19
  from openstack import exceptions as sdk_exceptions
20
- from osc_lib.command import command
21
20
  from osc_lib import utils
22
21
 
22
+ from openstackclient import command
23
23
  from openstackclient.i18n import _
24
24
 
25
25
 
@@ -15,15 +15,25 @@
15
15
 
16
16
  """Manage access to the clients, including authenticating when needed."""
17
17
 
18
+ import argparse
19
+ from collections.abc import Callable
18
20
  import importlib
19
21
  import logging
20
22
  import sys
21
23
  import typing as ty
22
24
 
25
+ from osc_lib.cli import client_config
23
26
  from osc_lib import clientmanager
24
27
  from osc_lib import shell
25
28
  import stevedore
26
29
 
30
+ if ty.TYPE_CHECKING:
31
+ from keystoneauth1 import access as ksa_access
32
+ from openstack.compute.v2 import _proxy as compute_proxy
33
+ from openstack.image.v2 import _proxy as image_proxy
34
+ from openstack.network.v2 import _proxy as network_proxy
35
+
36
+ from openstackclient.api import object_store_v1
27
37
 
28
38
  LOG = logging.getLogger(__name__)
29
39
 
@@ -40,11 +50,23 @@ class ClientManager(clientmanager.ClientManager):
40
50
  in osc-lib so we need to maintain a transition period.
41
51
  """
42
52
 
43
- # A simple incrementing version for the plugin to know what is available
44
- PLUGIN_INTERFACE_VERSION = "2"
45
-
46
- # Let the commands set this
47
- _auth_required = False
53
+ if ty.TYPE_CHECKING:
54
+ # we know this will be set by us and will not be nullable
55
+ auth_ref: ksa_access.AccessInfo
56
+
57
+ # this is a hack to keep mypy happy: the actual attributes are set in
58
+ # get_plugin_modules below
59
+ # TODO(stephenfin): Change the types of identity and volume once we've
60
+ # migrated everything to SDK. Hopefully by then we'll have figured out
61
+ # how to statically distinguish between the v2 and v3 versions of both
62
+ # services...
63
+ # TODO(stephenfin): We also need to migrate object storage...
64
+ compute: compute_proxy.Proxy
65
+ identity: ty.Any
66
+ image: image_proxy.Proxy
67
+ network: network_proxy.Proxy
68
+ object_store: object_store_v1.APIv1
69
+ volume: ty.Any
48
70
 
49
71
  def __init__(
50
72
  self,
@@ -81,6 +103,12 @@ class ClientManager(clientmanager.ClientManager):
81
103
  self._auth_required
82
104
  and self._cli_options._openstack_config is not None
83
105
  ):
106
+ if not isinstance(
107
+ self._cli_options._openstack_config, client_config.OSC_Config
108
+ ):
109
+ # programmer error
110
+ raise TypeError('unexpected type for _openstack_config')
111
+
84
112
  self._cli_options._openstack_config._pw_callback = (
85
113
  shell.prompt_for_password
86
114
  )
@@ -107,6 +135,13 @@ class ClientManager(clientmanager.ClientManager):
107
135
  self._cli_options.config['auth_type'] = self._original_auth_type
108
136
  del self._cli_options.config['auth']['token']
109
137
  del self._cli_options.config['auth']['endpoint']
138
+
139
+ if not isinstance(
140
+ self._cli_options._openstack_config, client_config.OSC_Config
141
+ ):
142
+ # programmer error
143
+ raise TypeError('unexpected type for _openstack_config')
144
+
110
145
  self._cli_options._auth = (
111
146
  self._cli_options._openstack_config.load_auth_plugin(
112
147
  self._cli_options.config,
@@ -144,11 +179,25 @@ class ClientManager(clientmanager.ClientManager):
144
179
 
145
180
  # Plugin Support
146
181
 
182
+ ArgumentParserT = ty.TypeVar('ArgumentParserT', bound=argparse.ArgumentParser)
183
+
184
+
185
+ @ty.runtime_checkable # Optional: allows usage with isinstance()
186
+ class PluginModule(ty.Protocol):
187
+ DEFAULT_API_VERSION: str
188
+ API_VERSION_OPTION: str
189
+ API_NAME: str
190
+ API_VERSIONS: tuple[str]
191
+
192
+ make_client: Callable[..., ty.Any]
193
+ build_option_parser: Callable[[ArgumentParserT], ArgumentParserT]
194
+ check_api_version: Callable[[str], bool]
195
+
147
196
 
148
197
  def _on_load_failure_callback(
149
198
  manager: stevedore.ExtensionManager,
150
199
  ep: importlib.metadata.EntryPoint,
151
- err: Exception,
200
+ err: BaseException,
152
201
  ) -> None:
153
202
  sys.stderr.write(
154
203
  f"WARNING: Failed to import plugin {ep.group}:{ep.name}: {err}.\n"
@@ -158,36 +207,25 @@ def _on_load_failure_callback(
158
207
  def get_plugin_modules(group):
159
208
  """Find plugin entry points"""
160
209
  mod_list = []
210
+ mgr: stevedore.ExtensionManager[PluginModule]
161
211
  mgr = stevedore.ExtensionManager(
162
212
  group, on_load_failure_callback=_on_load_failure_callback
163
213
  )
164
214
  for ep in mgr:
165
215
  LOG.debug('Found plugin %s', ep.name)
166
216
 
167
- # Different versions of stevedore use different
168
- # implementations of EntryPoint from other libraries, which
169
- # are not API-compatible.
170
- try:
171
- module_name = ep.entry_point.module_name
172
- except AttributeError:
173
- try:
174
- module_name = ep.entry_point.module
175
- except AttributeError:
176
- module_name = ep.entry_point.value
217
+ module_name = ep.entry_point.module
177
218
 
178
219
  try:
179
220
  module = importlib.import_module(module_name)
180
221
  except Exception as err:
181
222
  sys.stderr.write(
182
- f"WARNING: Failed to import plugin {ep.group}:{ep.name}: "
183
- f"{err}.\n"
223
+ f"WARNING: Failed to import plugin "
224
+ f"{ep.module_name}:{ep.name}: {err}.\n"
184
225
  )
185
226
  continue
186
227
 
187
228
  mod_list.append(module)
188
- init_func = getattr(module, 'Initialize', None)
189
- if init_func:
190
- init_func('x')
191
229
 
192
230
  # Add the plugin to the ClientManager
193
231
  setattr(
@@ -14,8 +14,8 @@
14
14
  """Configuration action implementations"""
15
15
 
16
16
  from keystoneauth1.loading import base
17
- from osc_lib.command import command
18
17
 
18
+ from openstackclient import command
19
19
  from openstackclient.i18n import _
20
20
 
21
21
  REDACTED = "<redacted>"
@@ -17,9 +17,9 @@
17
17
 
18
18
  import logging
19
19
 
20
- from osc_lib.command import command
21
20
  from osc_lib import utils
22
21
 
22
+ from openstackclient import command
23
23
  from openstackclient.i18n import _
24
24
 
25
25
  LOG = logging.getLogger(__name__)
@@ -17,9 +17,9 @@
17
17
 
18
18
  import itertools
19
19
 
20
- from osc_lib.command import command
21
20
  from osc_lib import utils
22
21
 
22
+ from openstackclient import command
23
23
  from openstackclient.i18n import _
24
24
  from openstackclient.identity import common as identity_common
25
25
 
@@ -17,9 +17,9 @@
17
17
 
18
18
  import sys
19
19
 
20
- from osc_lib.command import command
21
20
  from osc_lib import utils
22
21
 
22
+ from openstackclient import command
23
23
  from openstackclient.i18n import _
24
24
 
25
25
 
@@ -48,7 +48,9 @@ class ListCommand(command.Lister):
48
48
  columns = ('Command Group', 'Commands')
49
49
 
50
50
  if parsed_args.group:
51
- groups = (group for group in groups if parsed_args.group in group)
51
+ groups = sorted(
52
+ group for group in groups if parsed_args.group in group
53
+ )
52
54
 
53
55
  commands = []
54
56
  for group in groups:
@@ -59,7 +61,7 @@ class ListCommand(command.Lister):
59
61
  # TODO(bapalm): Fix this when cliff properly supports
60
62
  # handling the detection rather than using the hard-code below.
61
63
  if parsed_args.formatter == 'table':
62
- command_names = utils.format_list(command_names, "\n")
64
+ command_names = utils.format_list(command_names, "\n") # type: ignore
63
65
 
64
66
  commands.append((group, command_names))
65
67
 
@@ -20,8 +20,8 @@ import queue
20
20
  import typing as ty
21
21
 
22
22
  from cliff.formatters import table
23
- from osc_lib.command import command
24
23
 
24
+ from openstackclient import command
25
25
  from openstackclient.i18n import _
26
26
  from openstackclient.identity import common as identity_common
27
27
 
@@ -90,17 +90,19 @@ class ProjectCleanup(command.Command):
90
90
  return parser
91
91
 
92
92
  def take_action(self, parsed_args):
93
- sdk = self.app.client_manager.sdk_connection
93
+ connection = self.app.client_manager.sdk_connection
94
94
 
95
95
  if parsed_args.auth_project:
96
- project_connect = sdk
96
+ # is we've got a project already configured, use the connection
97
+ # as-is
98
+ pass
97
99
  elif parsed_args.project:
98
- project = sdk.identity.find_project(
100
+ project = connection.identity.find_project(
99
101
  name_or_id=parsed_args.project, ignore_missing=False
100
102
  )
101
- project_connect = sdk.connect_as_project(project)
103
+ connection = connection.connect_as_project(project)
102
104
 
103
- if project_connect:
105
+ if connection:
104
106
  status_queue: queue.Queue[ty.Any] = queue.Queue()
105
107
  parsed_args.max_width = int(
106
108
  os.environ.get('CLIFF_MAX_TERM_WIDTH', 0)
@@ -120,7 +122,7 @@ class ProjectCleanup(command.Command):
120
122
  if parsed_args.updated_before:
121
123
  filters['updated_at'] = parsed_args.updated_before
122
124
 
123
- project_connect.project_cleanup(
125
+ connection.project_cleanup(
124
126
  dry_run=True,
125
127
  status_queue=status_queue,
126
128
  filters=filters,
@@ -150,7 +152,7 @@ class ProjectCleanup(command.Command):
150
152
 
151
153
  self.log.warning(_('Deleting resources'))
152
154
 
153
- project_connect.project_cleanup(
155
+ connection.project_cleanup(
154
156
  dry_run=False,
155
157
  status_queue=status_queue,
156
158
  filters=filters,
@@ -21,10 +21,10 @@ import sys
21
21
  import typing as ty
22
22
 
23
23
  from openstack import exceptions as sdk_exceptions
24
- from osc_lib.command import command
25
24
  from osc_lib import exceptions
26
25
  from osc_lib import utils
27
26
 
27
+ from openstackclient import command
28
28
  from openstackclient.i18n import _
29
29
  from openstackclient.network import common
30
30
 
@@ -272,7 +272,10 @@ class ListQuota(command.Lister):
272
272
  sdk_exceptions.NotFoundException,
273
273
  ) as exc:
274
274
  # Project not found, move on to next one
275
- LOG.warning(f"Project {project_id} not found: {exc}")
275
+ LOG.warning(
276
+ 'Project %(project_id)s not found: %(exc)s',
277
+ {'project_id': project_id, 'exc': exc},
278
+ )
276
279
  continue
277
280
 
278
281
  project_result = _xform_get_quota(
@@ -334,7 +337,10 @@ class ListQuota(command.Lister):
334
337
  sdk_exceptions.NotFoundException,
335
338
  ) as exc:
336
339
  # Project not found, move on to next one
337
- LOG.warning(f"Project {project_id} not found: {exc}")
340
+ LOG.warning(
341
+ 'Project %(project_id)s not found: %(exc)s',
342
+ {'project_id': project_id, 'exc': exc},
343
+ )
338
344
  continue
339
345
 
340
346
  project_result = _xform_get_quota(
@@ -389,7 +395,10 @@ class ListQuota(command.Lister):
389
395
  sdk_exceptions.ForbiddenException,
390
396
  ) as exc:
391
397
  # Project not found, move on to next one
392
- LOG.warning(f"Project {project_id} not found: {exc}")
398
+ LOG.warning(
399
+ 'Project %(project_id)s not found: %(exc)s',
400
+ {'project_id': project_id, 'exc': exc},
401
+ )
393
402
  continue
394
403
 
395
404
  project_result = _xform_get_quota(
@@ -746,21 +755,32 @@ and ``server-group-members`` output for a given quota class."""
746
755
  # values if the project or class does not exist. This is expected
747
756
  # behavior. However, we have already checked for the presence of the
748
757
  # project above so it shouldn't be an issue.
749
- if parsed_args.service in {'all', 'compute'}:
758
+ if parsed_args.service == 'compute' or (
759
+ parsed_args.service == 'all'
760
+ and self.app.client_manager.is_compute_endpoint_enabled()
761
+ ):
750
762
  compute_quota_info = get_compute_quotas(
751
763
  self.app,
752
764
  project,
753
765
  detail=parsed_args.usage,
754
766
  default=parsed_args.default,
755
767
  )
756
- if parsed_args.service in {'all', 'volume'}:
768
+
769
+ if parsed_args.service == 'volume' or (
770
+ parsed_args.service == 'all'
771
+ and self.app.client_manager.is_volume_endpoint_enabled()
772
+ ):
757
773
  volume_quota_info = get_volume_quotas(
758
774
  self.app,
759
775
  project,
760
776
  detail=parsed_args.usage,
761
777
  default=parsed_args.default,
762
778
  )
763
- if parsed_args.service in {'all', 'network'}:
779
+
780
+ if parsed_args.service == 'network' or (
781
+ parsed_args.service == 'all'
782
+ and self.app.client_manager.is_network_endpoint_enabled()
783
+ ):
764
784
  network_quota_info = get_network_quotas(
765
785
  self.app,
766
786
  project,
@@ -786,20 +806,25 @@ and ``server-group-members`` output for a given quota class."""
786
806
  info.update(volume_quota_info)
787
807
  info.update(network_quota_info)
788
808
 
789
- # Map the internal quota names to the external ones
790
- # COMPUTE_QUOTAS and NETWORK_QUOTAS share floating-ips,
791
- # secgroup-rules and secgroups as dict value, so when
792
- # neutron is enabled, quotas of these three resources
793
- # in nova will be replaced by neutron's.
794
- for k, v in itertools.chain(
795
- COMPUTE_QUOTAS.items(),
796
- NOVA_NETWORK_QUOTAS.items(),
797
- VOLUME_QUOTAS.items(),
798
- NETWORK_QUOTAS.items(),
799
- ):
800
- if not k == v and info.get(k) is not None:
801
- info[v] = info[k]
802
- info.pop(k)
809
+ def _normalize_names(section: dict) -> None:
810
+ # Map the internal quota names to the external ones
811
+ # COMPUTE_QUOTAS and NETWORK_QUOTAS share floating-ips,
812
+ # secgroup-rules and secgroups as dict value, so when
813
+ # neutron is enabled, quotas of these three resources
814
+ # in nova will be replaced by neutron's.
815
+ for k, v in itertools.chain(
816
+ COMPUTE_QUOTAS.items(),
817
+ NOVA_NETWORK_QUOTAS.items(),
818
+ VOLUME_QUOTAS.items(),
819
+ NETWORK_QUOTAS.items(),
820
+ ):
821
+ if not k == v and section.get(k) is not None:
822
+ section[v] = section.pop(k)
823
+
824
+ _normalize_names(info)
825
+ if parsed_args.usage:
826
+ _normalize_names(info["reservation"])
827
+ _normalize_names(info["usage"])
803
828
 
804
829
  # Remove the 'id' field since it's not very useful
805
830
  if 'id' in info:
@@ -906,12 +931,18 @@ class DeleteQuota(command.Command):
906
931
  )
907
932
 
908
933
  # compute quotas
909
- if parsed_args.service in {'all', 'compute'}:
934
+ if parsed_args.service == 'compute' or (
935
+ parsed_args.service == 'all'
936
+ and self.app.client_manager.is_compute_endpoint_enabled()
937
+ ):
910
938
  compute_client = self.app.client_manager.compute
911
939
  compute_client.revert_quota_set(project.id)
912
940
 
913
941
  # volume quotas
914
- if parsed_args.service in {'all', 'volume'}:
942
+ if parsed_args.service == 'volume' or (
943
+ parsed_args.service == 'all'
944
+ and self.app.client_manager.is_volume_endpoint_enabled()
945
+ ):
915
946
  volume_client = self.app.client_manager.sdk_connection.volume
916
947
  volume_client.revert_quota_set(project.id)
917
948
 
@@ -14,8 +14,7 @@
14
14
 
15
15
  """Versions Action Implementation"""
16
16
 
17
- from osc_lib.command import command
18
-
17
+ from openstackclient import command
19
18
  from openstackclient.i18n import _
20
19
 
21
20
 
@@ -18,10 +18,10 @@
18
18
  import logging
19
19
 
20
20
  from openstack import exceptions as sdk_exceptions
21
- from osc_lib.command import command
22
21
  from osc_lib import exceptions
23
22
  from osc_lib import utils
24
23
 
24
+ from openstackclient import command
25
25
  from openstackclient.i18n import _
26
26
 
27
27
 
@@ -19,20 +19,21 @@
19
19
  import logging
20
20
  import typing as ty
21
21
 
22
+ from cliff import columns
22
23
  from openstack import utils as sdk_utils
23
24
  from osc_lib.cli import format_columns
24
25
  from osc_lib.cli import parseractions
25
- from osc_lib.command import command
26
26
  from osc_lib import exceptions
27
27
  from osc_lib import utils
28
28
 
29
+ from openstackclient import command
29
30
  from openstackclient.i18n import _
30
31
 
31
32
 
32
33
  LOG = logging.getLogger(__name__)
33
34
 
34
35
 
35
- _aggregate_formatters = {
36
+ _aggregate_formatters: dict[str, type[columns.FormattableColumn[ty.Any]]] = {
36
37
  'Hosts': format_columns.ListColumn,
37
38
  'Metadata': format_columns.DictColumn,
38
39
  'hosts': format_columns.ListColumn,
@@ -438,15 +439,15 @@ class CacheImageForAggregate(command.Command):
438
439
  )
439
440
  raise exceptions.CommandError(msg)
440
441
 
442
+ image_client = self.app.client_manager.sdk_connection.image
443
+
441
444
  aggregate = compute_client.find_aggregate(
442
445
  parsed_args.aggregate, ignore_missing=False
443
446
  )
444
447
 
445
448
  images = []
446
449
  for img in parsed_args.image:
447
- image = self.app.client_manager.sdk_connection.image.find_image(
448
- img, ignore_missing=False
449
- )
450
+ image = image_client.find_image(img, ignore_missing=False)
450
451
  images.append(image.id)
451
452
 
452
453
  compute_client.aggregate_precache_images(aggregate.id, images)
@@ -16,9 +16,9 @@
16
16
  """Compute v2 Console action implementations"""
17
17
 
18
18
  from osc_lib.cli import parseractions
19
- from osc_lib.command import command
20
19
  from osc_lib import utils
21
20
 
21
+ from openstackclient import command
22
22
  from openstackclient.i18n import _
23
23
 
24
24
 
@@ -64,13 +64,15 @@ class ShowConsoleLog(command.Command):
64
64
  output = compute_client.get_server_console_output(
65
65
  server.id, length=parsed_args.lines
66
66
  )
67
- data = None
67
+ data: str | None = None
68
68
  if output:
69
69
  data = output.get('output', None)
70
70
 
71
71
  if data and data[-1] != '\n':
72
72
  data += '\n'
73
- self.app.stdout.write(data)
73
+
74
+ if data:
75
+ self.app.stdout.write(data)
74
76
 
75
77
 
76
78
  class ShowConsoleURL(command.ShowOne):
@@ -13,9 +13,9 @@
13
13
 
14
14
  """Compute v2 Console auth token implementations."""
15
15
 
16
- from osc_lib.command import command
17
16
  from osc_lib import utils
18
17
 
18
+ from openstackclient import command
19
19
  from openstackclient.i18n import _
20
20
 
21
21
 
@@ -21,10 +21,10 @@ from openstack import exceptions as sdk_exceptions
21
21
  from openstack import utils as sdk_utils
22
22
  from osc_lib.cli import format_columns
23
23
  from osc_lib.cli import parseractions
24
- from osc_lib.command import command
25
24
  from osc_lib import exceptions
26
25
  from osc_lib import utils
27
26
 
27
+ from openstackclient import command
28
28
  from openstackclient.common import pagination
29
29
  from openstackclient.i18n import _
30
30
  from openstackclient.identity import common as identity_common
@@ -16,9 +16,9 @@
16
16
  """Host action implementations"""
17
17
 
18
18
  from openstack import exceptions as sdk_exceptions
19
- from osc_lib.command import command
20
19
  from osc_lib import utils
21
20
 
21
+ from openstackclient import command
22
22
  from openstackclient.i18n import _
23
23
 
24
24
 
@@ -21,10 +21,10 @@ import re
21
21
  from openstack import exceptions as sdk_exceptions
22
22
  from openstack import utils as sdk_utils
23
23
  from osc_lib.cli import format_columns
24
- from osc_lib.command import command
25
24
  from osc_lib import exceptions
26
25
  from osc_lib import utils
27
26
 
27
+ from openstackclient import command
28
28
  from openstackclient.common import pagination
29
29
  from openstackclient.i18n import _
30
30
 
@@ -13,9 +13,9 @@
13
13
 
14
14
  """Hypervisor Stats action implementations"""
15
15
 
16
- from osc_lib.command import command
17
16
  from osc_lib import utils
18
17
 
18
+ from openstackclient import command
19
19
  from openstackclient.i18n import _
20
20
 
21
21
 
@@ -22,10 +22,10 @@ import os
22
22
  from cryptography.hazmat.primitives.asymmetric import ed25519
23
23
  from cryptography.hazmat.primitives import serialization
24
24
  from openstack import utils as sdk_utils
25
- from osc_lib.command import command
26
25
  from osc_lib import exceptions
27
26
  from osc_lib import utils
28
27
 
28
+ from openstackclient import command
29
29
  from openstackclient.common import pagination
30
30
  from openstackclient.i18n import _
31
31
  from openstackclient.identity import common as identity_common