Skip to content

Commit 17627c5

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Moving authentication from keystoneclient to keystoneauth"
2 parents a84a905 + 6ae0d2e commit 17627c5

18 files changed

Lines changed: 330 additions & 146 deletions

File tree

openstackclient/api/auth.py

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,12 @@
1616
import argparse
1717
import logging
1818

19-
import stevedore
20-
21-
from keystoneclient.auth import base
19+
from keystoneauth1.loading import base
2220

2321
from openstackclient.common import exceptions as exc
2422
from openstackclient.common import utils
2523
from openstackclient.i18n import _
2624

27-
2825
LOG = logging.getLogger(__name__)
2926

3027
# Initialize the list of Authentication plugins early in order
@@ -37,15 +34,10 @@
3734

3835
def get_plugin_list():
3936
"""Gather plugin list and cache it"""
40-
4137
global PLUGIN_LIST
4238

4339
if PLUGIN_LIST is None:
44-
PLUGIN_LIST = stevedore.ExtensionManager(
45-
base.PLUGIN_NAMESPACE,
46-
invoke_on_load=False,
47-
propagate_map_exceptions=True,
48-
)
40+
PLUGIN_LIST = base.get_available_plugin_names()
4941
return PLUGIN_LIST
5042

5143

@@ -55,8 +47,9 @@ def get_options_list():
5547
global OPTIONS_LIST
5648

