diff --git a/openstackclient/api/auth.py b/openstackclient/api/auth.py index f6e99cdcf0..e19c6b7931 100644 --- a/openstackclient/api/auth.py +++ b/openstackclient/api/auth.py @@ -36,8 +36,6 @@ PLUGIN_LIST = stevedore.ExtensionManager( invoke_on_load=False, propagate_map_exceptions=True, ) -# TODO(dtroyer): add some method to list the plugins for the -# --os_auth_plugin option # Get the command line options so the help action has them available OPTIONS_LIST = {} @@ -56,50 +54,53 @@ for plugin in PLUGIN_LIST: def select_auth_plugin(options): - """If no auth plugin was specified, pick one based on other options""" + """Pick an auth plugin based on --os-auth-type or other options""" + + auth_plugin_name = None + + if options.os_auth_type in [plugin.name for plugin in PLUGIN_LIST]: + # A direct plugin name was given, use it + return options.os_auth_type - auth_plugin = None if options.os_url and options.os_token: # service token authentication - auth_plugin = 'token_endpoint' + auth_plugin_name = 'token_endpoint' elif options.os_username: if options.os_identity_api_version == '3': - auth_plugin = 'v3password' + auth_plugin_name = 'v3password' elif options.os_identity_api_version == '2.0': - auth_plugin = 'v2password' + auth_plugin_name = 'v2password' else: # let keystoneclient figure it out itself - auth_plugin = 'password' + auth_plugin_name = 'password' elif options.os_token: if options.os_identity_api_version == '3': - auth_plugin = 'v3token' + auth_plugin_name = 'v3token' elif options.os_identity_api_version == '2.0': - auth_plugin = 'v2token' + auth_plugin_name = 'v2token' else: # let keystoneclient figure it out itself - auth_plugin = 'token' + auth_plugin_name = 'token' else: raise exc.CommandError( - "Could not figure out which authentication method " - "to use, please set --os-auth-plugin" + "Authentication type must be selected with --os-auth-type" ) - LOG.debug("No auth plugin selected, picking %s from other " - "options" % auth_plugin) - return auth_plugin + LOG.debug("Auth plugin %s selected" % auth_plugin_name) + return auth_plugin_name -def build_auth_params(cmd_options): +def build_auth_params(auth_plugin_name, cmd_options): auth_params = {} - if cmd_options.os_auth_plugin: - LOG.debug('auth_plugin: %s', cmd_options.os_auth_plugin) - auth_plugin = base.get_plugin_class(cmd_options.os_auth_plugin) - plugin_options = auth_plugin.get_options() + if auth_plugin_name: + LOG.debug('auth_type: %s', auth_plugin_name) + auth_plugin_class = base.get_plugin_class(auth_plugin_name) + plugin_options = auth_plugin_class.get_options() for option in plugin_options: option_name = 'os_' + option.dest LOG.debug('fetching option %s' % option_name) auth_params[option.dest] = getattr(cmd_options, option_name, None) # grab tenant from project for v2.0 API compatibility - if cmd_options.os_auth_plugin.startswith("v2"): + if auth_plugin_name.startswith("v2"): auth_params['tenant_id'] = getattr( cmd_options, 'os_project_id', @@ -111,14 +112,14 @@ def build_auth_params(cmd_options): None, ) else: - LOG.debug('no auth_plugin') + LOG.debug('no auth_type') # delay the plugin choice, grab every option plugin_options = set([o.replace('-', '_') for o in OPTIONS_LIST]) for option in plugin_options: option_name = 'os_' + option LOG.debug('fetching option %s' % option_name) auth_params[option] = getattr(cmd_options, option_name, None) - return auth_params + return (auth_plugin_class, auth_params) def build_auth_plugins_option_parser(parser): @@ -130,15 +131,12 @@ def build_auth_plugins_option_parser(parser): """ available_plugins = [plugin.name for plugin in PLUGIN_LIST] parser.add_argument( - '--os-auth-plugin', - metavar='', - default=utils.env('OS_AUTH_PLUGIN'), - help='The authentication method to use. If this option is not set, ' - 'openstackclient will attempt to guess the authentication method ' - 'to use based on the other options. If this option is set, ' - 'the --os-identity-api-version argument must be consistent ' - 'with the version of the method.\nAvailable methods are ' + - ', '.join(available_plugins), + '--os-auth-type', + metavar='', + default=utils.env('OS_AUTH_TYPE'), + help='Select an auhentication type. Available types: ' + + ', '.join(available_plugins) + + '. Default: selected based on --os-username/--os-token', choices=available_plugins ) # make sur we catch old v2.0 env values diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py index ae38f16077..adec842f13 100644 --- a/openstackclient/common/clientmanager.py +++ b/openstackclient/common/clientmanager.py @@ -19,7 +19,6 @@ import logging import pkg_resources import sys -from keystoneclient.auth import base from keystoneclient import session import requests @@ -78,20 +77,22 @@ class ClientManager(object): returns a string containig the password """ - # If no plugin is named by the user, select one based on + # If no auth type is named by the user, select one based on # the supplied options - if not auth_options.os_auth_plugin: - auth_options.os_auth_plugin = auth.select_auth_plugin(auth_options) - self._auth_plugin = auth_options.os_auth_plugin + self.auth_plugin_name = auth.select_auth_plugin(auth_options) # Horrible hack alert...must handle prompt for null password if # password auth is requested. - if (self._auth_plugin.endswith('password') and + if (self.auth_plugin_name.endswith('password') and not auth_options.os_password): auth_options.os_password = pw_func() + (auth_plugin, self._auth_params) = auth.build_auth_params( + self.auth_plugin_name, + auth_options, + ) + self._url = auth_options.os_url - self._auth_params = auth.build_auth_params(auth_options) self._region_name = auth_options.os_region_name self._api_version = api_version self._auth_ref = None @@ -117,8 +118,7 @@ class ClientManager(object): root_logger = logging.getLogger('') LOG.setLevel(root_logger.getEffectiveLevel()) - LOG.debug('Using auth plugin: %s' % self._auth_plugin) - auth_plugin = base.get_plugin_class(self._auth_plugin) + LOG.debug('Using auth plugin: %s' % self.auth_plugin_name) self.auth = auth_plugin.load_from_options(**self._auth_params) # needed by SAML authentication request_session = requests.session() diff --git a/openstackclient/tests/common/test_clientmanager.py b/openstackclient/tests/common/test_clientmanager.py index a7b13c6c9c..8c27e5621d 100644 --- a/openstackclient/tests/common/test_clientmanager.py +++ b/openstackclient/tests/common/test_clientmanager.py @@ -44,7 +44,7 @@ class FakeOptions(object): def __init__(self, **kwargs): for option in auth.OPTIONS_LIST: setattr(self, 'os_' + option.replace('-', '_'), None) - self.os_auth_plugin = None + self.os_auth_type = None self.os_identity_api_version = '2.0' self.timing = None self.os_region_name = None @@ -81,7 +81,7 @@ class TestClientManager(utils.TestCase): client_manager = clientmanager.ClientManager( auth_options=FakeOptions(os_token=fakes.AUTH_TOKEN, os_url=fakes.AUTH_URL, - os_auth_plugin='token_endpoint'), + os_auth_type='token_endpoint'), api_version=API_VERSION, verify=True ) @@ -105,7 +105,7 @@ class TestClientManager(utils.TestCase): client_manager = clientmanager.ClientManager( auth_options=FakeOptions(os_token=fakes.AUTH_TOKEN, os_auth_url=fakes.AUTH_URL, - os_auth_plugin='v2token'), + os_auth_type='v2token'), api_version=API_VERSION, verify=True ) @@ -183,7 +183,7 @@ class TestClientManager(utils.TestCase): auth_options=FakeOptions(os_auth_url=fakes.AUTH_URL, os_username=fakes.USERNAME, os_password=fakes.PASSWORD, - os_auth_plugin='v2password'), + os_auth_type='v2password'), api_version=API_VERSION, verify='cafile', ) @@ -192,8 +192,8 @@ class TestClientManager(utils.TestCase): self.assertTrue(client_manager._verify) self.assertEqual('cafile', client_manager._cacert) - def _select_auth_plugin(self, auth_params, api_version, auth_plugin): - auth_params['os_auth_plugin'] = auth_plugin + def _select_auth_plugin(self, auth_params, api_version, auth_plugin_name): + auth_params['os_auth_type'] = auth_plugin_name auth_params['os_identity_api_version'] = api_version client_manager = clientmanager.ClientManager( auth_options=FakeOptions(**auth_params), @@ -201,8 +201,8 @@ class TestClientManager(utils.TestCase): verify=True ) self.assertEqual( - auth_plugin, - client_manager._auth_plugin, + auth_plugin_name, + client_manager.auth_plugin_name, ) def test_client_manager_select_auth_plugin(self): diff --git a/openstackclient/tests/test_shell.py b/openstackclient/tests/test_shell.py index b0c1452ef9..837a48afd7 100644 --- a/openstackclient/tests/test_shell.py +++ b/openstackclient/tests/test_shell.py @@ -108,8 +108,8 @@ class TestShell(utils.TestCase): default_args["region_name"]) self.assertEqual(_shell.options.os_trust_id, default_args["trust_id"]) - self.assertEqual(_shell.options.os_auth_plugin, - default_args['auth_plugin']) + self.assertEqual(_shell.options.os_auth_type, + default_args['auth_type']) def _assert_token_auth(self, cmd_options, default_args): with mock.patch("openstackclient.shell.OpenStackShell.initialize_app", @@ -190,7 +190,7 @@ class TestShellPasswordAuth(TestShell): "password": "", "region_name": "", "trust_id": "", - "auth_plugin": "", + "auth_type": "", } self._assert_password_auth(flag, kwargs) @@ -210,7 +210,7 @@ class TestShellPasswordAuth(TestShell): "password": "", "region_name": "", "trust_id": "", - "auth_plugin": "", + "auth_type": "", } self._assert_password_auth(flag, kwargs) @@ -230,7 +230,7 @@ class TestShellPasswordAuth(TestShell): "password": "", "region_name": "", "trust_id": "", - "auth_plugin": "", + "auth_type": "", } self._assert_password_auth(flag, kwargs) @@ -250,7 +250,7 @@ class TestShellPasswordAuth(TestShell): "password": "", "region_name": "", "trust_id": "", - "auth_plugin": "", + "auth_type": "", } self._assert_password_auth(flag, kwargs) @@ -270,7 +270,7 @@ class TestShellPasswordAuth(TestShell): "password": "", "region_name": "", "trust_id": "", - "auth_plugin": "", + "auth_type": "", } self._assert_password_auth(flag, kwargs) @@ -290,7 +290,7 @@ class TestShellPasswordAuth(TestShell): "password": "", "region_name": "", "trust_id": "", - "auth_plugin": "", + "auth_type": "", } self._assert_password_auth(flag, kwargs) @@ -310,7 +310,7 @@ class TestShellPasswordAuth(TestShell): "password": "", "region_name": "", "trust_id": "", - "auth_plugin": "", + "auth_type": "", } self._assert_password_auth(flag, kwargs) @@ -330,7 +330,7 @@ class TestShellPasswordAuth(TestShell): "password": "", "region_name": "", "trust_id": "", - "auth_plugin": "", + "auth_type": "", } self._assert_password_auth(flag, kwargs) @@ -350,7 +350,7 @@ class TestShellPasswordAuth(TestShell): "password": "", "region_name": "", "trust_id": "", - "auth_plugin": "", + "auth_type": "", } self._assert_password_auth(flag, kwargs) @@ -370,7 +370,7 @@ class TestShellPasswordAuth(TestShell): "password": "", "region_name": "", "trust_id": "", - "auth_plugin": "", + "auth_type": "", } self._assert_password_auth(flag, kwargs) @@ -390,7 +390,7 @@ class TestShellPasswordAuth(TestShell): "password": DEFAULT_PASSWORD, "region_name": "", "trust_id": "", - "auth_plugin": "", + "auth_type": "", } self._assert_password_auth(flag, kwargs) @@ -410,7 +410,7 @@ class TestShellPasswordAuth(TestShell): "password": "", "region_name": DEFAULT_REGION_NAME, "trust_id": "", - "auth_plugin": "", + "auth_type": "", } self._assert_password_auth(flag, kwargs) @@ -430,12 +430,12 @@ class TestShellPasswordAuth(TestShell): "password": "", "region_name": "", "trust_id": "1234", - "auth_plugin": "", + "auth_type": "", } self._assert_password_auth(flag, kwargs) - def test_only_auth_plugin_flow(self): - flag = "--os-auth-plugin " + "v2password" + def test_only_auth_type_flow(self): + flag = "--os-auth-type " + "v2password" kwargs = { "auth_url": "", "project_id": "", @@ -450,7 +450,7 @@ class TestShellPasswordAuth(TestShell): "password": "", "region_name": "", "trust_id": "", - "auth_plugin": DEFAULT_AUTH_PLUGIN + "auth_type": DEFAULT_AUTH_PLUGIN } self._assert_password_auth(flag, kwargs)