summaryrefslogtreecommitdiff
path: root/openstackclient
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2016-08-29 21:09:58 +0000
committerGerrit Code Review <review@openstack.org>2016-08-29 21:09:58 +0000
commitc5f8f761de01e7dee7d65ccba40e8ee4cf116500 (patch)
tree8ea65ab26ab5dc1d70dd8a9568fc3d4801721416 /openstackclient
parent0ee74b4b274202de6e39b920a8a6d2c23ebb5a87 (diff)
parentbec206fa0a0214d856259661c5e32086f33d2f62 (diff)
downloadpython-openstackclient-c5f8f761de01e7dee7d65ccba40e8ee4cf116500.tar.gz
Merge "Fix auth prompt brokenness"
Diffstat (limited to 'openstackclient')
-rw-r--r--openstackclient/common/client_config.py43
-rw-r--r--openstackclient/common/clientmanager.py2
-rw-r--r--openstackclient/shell.py2
-rw-r--r--openstackclient/tests/test_shell_integ.py58
4 files changed, 102 insertions, 3 deletions
diff --git a/openstackclient/common/client_config.py b/openstackclient/common/client_config.py
index 9e98adc6..895909e9 100644
--- a/openstackclient/common/client_config.py
+++ b/openstackclient/common/client_config.py
@@ -25,6 +25,40 @@ LOG = logging.getLogger(__name__)
# before auth plugins are loaded
class OSC_Config(config.OpenStackConfig):
+ # TODO(dtroyer): Once os-client-config with pw_func argument is in
+ # global-requirements we can remove __init()__
+ def __init__(
+ self,
+ config_files=None,
+ vendor_files=None,
+ override_defaults=None,
+ force_ipv4=None,
+ envvar_prefix=None,
+ secure_files=None,
+ pw_func=None,
+ ):
+ ret = super(OSC_Config, self).__init__(
+ config_files=config_files,
+ vendor_files=vendor_files,
+ override_defaults=override_defaults,
+ force_ipv4=force_ipv4,
+ envvar_prefix=envvar_prefix,
+ secure_files=secure_files,
+ )
+
+ # NOTE(dtroyer): This will be pushed down into os-client-config
+ # The default is there is no callback, the calling
+ # application must specify what to use, typically
+ # it will be osc_lib.shell.prompt_for_password()
+ if '_pw_callback' not in vars(self):
+ # Set the default if it doesn't already exist
+ self._pw_callback = None
+ if pw_func is not None:
+ # Set the passed in value
+ self._pw_callback = pw_func
+
+ return ret
+
def _auth_select_default_plugin(self, config):
"""Select a default plugin based on supplied arguments
@@ -183,4 +217,13 @@ class OSC_Config(config.OpenStackConfig):
else:
config['auth'][p_opt.dest] = winning_value
+ # See if this needs a prompting
+ if (
+ 'prompt' in vars(p_opt) and
+ p_opt.prompt is not None and
+ p_opt.dest not in config['auth'] and
+ self._pw_callback is not None
+ ):
+ config['auth'][p_opt.dest] = self._pw_callback(p_opt.prompt)
+
return config
diff --git a/openstackclient/common/clientmanager.py b/openstackclient/common/clientmanager.py
index ccfde2d0..9097543b 100644
--- a/openstackclient/common/clientmanager.py
+++ b/openstackclient/common/clientmanager.py
@@ -44,12 +44,10 @@ class ClientManager(clientmanager.ClientManager):
self,
cli_options=None,
api_version=None,
- pw_func=None,
):
super(ClientManager, self).__init__(
cli_options=cli_options,
api_version=api_version,
- pw_func=pw_func,
)
# TODO(dtroyer): For compatibility; mark this for removal when plugin
diff --git a/openstackclient/shell.py b/openstackclient/shell.py
index da58b63b..26147be9 100644
--- a/openstackclient/shell.py
+++ b/openstackclient/shell.py
@@ -145,6 +145,7 @@ class OpenStackShell(shell.OpenStackShell):
'interface': None,
'auth_type': self._auth_type,
},
+ pw_func=shell.prompt_for_password,
)
except (IOError, OSError) as e:
self.log.critical("Could not read clouds.yaml configuration file")
@@ -162,7 +163,6 @@ class OpenStackShell(shell.OpenStackShell):
self.client_manager = clientmanager.ClientManager(
cli_options=self.cloud,
api_version=self.api_version,
- pw_func=shell.prompt_for_password,
)
diff --git a/openstackclient/tests/test_shell_integ.py b/openstackclient/tests/test_shell_integ.py
index bc5f1ae5..d50113b2 100644
--- a/openstackclient/tests/test_shell_integ.py
+++ b/openstackclient/tests/test_shell_integ.py
@@ -354,6 +354,64 @@ class TestShellCliV3Integ(TestShellInteg):
self.assertFalse(self.requests_mock.request_history[0].verify)
+class TestShellCliV3Prompt(TestShellInteg):
+
+ def setUp(self):
+ super(TestShellCliV3Prompt, self).setUp()
+ env = {
+ "OS_AUTH_URL": V3_AUTH_URL,
+ "OS_PROJECT_DOMAIN_ID": test_shell.DEFAULT_PROJECT_DOMAIN_ID,
+ "OS_USER_DOMAIN_ID": test_shell.DEFAULT_USER_DOMAIN_ID,
+ "OS_USERNAME": test_shell.DEFAULT_USERNAME,
+ "OS_IDENTITY_API_VERSION": "3",
+ }
+ self.useFixture(osc_lib_utils.EnvFixture(copy.deepcopy(env)))
+
+ self.token = ksa_fixture.V3Token(
+ project_domain_id=test_shell.DEFAULT_PROJECT_DOMAIN_ID,
+ user_domain_id=test_shell.DEFAULT_USER_DOMAIN_ID,
+ user_name=test_shell.DEFAULT_USERNAME,
+ )
+
+ # Set up the v3 auth routes
+ self.requests_mock.register_uri(
+ 'GET',
+ V3_AUTH_URL,
+ json=V3_VERSION_RESP,
+ status_code=200,
+ )
+ self.requests_mock.register_uri(
+ 'POST',
+ V3_AUTH_URL + 'auth/tokens',
+ json=self.token,
+ status_code=200,
+ )
+
+ @mock.patch("osc_lib.shell.prompt_for_password")
+ def test_shell_callback(self, mock_prompt):
+ mock_prompt.return_value = "qaz"
+ _shell = shell.OpenStackShell()
+ _shell.run("configuration show".split())
+
+ # Check general calls
+ self.assertEqual(len(self.requests_mock.request_history), 2)
+
+ # Check password callback set correctly
+ self.assertEqual(
+ mock_prompt,
+ _shell.cloud._openstack_config._pw_callback
+ )
+
+ # Check auth request
+ auth_req = self.requests_mock.request_history[1].json()
+
+ # Check returned password from prompt function
+ self.assertEqual(
+ "qaz",
+ auth_req['auth']['identity']['password']['user']['password'],
+ )
+
+
class TestShellCliPrecedence(TestShellInteg):
"""Validate option precedence rules without clouds.yaml