5749
if not OPTIONS_LIST:
58-
for plugin in get_plugin_list():
59-
for o in plugin.plugin.get_options():
50+
for plugin_name in get_plugin_list():
51+
plugin_options = base.get_plugin_options(plugin_name)
52+
for o in plugin_options:
6053
os_name = o.dest.lower().replace('_', '-')
6154
os_env_name = 'OS_' + os_name.upper().replace('-', '_')
6255
OPTIONS_LIST.setdefault(
@@ -66,7 +59,7 @@ def get_options_list():
6659
# help texts if they vary from one auth plugin to another
6760
# also the text rendering is ugly in the CLI ...
6861
OPTIONS_LIST[os_name]['help'] += 'With %s: %s\n' % (
69-
plugin.name,
62+
plugin_name,
7063
o.help,
7164
)
7265
return OPTIONS_LIST
@@ -83,7 +76,7 @@ def select_auth_plugin(options):
8376
if options.auth.get('url') and options.auth.get('token'):
8477
# service token authentication
8578
auth_plugin_name = 'token_endpoint'
86-
elif options.auth_type in [plugin.name for plugin in PLUGIN_LIST]:
79+
elif options.auth_type in PLUGIN_LIST:
8780
# A direct plugin name was given, use it
8881
auth_plugin_name = options.auth_type
8982
elif options.auth.get('username'):
@@ -115,7 +108,7 @@ def build_auth_params(auth_plugin_name, cmd_options):
115108
auth_params = dict(cmd_options.auth)
116109
if auth_plugin_name:
117110
LOG.debug('auth_type: %s', auth_plugin_name)
118-
auth_plugin_class = base.get_plugin_class(auth_plugin_name)
111+
auth_plugin_loader = base.get_plugin_loader(auth_plugin_name)
119112
# grab tenant from project for v2.0 API compatibility
120113
if auth_plugin_name.startswith("v2"):
121114
if 'project_id' in auth_params:
@@ -127,12 +120,12 @@ def build_auth_params(auth_plugin_name, cmd_options):
127120
else:
128121
LOG.debug('no auth_type')
129122
# delay the plugin choice, grab every option
130-
auth_plugin_class = None
123+
auth_plugin_loader = None
131124
plugin_options = set([o.replace('-', '_') for o in get_options_list()])
132125
for option in plugin_options:
133126
LOG.debug('fetching option %s', option)
134127
auth_params[option] = getattr(cmd_options.auth, option, None)
135-
return (auth_plugin_class, auth_params)
128+
return (auth_plugin_loader, auth_params)
136129

137130

138131
def check_valid_auth_options(options, auth_plugin_name, required_scope=True):
@@ -188,7 +181,7 @@ def build_auth_plugins_option_parser(parser):
188181
authentication plugin.
189182
190183
"""
191-
available_plugins = [plugin.name for plugin in get_plugin_list()]
184+
available_plugins = list(get_plugin_list())
192185
parser.add_argument(
193186
'--os-auth-type',
194187
metavar='<auth-type>',

openstackclient/api/auth_plugin.py

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@
1818
from oslo_config import cfg
1919
from six.moves.urllib import parse as urlparse
2020

21-
from keystoneclient.auth.identity.generic import password as ksc_password
22-
from keystoneclient.auth import token_endpoint
21+
from keystoneauth1.loading._plugins import admin_token as token_endpoint
22+
from keystoneauth1.loading._plugins.identity import generic as ksa_password
2323

2424
LOG = logging.getLogger(__name__)
2525

2626

27-
class TokenEndpoint(token_endpoint.Token):
27+
class TokenEndpoint(token_endpoint.AdminToken):
2828
"""Auth plugin to handle traditional token/endpoint usage
2929
3030
Implements the methods required to handle token authentication
@@ -36,20 +36,15 @@ class TokenEndpoint(token_endpoint.Token):
3636
is for bootstrapping the Keystone database.
3737
"""
3838

39-
def __init__(self, url, token, **kwargs):
39+
def load_from_options(self, url, token):
4040
"""A plugin for static authentication with an existing token
4141
4242
:param string url: Service endpoint
4343
:param string token: Existing token
4444
"""
45-
super(TokenEndpoint, self).__init__(endpoint=url,
46-
token=token)
45+
return super(TokenEndpoint, self).load_from_options(endpoint=url,
46+
token=token)
4747

48-
def get_auth_ref(self, session, **kwargs):
49-
# Stub this method for compatibility
50-
return None
51-
52-
@classmethod
5348
def get_options(self):
5449
options = super(TokenEndpoint, self).get_options()
5550

@@ -65,7 +60,7 @@ def get_options(self):
6560
return options
6661

6762

68-
class OSCGenericPassword(ksc_password.Password):
63+
class OSCGenericPassword(ksa_password.Password):
6964
"""Auth plugin hack to work around broken Keystone configurations
7065
7166
The default Keystone configuration uses http://localhost:xxxx in

openstackclient/common/clientmanager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ def get_endpoint_for_service_type(self, service_type, region_name=None,
269269
endpoint = self.auth_ref.service_catalog.url_for(
270270
service_type=service_type,
271271
region_name=region_name,
272-
endpoint_type=interface,
272+
interface=interface,
273273
)
274274
else:
275275
# Get the passed endpoint directly from the auth plugin

openstackclient/identity/v2_0/catalog.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import six
1717

1818
from openstackclient.common import command
19+
from openstackclient.common import exceptions
1920
from openstackclient.common import utils
2021
from openstackclient.i18n import _
2122

@@ -41,13 +42,14 @@ class ListCatalog(command.Lister):
4142

4243
def take_action(self, parsed_args):
4344

44-
# This is ugly because if auth hasn't happened yet we need
45-
# to trigger it here.
46-
sc = self.app.client_manager.session.auth.get_auth_ref(
47-
self.app.client_manager.session,
48-
).service_catalog
45+
# Trigger auth if it has not happened yet
46+
auth_ref = self.app.client_manager.auth_ref
47+
if not auth_ref:
48+
raise exceptions.AuthorizationFailure(
49+
"Only an authorized user may issue a new token."
50+
)
4951

50-
data = sc.get_data()
52+
data = auth_ref.service_catalog.catalog
5153
columns = ('Name', 'Type', 'Endpoints')
5254
return (columns,
5355
(utils.get_dict_properties(
@@ -72,14 +74,15 @@ def get_parser(self, prog_name):
7274

7375
def take_action(self, parsed_args):
7476

75-
# This is ugly because if auth hasn't happened yet we need
76-
# to trigger it here.
77-
sc = self.app.client_manager.session.auth.get_auth_ref(
78-
self.app.client_manager.session,
79-
).service_catalog
77+
# Trigger auth if it has not happened yet
78+
auth_ref = self.app.client_manager.auth_ref
79+
if not auth_ref:
80+
raise exceptions.AuthorizationFailure(
81+
"Only an authorized user may issue a new token."
82+
)
8083

8184
data = None
82-
for service in sc.get_data():
85+
for service in auth_ref.service_catalog.catalog:
8386
if (service.get('name') == parsed_args.service or
8487
service.get('type') == parsed_args.service):
8588
data = service
@@ -91,6 +94,6 @@ def take_action(self, parsed_args):
9194
if not data:
9295
self.app.log.error(_('service %s not found\n') %
9396
parsed_args.service)
94-
return ([], [])
97+
return ((), ())
9598

9699
return zip(*sorted(six.iteritems(data)))

openstackclient/identity/v2_0/role.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -231,18 +231,19 @@ def take_action(self, parsed_args):
231231
# Project and user are required, if not included in command args
232232
# default to the values used for authentication. For token-flow
233233
# authentication they must be included on the command line.
234+
if (not parsed_args.project and
235+
self.app.client_manager.auth_ref.project_id):
236+
parsed_args.project = auth_ref.project_id
234237
if not parsed_args.project:
235-
if self.app.client_manager.auth_ref:
236-
parsed_args.project = auth_ref.project_id
237-
else:
238-
msg = _("Project must be specified")
239-
raise exceptions.CommandError(msg)
238+
msg = _("Project must be specified")
239+
raise exceptions.CommandError(msg)
240+
241+
if (not parsed_args.user and
242+
self.app.client_manager.auth_ref.user_id):
243+
parsed_args.user = auth_ref.user_id
240244
if not parsed_args.user:
241-
if self.app.client_manager.auth_ref:
242-
parsed_args.user = auth_ref.user_id
243-
else:
244-
msg = _("User must be specified")
245-
raise exceptions.CommandError(msg)
245+
msg = _("User must be specified")
246+
raise exceptions.CommandError(msg)
246247

247248
project = utils.find_resource(
248249
identity_client.tenants,

openstackclient/identity/v2_0/token.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import six
1919

2020
from openstackclient.common import command
21+
from openstackclient.common import exceptions
2122
from openstackclient.i18n import _
2223

2324

@@ -32,11 +33,21 @@ def get_parser(self, prog_name):
3233
return parser
3334

3435
def take_action(self, parsed_args):
36+
auth_ref = self.app.client_manager.auth_ref
37+
if not auth_ref:
38+
raise exceptions.AuthorizationFailure(
39+
"Only an authorized user may issue a new token.")
3540

36-
token = self.app.client_manager.auth_ref.service_catalog.get_token()
37-
if 'tenant_id' in token:
38-
token['project_id'] = token.pop('tenant_id')
39-
return zip(*sorted(six.iteritems(token)))
41+
data = {}
42+
if auth_ref.auth_token:
43+
data['id'] = auth_ref.auth_token
44+
if auth_ref.expires:
45+
data['expires'] = auth_ref.expires
46+
if auth_ref.project_id:
47+
data['project_id'] = auth_ref.project_id
48+
if auth_ref.user_id:
49+
data['user_id'] = auth_ref.user_id
50+
return zip(*sorted(six.iteritems(data)))
4051

4152

4253
class RevokeToken(command.Command):

openstackclient/identity/v3/catalog.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import six
1717

1818
from openstackclient.common import command
19+
from openstackclient.common import exceptions
1920
from openstackclient.common import utils
2021
from openstackclient.i18n import _
2122

@@ -36,13 +37,14 @@ class ListCatalog(command.Lister):
3637

3738
def take_action(self, parsed_args):
3839

39-
# This is ugly because if auth hasn't happened yet we need
40-
# to trigger it here.
41-
sc = self.app.client_manager.session.auth.get_auth_ref(
42-
self.app.client_manager.session,
43-
).service_catalog
40+
# Trigger auth if it has not happened yet
41+
auth_ref = self.app.client_manager.auth_ref
42+
if not auth_ref:
43+
raise exceptions.AuthorizationFailure(
44+
"Only an authorized user may issue a new token."
45+
)
4446

45-
data = sc.get_data()
47+
data = auth_ref.service_catalog.catalog
4648
columns = ('Name', 'Type', 'Endpoints')
4749
return (columns,
4850
(utils.get_dict_properties(
@@ -67,14 +69,15 @@ def get_parser(self, prog_name):
6769

6870
def take_action(self, parsed_args):
6971

70-
# This is ugly because if auth hasn't happened yet we need
71-
# to trigger it here.
72-
sc = self.app.client_manager.session.auth.get_auth_ref(
73-
self.app.client_manager.session,
74-
).service_catalog
72+
# Trigger auth if it has not happened yet
73+
auth_ref = self.app.client_manager.auth_ref
74+
if not auth_ref:
75+
raise exceptions.AuthorizationFailure(
76+
"Only an authorized user may issue a new token."
77+
)
7578

7679
data = None
77-
for service in sc.get_data():
80+
for service in auth_ref.service_catalog.catalog:
7881
if (service.get('name') == parsed_args.service or
7982
service.get('type') == parsed_args.service):
8083
data = dict(service)
@@ -86,6 +89,6 @@ def take_action(self, parsed_args):
8689
if not data:
8790
self.app.log.error(_('service %s not found\n') %
8891
parsed_args.service)
89-
return ([], [])
92+
return ((), ())
9093

9194
return zip(*sorted(six.iteritems(data)))

openstackclient/identity/v3/token.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,23 @@ def get_parser(self, prog_name):
174174
return parser
175175

176176
def take_action(self, parsed_args):
177-
if not self.app.client_manager.auth_ref:
177+
auth_ref = self.app.client_manager.auth_ref
178+
if not auth_ref:
178179
raise exceptions.AuthorizationFailure(
179180
_("Only an authorized user may issue a new token."))
180-
token = self.app.client_manager.auth_ref.service_catalog.get_token()
181-
if 'tenant_id' in token:
182-
token['project_id'] = token.pop('tenant_id')
183-
return zip(*sorted(six.iteritems(token)))
181+
182+
data = {}
183+
if auth_ref.auth_token:
184+
data['id'] = auth_ref.auth_token
185+
if auth_ref.expires:
186+
data['expires'] = auth_ref.expires
187+
if auth_ref.project_id:
188+
data['project_id'] = auth_ref.project_id
189+
if auth_ref.user_id:
190+
data['user_id'] = auth_ref.user_id
191+
if auth_ref.domain_id:
192+
data['domain_id'] = auth_ref.domain_id
193+
return zip(*sorted(six.iteritems(data)))
184194

185195

186196
class RevokeToken(command.Command):

0 commit comments

Comments
 (0)