diff --git a/ironicclient/shell.py b/ironicclient/shell.py index 172076606..3577a5c5f 100644 --- a/ironicclient/shell.py +++ b/ironicclient/shell.py @@ -331,8 +331,7 @@ class IronicShell(object): self.do_bash_completion() return 0 - if not (args.os_auth_token and (args.ironic_url or args.os_endpoint or - args.os_auth_url)): + if not (args.os_auth_token and (args.ironic_url or args.os_auth_url)): if not args.os_username: raise exc.CommandError(_("You must provide a username via " "either --os-username or via " diff --git a/ironicclient/tests/unit/test_shell.py b/ironicclient/tests/unit/test_shell.py index 1d4b93f10..36752e1d0 100644 --- a/ironicclient/tests/unit/test_shell.py +++ b/ironicclient/tests/unit/test_shell.py @@ -55,13 +55,19 @@ FAKE_ENV_KEYSTONE_V3 = { 'OS_PROJECT_DOMAIN_ID': 'default', } +FAKE_ENV_KEYSTONE_V2_TOKEN = { + 'OS_AUTH_TOKEN': 'admin_token', + 'OS_TENANT_NAME': 'tenant_name', + 'OS_AUTH_URL': V2_URL +} + class ShellTest(utils.BaseTestCase): re_options = re.DOTALL | re.MULTILINE # Patch os.environ to avoid required auth info. - def make_env(self, exclude=None): - env = dict((k, v) for k, v in FAKE_ENV.items() if k != exclude) + def make_env(self, exclude=None, environ_dict=FAKE_ENV): + env = dict((k, v) for k, v in environ_dict.items() if k != exclude) self.useFixture(fixtures.MonkeyPatch('os.environ', env)) def setUp(self): @@ -149,6 +155,33 @@ class ShellTest(utils.BaseTestCase): # Make sure we are actually prompted. mock_getpass.assert_called_with('OpenStack Password: ') + @mock.patch.object(client, 'get_client', + side_effect=keystone_exc.ConnectFailure) + @mock.patch('getpass.getpass', return_value='password') + def test_token_auth(self, mock_getpass, mock_client): + self.make_env(environ_dict=FAKE_ENV_KEYSTONE_V2_TOKEN) + # We will get a ConnectFailure because there is no keystone. + self.assertRaises(keystone_exc.ConnectFailure, + self.shell, 'node-list') + expected_kwargs = { + 'ironic_url': '', + 'os_auth_url': FAKE_ENV_KEYSTONE_V2_TOKEN['OS_AUTH_URL'], + 'os_tenant_id': '', + 'os_tenant_name': FAKE_ENV_KEYSTONE_V2_TOKEN['OS_TENANT_NAME'], + 'os_username': '', 'os_user_domain_id': '', + 'os_user_domain_name': '', 'os_password': '', + 'os_auth_token': FAKE_ENV_KEYSTONE_V2_TOKEN['OS_AUTH_TOKEN'], + 'os_project_id': '', 'os_project_name': '', + 'os_project_domain_id': '', 'os_project_domain_name': '', + 'os_region_name': '', 'os_service_type': '', + 'os_endpoint_type': '', 'os_cacert': None, 'os_cert': None, + 'os_key': None, 'max_retries': http.DEFAULT_MAX_RETRIES, + 'retry_interval': http.DEFAULT_RETRY_INTERVAL, + 'os_ironic_api_version': None, 'timeout': 600, 'insecure': False + } + mock_client.assert_called_once_with(1, **expected_kwargs) + self.assertFalse(mock_getpass.called) + @mock.patch('sys.stdin', side_effect=mock.MagicMock) @mock.patch('getpass.getpass', side_effect=EOFError) def test_password_prompted_ctrlD(self, mock_getpass, mock_stdin):