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)