Skip to content

Commit a5e79d5

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Defer client imports"
2 parents 98604ab + f43c1f7 commit a5e79d5

5 files changed

Lines changed: 73 additions & 39 deletions

File tree

openstackclient/api/auth.py

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,37 +27,57 @@
2727

2828
LOG = logging.getLogger(__name__)
2929

30-
3130
# Initialize the list of Authentication plugins early in order
3231
# to get the command-line options
33-
PLUGIN_LIST = stevedore.ExtensionManager(
34-
base.PLUGIN_NAMESPACE,
35-
invoke_on_load=False,
36-
propagate_map_exceptions=True,
37-
)
32+
PLUGIN_LIST = None
3833

39-
# Get the command line options so the help action has them available
34+
# List of plugin command line options
4035
OPTIONS_LIST = {}
41-
for plugin in PLUGIN_LIST:
42-
for o in plugin.plugin.get_options():
43-
os_name = o.dest.lower().replace('_', '-')
44-
os_env_name = 'OS_' + os_name.upper().replace('-', '_')
45-
OPTIONS_LIST.setdefault(os_name, {'env': os_env_name, 'help': ''})
46-
# TODO(mhu) simplistic approach, would be better to only add
47-
# help texts if they vary from one auth plugin to another
48-
# also the text rendering is ugly in the CLI ...
49-
OPTIONS_LIST[os_name]['help'] += 'With %s: %s\n' % (
50-
plugin.name,
51-
o.help,
36+
37+
38+
def get_plugin_list():
39+
"""Gather plugin list and cache it"""
40+
41+
global PLUGIN_LIST
42+
43+
if PLUGIN_LIST is None:
44+
PLUGIN_LIST = stevedore.ExtensionManager(
45+
base.PLUGIN_NAMESPACE,
46+
invoke_on_load=False,
47+
propagate_map_exceptions=True,
5248
)
49+
return PLUGIN_LIST
50+
51+
52+
def get_options_list():
53+
"""Gather plugin options so the help action has them available"""
54+
55+
global OPTIONS_LIST
56+
57+
if not OPTIONS_LIST:
58+
for plugin in get_plugin_list():
59+
for o in plugin.plugin.get_options():
60+
os_name = o.dest.lower().replace('_', '-')
61+
os_env_name = 'OS_' + os_name.upper().replace('-', '_')
62+
OPTIONS_LIST.setdefault(
63+
os_name, {'env': os_env_name, 'help': ''},
64+
)
65+
# TODO(mhu) simplistic approach, would be better to only add
66+
# help texts if they vary from one auth plugin to another
67+
# also the text rendering is ugly in the CLI ...
68+
OPTIONS_LIST[os_name]['help'] += 'With %s: %s\n' % (
69+
plugin.name,
70+
o.help,
71+
)
72+
return OPTIONS_LIST
5373

5474

5575
def select_auth_plugin(options):
5676
"""Pick an auth plugin based on --os-auth-type or other options"""
5777

5878
auth_plugin_name = None
5979

60-
if options.os_auth_type in [plugin.name for plugin in PLUGIN_LIST]:
80+
if options.os_auth_type in [plugin.name for plugin in get_plugin_list()]:
6181
# A direct plugin name was given, use it
6282
return options.os_auth_type
6383

@@ -113,7 +133,7 @@ def build_auth_params(auth_plugin_name, cmd_options):
113133
else:
114134
LOG.debug('no auth_type')
115135
# delay the plugin choice, grab every option
116-
plugin_options = set([o.replace('-', '_') for o in OPTIONS_LIST])
136+
plugin_options = set([o.replace('-', '_') for o in get_options_list()])
117137
for option in plugin_options:
118138
option_name = 'os_' + option
119139
LOG.debug('fetching option %s' % option_name)
@@ -147,7 +167,7 @@ def build_auth_plugins_option_parser(parser):
147167
authentication plugin.
148168
149169
"""
150-
available_plugins = [plugin.name for plugin in PLUGIN_LIST]
170+
available_plugins = [plugin.name for plugin in get_plugin_list()]
151171
parser.add_argument(
152172
'--os-auth-type',
153173
metavar='<auth-type>',
@@ -169,7 +189,7 @@ def build_auth_plugins_option_parser(parser):
169189
default=utils.env('OS_TENANT_ID')
170190
),
171191
}
172-
for o in OPTIONS_LIST:
192+
for o in get_options_list():
173193
# remove allusion to tenants from v2.0 API
174194
if 'tenant' not in o:
175195
parser.add_argument(

openstackclient/compute/client.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,6 @@
1515

1616
import logging
1717

18-
from novaclient import client as nova_client
19-
from novaclient import extension
20-
21-
try:
22-
from novaclient.v2.contrib import list_extensions
23-
except ImportError:
24-
from novaclient.v1_1.contrib import list_extensions
25-
2618
from openstackclient.common import utils
2719

2820
LOG = logging.getLogger(__name__)
@@ -37,6 +29,15 @@
3729

3830
def make_client(instance):
3931
"""Returns a compute service client."""
32+
33+
# Defer client imports until we actually need them
34+
from novaclient import client as nova_client
35+
from novaclient import extension
36+
try:
37+
from novaclient.v2.contrib import list_extensions
38+
except ImportError:
39+
from novaclient.v1_1.contrib import list_extensions
40+
4041
compute_client = nova_client.get_client_class(
4142
instance._api_version[API_NAME],
4243
)

openstackclient/tests/common/test_clientmanager.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@
3434
SERVICE_CATALOG = service_catalog.ServiceCatalogV2(AUTH_REF)
3535

3636

37+
# This is deferred in api.auth but we need it here...
38+
auth.get_options_list()
39+
40+
3741
class Container(object):
3842
attr = clientmanager.ClientCache(lambda x: object())
3943

openstackclient/tests/volume/test_find_resource.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@
2424
from openstackclient.volume import client # noqa
2525

2626

27+
# Monkey patch for v1 cinderclient
28+
# NOTE(dtroyer): Do here because openstackclient.volume.client
29+
# doesn't do it until the client object is created now.
30+
volumes.Volume.NAME_ATTR = 'display_name'
31+
volume_snapshots.Snapshot.NAME_ATTR = 'display_name'
32+
33+
2734
ID = '1after909'
2835
NAME = 'PhilSpector'
2936

openstackclient/volume/client.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,8 @@
1515

1616
import logging
1717

18-
from cinderclient import extension
19-
from cinderclient.v1.contrib import list_extensions
20-
from cinderclient.v1 import volume_snapshots
21-
from cinderclient.v1 import volumes
22-
2318
from openstackclient.common import utils
2419

25-
# Monkey patch for v1 cinderclient
26-
volumes.Volume.NAME_ATTR = 'display_name'
27-
volume_snapshots.Snapshot.NAME_ATTR = 'display_name'
28-
2920
LOG = logging.getLogger(__name__)
3021

3122
DEFAULT_VOLUME_API_VERSION = '1'
@@ -38,6 +29,17 @@
3829

3930
def make_client(instance):
4031
"""Returns a volume service client."""
32+
33+
# Defer client imports until we actually need them
34+
from cinderclient import extension
35+
from cinderclient.v1.contrib import list_extensions
36+
from cinderclient.v1 import volume_snapshots
37+
from cinderclient.v1 import volumes
38+
39+
# Monkey patch for v1 cinderclient
40+
volumes.Volume.NAME_ATTR = 'display_name'
41+
volume_snapshots.Snapshot.NAME_ATTR = 'display_name'
42+
4143
volume_client = utils.get_client_class(
4244
API_NAME,
4345
instance._api_version[API_NAME],

0 commit comments

Comments
 (0)