Skip to content

Commit

Permalink
Merge "Adds tty password entry for glanceclient"
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenkins authored and openstack-gerrit committed Nov 25, 2014
2 parents 265bb4a + 751e064 commit 3b6754a
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 4 deletions.
20 changes: 16 additions & 4 deletions glanceclient/shell.py
Expand Up @@ -21,6 +21,7 @@

import argparse
import copy
import getpass
import json
import logging
import os
Expand Down Expand Up @@ -448,10 +449,21 @@ def _get_endpoint_and_token(self, args, force_auth=False):
"env[OS_USERNAME]"))

if not args.os_password:
raise exc.CommandError(
_("You must provide a password via"
" either --os-password or "
"env[OS_PASSWORD]"))
# No password, If we've got a tty, try prompting for it
if hasattr(sys.stdin, 'isatty') and sys.stdin.isatty():
# Check for Ctl-D
try:
args.os_password = getpass.getpass('OS Password: ')
except EOFError:
pass
# No password because we didn't have a tty or the
# user Ctl-D when prompted.
if not args.os_password:
raise exc.CommandError(
_("You must provide a password via "
"either --os-password, "
"env[OS_PASSWORD], "
"or prompted response"))

# Validate password flow auth
project_info = (args.os_tenant_name or
Expand Down
27 changes: 27 additions & 0 deletions tests/test_shell.py
Expand Up @@ -18,6 +18,7 @@
import os
import sys

import fixtures
import mock
import six

Expand Down Expand Up @@ -67,6 +68,11 @@ class ShellTest(utils.TestCase):
# expected auth plugin to invoke
auth_plugin = 'keystoneclient.auth.identity.v2.Password'

# Patch os.environ to avoid required auth info
def make_env(self, exclude=None, fake_env=FAKE_V2_ENV):
env = dict((k, v) for k, v in fake_env.items() if k != exclude)
self.useFixture(fixtures.MonkeyPatch('os.environ', env))

def setUp(self):
super(ShellTest, self).setUp()
global _old_env
Expand Down Expand Up @@ -246,6 +252,27 @@ def test_auth_plugin_invocation_with_unversioned_auth_url_with_v2(
glance_shell.main(args.split())
self._assert_auth_plugin_args(mock_auth_plugin)

@mock.patch('sys.stdin', side_effect=mock.MagicMock)
@mock.patch('getpass.getpass', return_value='password')
def test_password_prompted_with_v2(self, mock_getpass, mock_stdin):
glance_shell = openstack_shell.OpenStackImagesShell()
self.make_env(exclude='OS_PASSWORD')
# We will get a Connection Refused because there is no keystone.
self.assertRaises(ks_exc.ConnectionRefused,
glance_shell.main, ['image-list'])
# Make sure we are actually prompted.
mock_getpass.assert_called_with('OS Password: ')

@mock.patch('sys.stdin', side_effect=mock.MagicMock)
@mock.patch('getpass.getpass', side_effect=EOFError)
def test_password_prompted_ctrlD_with_v2(self, mock_getpass, mock_stdin):
glance_shell = openstack_shell.OpenStackImagesShell()
self.make_env(exclude='OS_PASSWORD')
# We should get Command Error because we mock Ctl-D.
self.assertRaises(exc.CommandError, glance_shell.main, ['image-list'])
# Make sure we are actually prompted.
mock_getpass.assert_called_with('OS Password: ')


class ShellTestWithKeystoneV3Auth(ShellTest):
# auth environment to use
Expand Down

0 comments on commit 3b6754a

Please sign in to comment.