Fix auth prompt brokenness
We start by fixing this in the already-present OSC_Config class so OSC can move forward. This change needs to get ported down into os-client-config in the near future, maybe even soon enough to make the client library freeze this week. * Add the pw-func argument to the OSC_Config (or OpenStackConfig) __init__() * When looping through the auth options from the KSA plugin look for any that have a prompt defined and do not have a value already, so ask for one. Closes-bug: #1617384 Change-Id: Ic86d56b8a6844516292fb74513712b486fec4442
This commit is contained in:
parent
a08b62523f
commit
bec206fa0a
@ -25,6 +25,40 @@ LOG = logging.getLogger(__name__)
|
||||
# before auth plugins are loaded
|
||||
class OSC_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(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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
)
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user