Merge "Add some bash helpers for auth stuff"
This commit is contained in:
commit
605ec92507
@ -31,14 +31,19 @@ from swiftclient.utils import config_true_value, generate_temp_url, prt_bytes
|
||||
from swiftclient.multithreading import OutputManager
|
||||
from swiftclient.exceptions import ClientException
|
||||
from swiftclient import __version__ as client_version
|
||||
from swiftclient.service import SwiftService, SwiftError, SwiftUploadObject
|
||||
from swiftclient.service import SwiftService, SwiftError, \
|
||||
SwiftUploadObject, get_conn
|
||||
from swiftclient.command_helpers import print_account_stats, \
|
||||
print_container_stats, print_object_stats
|
||||
|
||||
try:
|
||||
from shlex import quote as sh_quote
|
||||
except ImportError:
|
||||
from pipes import quote as sh_quote
|
||||
|
||||
BASENAME = 'swift'
|
||||
commands = ('delete', 'download', 'list', 'post',
|
||||
'stat', 'upload', 'capabilities', 'info', 'tempurl')
|
||||
commands = ('delete', 'download', 'list', 'post', 'stat', 'upload',
|
||||
'capabilities', 'info', 'tempurl', 'auth')
|
||||
|
||||
|
||||
def immediate_exit(signum, frame):
|
||||
@ -930,6 +935,46 @@ def st_capabilities(parser, args, output_manager):
|
||||
|
||||
st_info = st_capabilities
|
||||
|
||||
st_auth_help = '''
|
||||
Display auth related authentication variables in shell friendly format.
|
||||
|
||||
Commands to run to export storage url and auth token into
|
||||
OS_STORAGE_URL and OS_AUTH_TOKEN:
|
||||
|
||||
swift auth
|
||||
|
||||
Commands to append to a runcom file (e.g. ~/.bashrc, /etc/profile) for
|
||||
automatic authentication:
|
||||
|
||||
swift auth -v -U test:tester -K testing \
|
||||
-A http://localhost:8080/auth/v1.0
|
||||
|
||||
'''.strip('\n')
|
||||
|
||||
|
||||
def st_auth(parser, args, thread_manager):
|
||||
(options, args) = parse_args(parser, args)
|
||||
_opts = vars(options)
|
||||
if options.verbose > 1:
|
||||
if options.auth_version in ('1', '1.0'):
|
||||
print('export ST_AUTH=%s' % sh_quote(options.auth))
|
||||
print('export ST_USER=%s' % sh_quote(options.user))
|
||||
print('export ST_KEY=%s' % sh_quote(options.key))
|
||||
else:
|
||||
print('export OS_IDENTITY_API_VERSION=%s' % sh_quote(
|
||||
options.auth_version))
|
||||
print('export OS_AUTH_VERSION=%s' % sh_quote(options.auth_version))
|
||||
print('export OS_AUTH_URL=%s' % sh_quote(options.auth))
|
||||
for k, v in sorted(_opts.items()):
|
||||
if v and k.startswith('os_') and \
|
||||
k not in ('os_auth_url', 'os_options'):
|
||||
print('export %s=%s' % (k.upper(), sh_quote(v)))
|
||||
else:
|
||||
conn = get_conn(_opts)
|
||||
url, token = conn.get_auth()
|
||||
print('export OS_STORAGE_URL=%s' % sh_quote(url))
|
||||
print('export OS_AUTH_TOKEN=%s' % sh_quote(token))
|
||||
|
||||
|
||||
st_tempurl_options = '<method> <seconds> <path> <key>'
|
||||
|
||||
@ -1098,7 +1143,8 @@ Positional arguments:
|
||||
or object.
|
||||
upload Uploads files or directories to the given container.
|
||||
capabilities List cluster capabilities.
|
||||
tempurl Create a temporary URL
|
||||
tempurl Create a temporary URL.
|
||||
auth Display auth related environment variables.
|
||||
|
||||
Examples:
|
||||
%%prog download --help
|
||||
|
@ -19,8 +19,10 @@ import mock
|
||||
import os
|
||||
import tempfile
|
||||
import unittest
|
||||
import textwrap
|
||||
from testtools import ExpectedException
|
||||
|
||||
|
||||
import six
|
||||
|
||||
import swiftclient
|
||||
@ -46,6 +48,11 @@ mocked_os_environ = {
|
||||
'ST_USER': 'test:tester',
|
||||
'ST_KEY': 'testing'
|
||||
}
|
||||
clean_os_environ = {}
|
||||
environ_prefixes = ('ST_', 'OS_')
|
||||
for key in os.environ:
|
||||
if any(key.startswith(m) for m in environ_prefixes):
|
||||
clean_os_environ[key] = ''
|
||||
|
||||
clean_os_environ = {}
|
||||
environ_prefixes = ('ST_', 'OS_')
|
||||
@ -1554,6 +1561,101 @@ class TestAuth(MockHttpTest):
|
||||
}),
|
||||
])
|
||||
|
||||
def test_auth(self):
|
||||
headers = {
|
||||
'x-auth-token': 'AUTH_tk5b6b12',
|
||||
'x-storage-url': 'https://swift.storage.example.com/v1/AUTH_test',
|
||||
}
|
||||
mock_resp = self.fake_http_connection(200, headers=headers)
|
||||
with mock.patch('swiftclient.client.http_connection', new=mock_resp):
|
||||
stdout = six.StringIO()
|
||||
with mock.patch('sys.stdout', new=stdout):
|
||||
argv = [
|
||||
'',
|
||||
'auth',
|
||||
'--auth', 'https://swift.storage.example.com/auth/v1.0',
|
||||
'--user', 'test:tester', '--key', 'testing',
|
||||
]
|
||||
swiftclient.shell.main(argv)
|
||||
|
||||
expected = """
|
||||
export OS_STORAGE_URL=https://swift.storage.example.com/v1/AUTH_test
|
||||
export OS_AUTH_TOKEN=AUTH_tk5b6b12
|
||||
"""
|
||||
self.assertEquals(textwrap.dedent(expected).lstrip(),
|
||||
stdout.getvalue())
|
||||
|
||||
def test_auth_verbose(self):
|
||||
with mock.patch('swiftclient.client.http_connection') as mock_conn:
|
||||
stdout = six.StringIO()
|
||||
with mock.patch('sys.stdout', new=stdout):
|
||||
argv = [
|
||||
'',
|
||||
'auth',
|
||||
'--auth', 'https://swift.storage.example.com/auth/v1.0',
|
||||
'--user', 'test:tester', '--key', 'te$tin&',
|
||||
'--verbose',
|
||||
]
|
||||
swiftclient.shell.main(argv)
|
||||
|
||||
expected = """
|
||||
export ST_AUTH=https://swift.storage.example.com/auth/v1.0
|
||||
export ST_USER=test:tester
|
||||
export ST_KEY='te$tin&'
|
||||
"""
|
||||
self.assertEquals(textwrap.dedent(expected).lstrip(),
|
||||
stdout.getvalue())
|
||||
self.assertEqual([], mock_conn.mock_calls)
|
||||
|
||||
def test_auth_v2(self):
|
||||
os_options = {'tenant_name': 'demo'}
|
||||
with mock.patch('swiftclient.client.get_auth_keystone',
|
||||
new=fake_get_auth_keystone(os_options)):
|
||||
stdout = six.StringIO()
|
||||
with mock.patch('sys.stdout', new=stdout):
|
||||
argv = [
|
||||
'',
|
||||
'auth', '-V2',
|
||||
'--auth', 'https://keystone.example.com/v2.0/',
|
||||
'--os-tenant-name', 'demo',
|
||||
'--os-username', 'demo', '--os-password', 'admin',
|
||||
]
|
||||
swiftclient.shell.main(argv)
|
||||
|
||||
expected = """
|
||||
export OS_STORAGE_URL=http://url/
|
||||
export OS_AUTH_TOKEN=token
|
||||
"""
|
||||
self.assertEquals(textwrap.dedent(expected).lstrip(),
|
||||
stdout.getvalue())
|
||||
|
||||
def test_auth_verbose_v2(self):
|
||||
with mock.patch('swiftclient.client.get_auth_keystone') \
|
||||
as mock_keystone:
|
||||
stdout = six.StringIO()
|
||||
with mock.patch('sys.stdout', new=stdout):
|
||||
argv = [
|
||||
'',
|
||||
'auth', '-V2',
|
||||
'--auth', 'https://keystone.example.com/v2.0/',
|
||||
'--os-tenant-name', 'demo',
|
||||
'--os-username', 'demo', '--os-password', '$eKr3t',
|
||||
'--verbose',
|
||||
]
|
||||
swiftclient.shell.main(argv)
|
||||
|
||||
expected = """
|
||||
export OS_IDENTITY_API_VERSION=2.0
|
||||
export OS_AUTH_VERSION=2.0
|
||||
export OS_AUTH_URL=https://keystone.example.com/v2.0/
|
||||
export OS_PASSWORD='$eKr3t'
|
||||
export OS_TENANT_NAME=demo
|
||||
export OS_USERNAME=demo
|
||||
"""
|
||||
self.assertEquals(textwrap.dedent(expected).lstrip(),
|
||||
stdout.getvalue())
|
||||
self.assertEqual([], mock_keystone.mock_calls)
|
||||
|
||||
|
||||
class TestCrossAccountObjectAccess(TestBase, MockHttpTest):
|
||||
"""
|
||||
|
@ -38,8 +38,10 @@ def fake_get_auth_keystone(expected_os_options=None, exc=None,
|
||||
if exc:
|
||||
raise exc('test')
|
||||
# TODO: some way to require auth_url, user and key?
|
||||
if expected_os_options and actual_os_options != expected_os_options:
|
||||
return "", None
|
||||
if expected_os_options:
|
||||
for key, value in actual_os_options.items():
|
||||
if value and value != expected_os_options.get(key):
|
||||
return "", None
|
||||
if 'required_kwargs' in kwargs:
|
||||
for k, v in kwargs['required_kwargs'].items():
|
||||
if v != actual_kwargs.get(k):
|
||||
|
Loading…
x
Reference in New Issue
Block a user