1515
1616"""Manage access to the clients, including authenticating when needed."""
1717
18+ import argparse
19+ from collections .abc import Callable
1820import importlib
1921import logging
2022import sys
2123import typing as ty
2224
25+ from osc_lib .cli import client_config
2326from osc_lib import clientmanager
2427from osc_lib import shell
2528import stevedore
2629
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
2737
2838LOG = logging .getLogger (__name__ )
2939
@@ -40,6 +50,24 @@ class ClientManager(clientmanager.ClientManager):
4050 in osc-lib so we need to maintain a transition period.
4151 """
4252
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
70+
4371 def __init__ (
4472 self ,
4573 cli_options = None ,
@@ -75,6 +103,12 @@ def setup_auth(self):
75103 self ._auth_required
76104 and self ._cli_options ._openstack_config is not None
77105 ):
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+
78112 self ._cli_options ._openstack_config ._pw_callback = (
79113 shell .prompt_for_password
80114 )
@@ -101,6 +135,13 @@ def _fallback_load_auth_plugin(self, e):
101135 self ._cli_options .config ['auth_type' ] = self ._original_auth_type
102136 del self ._cli_options .config ['auth' ]['token' ]
103137 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+
104145 self ._cli_options ._auth = (
105146 self ._cli_options ._openstack_config .load_auth_plugin (
106147 self ._cli_options .config ,
@@ -138,11 +179,25 @@ def is_volume_endpoint_enabled(self, volume_client=None):
138179
139180# Plugin Support
140181
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+
141196
142197def _on_load_failure_callback (
143198 manager : stevedore .ExtensionManager ,
144199 ep : importlib .metadata .EntryPoint ,
145- err : Exception ,
200+ err : BaseException ,
146201) -> None :
147202 sys .stderr .write (
148203 f"WARNING: Failed to import plugin { ep .group } :{ ep .name } : { err } .\n "
@@ -152,6 +207,7 @@ def _on_load_failure_callback(
152207def get_plugin_modules (group ):
153208 """Find plugin entry points"""
154209 mod_list = []
210+ mgr : stevedore .ExtensionManager [PluginModule ]
155211 mgr = stevedore .ExtensionManager (
156212 group , on_load_failure_callback = _on_load_failure_callback
157213 )
@@ -164,8 +220,8 @@ def get_plugin_modules(group):
164220 module = importlib .import_module (module_name )
165221 except Exception as err :
166222 sys .stderr .write (
167- f"WARNING: Failed to import plugin { ep . group } : { ep . name } : "
168- f"{ err } .\n "
223+ f"WARNING: Failed to import plugin "
224+ f"{ ep . module_name } : { ep . name } : { err } .\n "
169225 )
170226 continue
171227
0 commit comments