From fff4a1cd23057160af13f157a6fde2c172fae7a9 Mon Sep 17 00:00:00 2001 From: Steve Martinelli Date: Fri, 16 Jan 2015 02:20:52 -0500 Subject: [PATCH] Add helpful messages when authN'ing with password Setting up auth options can be complicated, and we currently don't do any checking before we build all our auth parameters to send off to keystoneclient. We should do some basic checking to guide new users. Change-Id: I9c88f1c9637b3870c151952ecc797aaf65be271a Closes-Bug: #1400531 --- openstackclient/api/auth.py | 22 ++++++++++++++++++- openstackclient/common/clientmanager.py | 5 ++++- .../tests/common/test_clientmanager.py | 7 ++++-- openstackclient/tests/fakes.py | 1 + 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/openstackclient/api/auth.py b/openstackclient/api/auth.py index bfb2f83a47..fa196fa43e 100644 --- a/openstackclient/api/auth.py +++ b/openstackclient/api/auth.py @@ -24,6 +24,7 @@ from keystoneclient.auth import base from openstackclient.common import exceptions as exc from openstackclient.common import utils +from openstackclient.i18n import _ LOG = logging.getLogger(__name__) @@ -122,6 +123,25 @@ def build_auth_params(auth_plugin_name, cmd_options): return (auth_plugin_class, auth_params) +def check_valid_auth_options(options, auth_plugin_name): + """Perform basic option checking, provide helpful error messages""" + + msg = '' + if auth_plugin_name.endswith('password'): + if not options.os_username: + msg += _('Set a username with --os-username or OS_USERNAME\n') + if not options.os_auth_url: + msg += _('Set an authentication URL, with --os-auth-url or' + ' OS_AUTH_URL\n') + if (not options.os_project_id and not options.os_domain_id and not + options.os_domain_name and not options.os_project_name): + msg += _('Set a scope, such as a project or domain, with ' + '--os-project-name or OS_PROJECT_NAME') + + if msg: + raise exc.CommandError('Missing parameter(s): \n%s' % msg) + + def build_auth_plugins_option_parser(parser): """Auth plugins options builder @@ -140,7 +160,7 @@ def build_auth_plugins_option_parser(parser): ' (Env: OS_AUTH_TYPE)', choices=available_plugins ) - # make sur we catch old v2.0 env values + # make sure we catch old v2.0 env values envs = { 'OS_PROJECT_NAME': utils.env( 'OS_PROJECT_NAME', diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py index 0396e83dd2..cc75c68d48 100644 --- a/openstackclient/common/clientmanager.py +++ b/openstackclient/common/clientmanager.py @@ -74,13 +74,16 @@ class ClientManager(object): :param pw_func: Callback function for asking the user for a password. The function takes an optional string for the prompt ('Password: ' on None) and - returns a string containig the password + returns a string containing the password """ # If no auth type is named by the user, select one based on # the supplied options self.auth_plugin_name = auth.select_auth_plugin(auth_options) + # Basic option checking to avoid unhelpful error messages + auth.check_valid_auth_options(auth_options, self.auth_plugin_name) + # Horrible hack alert...must handle prompt for null password if # password auth is requested. if (self.auth_plugin_name.endswith('password') and diff --git a/openstackclient/tests/common/test_clientmanager.py b/openstackclient/tests/common/test_clientmanager.py index 8c27e5621d..2c213f8ab0 100644 --- a/openstackclient/tests/common/test_clientmanager.py +++ b/openstackclient/tests/common/test_clientmanager.py @@ -126,7 +126,8 @@ class TestClientManager(utils.TestCase): client_manager = clientmanager.ClientManager( auth_options=FakeOptions(os_auth_url=fakes.AUTH_URL, os_username=fakes.USERNAME, - os_password=fakes.PASSWORD), + os_password=fakes.PASSWORD, + os_project_name=fakes.PROJECT_NAME), api_version=API_VERSION, verify=False, ) @@ -183,6 +184,7 @@ class TestClientManager(utils.TestCase): auth_options=FakeOptions(os_auth_url=fakes.AUTH_URL, os_username=fakes.USERNAME, os_password=fakes.PASSWORD, + os_project_name=fakes.PROJECT_NAME, os_auth_type='v2password'), api_version=API_VERSION, verify='cafile', @@ -218,7 +220,8 @@ class TestClientManager(utils.TestCase): # test password auth params = dict(os_auth_url=fakes.AUTH_URL, os_username=fakes.USERNAME, - os_password=fakes.PASSWORD) + os_password=fakes.PASSWORD, + os_project_name=fakes.PROJECT_NAME) self._select_auth_plugin(params, '2.0', 'v2password') self._select_auth_plugin(params, '3', 'v3password') self._select_auth_plugin(params, 'XXX', 'password') diff --git a/openstackclient/tests/fakes.py b/openstackclient/tests/fakes.py index e25751d643..d37555e347 100644 --- a/openstackclient/tests/fakes.py +++ b/openstackclient/tests/fakes.py @@ -25,6 +25,7 @@ AUTH_TOKEN = "foobar" AUTH_URL = "http://0.0.0.0" USERNAME = "itchy" PASSWORD = "scratchy" +PROJECT_NAME = "poochie" TEST_RESPONSE_DICT = fixture.V2Token(token_id=AUTH_TOKEN, user_name=USERNAME)