Merge "Add keystone v3 auth support"
This commit is contained in:
@@ -35,6 +35,10 @@ from swiftclient import version as swiftclient_version
|
|||||||
from swiftclient.exceptions import ClientException
|
from swiftclient.exceptions import ClientException
|
||||||
from swiftclient.utils import LengthWrapper
|
from swiftclient.utils import LengthWrapper
|
||||||
|
|
||||||
|
AUTH_VERSIONS_V1 = ('1.0', '1', 1)
|
||||||
|
AUTH_VERSIONS_V2 = ('2.0', '2', 2)
|
||||||
|
AUTH_VERSIONS_V3 = ('3.0', '3', 3)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from logging import NullHandler
|
from logging import NullHandler
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@@ -275,35 +279,57 @@ def get_auth_1_0(url, user, key, snet, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
def get_keystoneclient_2_0(auth_url, user, key, os_options, **kwargs):
|
def get_keystoneclient_2_0(auth_url, user, key, os_options, **kwargs):
|
||||||
"""
|
# this function is only here to preserve the historic 'public'
|
||||||
Authenticate against an auth 2.0 server.
|
# interface of this module
|
||||||
|
kwargs.update({'auth_version': '2.0'})
|
||||||
|
return get_auth_keystone(auth_url, user, key, os_options, **kwargs)
|
||||||
|
|
||||||
We are using the keystoneclient library for our 2.0 authentication.
|
|
||||||
|
def get_auth_keystone(auth_url, user, key, os_options, **kwargs):
|
||||||
|
"""
|
||||||
|
Authenticate against a keystone server.
|
||||||
|
|
||||||
|
We are using the keystoneclient library for authentication.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
insecure = kwargs.get('insecure', False)
|
insecure = kwargs.get('insecure', False)
|
||||||
|
auth_version = kwargs.get('auth_version', '2.0')
|
||||||
debug = logger.isEnabledFor(logging.DEBUG) and True or False
|
debug = logger.isEnabledFor(logging.DEBUG) and True or False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
if auth_version in AUTH_VERSIONS_V3:
|
||||||
|
from keystoneclient.v3 import client as ksclient
|
||||||
|
else:
|
||||||
from keystoneclient.v2_0 import client as ksclient
|
from keystoneclient.v2_0 import client as ksclient
|
||||||
from keystoneclient import exceptions
|
from keystoneclient import exceptions
|
||||||
except ImportError:
|
except ImportError:
|
||||||
sys.exit('''
|
sys.exit('''
|
||||||
Auth version 2.0 requires python-keystoneclient, install it or use Auth
|
Auth versions 2.0 and 3 require python-keystoneclient, install it or use Auth
|
||||||
version 1.0 which requires ST_AUTH, ST_USER, and ST_KEY environment
|
version 1.0 which requires ST_AUTH, ST_USER, and ST_KEY environment
|
||||||
variables to be set or overridden with -A, -U, or -K.''')
|
variables to be set or overridden with -A, -U, or -K.''')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
_ksclient = ksclient.Client(username=user,
|
_ksclient = ksclient.Client(
|
||||||
|
username=user,
|
||||||
password=key,
|
password=key,
|
||||||
tenant_name=os_options.get('tenant_name'),
|
tenant_name=os_options.get('tenant_name'),
|
||||||
tenant_id=os_options.get('tenant_id'),
|
tenant_id=os_options.get('tenant_id'),
|
||||||
|
user_id=os_options.get('user_id'),
|
||||||
|
user_domain_name=os_options.get('user_domain_name'),
|
||||||
|
user_domain_id=os_options.get('user_domain_id'),
|
||||||
|
project_name=os_options.get('project_name'),
|
||||||
|
project_id=os_options.get('project_id'),
|
||||||
|
project_domain_name=os_options.get('project_domain_name'),
|
||||||
|
project_domain_id=os_options.get('project_domain_id'),
|
||||||
debug=debug,
|
debug=debug,
|
||||||
cacert=kwargs.get('cacert'),
|
cacert=kwargs.get('cacert'),
|
||||||
auth_url=auth_url, insecure=insecure)
|
auth_url=auth_url, insecure=insecure)
|
||||||
except exceptions.Unauthorized:
|
except exceptions.Unauthorized:
|
||||||
raise ClientException('Unauthorised. Check username, password'
|
msg = 'Unauthorized. Check username, password and tenant name/id.'
|
||||||
' and tenant name/id')
|
if auth_version in AUTH_VERSIONS_V3:
|
||||||
|
msg = 'Unauthorized. Check username/id, password, ' \
|
||||||
|
+ 'tenant name/id and user/tenant domain name/id.'
|
||||||
|
raise ClientException(msg)
|
||||||
except exceptions.AuthorizationFailure as err:
|
except exceptions.AuthorizationFailure as err:
|
||||||
raise ClientException('Authorization Failure. %s' % err)
|
raise ClientException('Authorization Failure. %s' % err)
|
||||||
service_type = os_options.get('service_type') or 'object-store'
|
service_type = os_options.get('service_type') or 'object-store'
|
||||||
@@ -335,13 +361,13 @@ def get_auth(auth_url, user, key, **kwargs):
|
|||||||
|
|
||||||
storage_url, token = None, None
|
storage_url, token = None, None
|
||||||
insecure = kwargs.get('insecure', False)
|
insecure = kwargs.get('insecure', False)
|
||||||
if auth_version in ['1.0', '1', 1]:
|
if auth_version in AUTH_VERSIONS_V1:
|
||||||
storage_url, token = get_auth_1_0(auth_url,
|
storage_url, token = get_auth_1_0(auth_url,
|
||||||
user,
|
user,
|
||||||
key,
|
key,
|
||||||
kwargs.get('snet'),
|
kwargs.get('snet'),
|
||||||
insecure=insecure)
|
insecure=insecure)
|
||||||
elif auth_version in ['2.0', '2', 2]:
|
elif auth_version in AUTH_VERSIONS_V2 + AUTH_VERSIONS_V3:
|
||||||
# We are allowing to specify a token/storage-url to re-use
|
# We are allowing to specify a token/storage-url to re-use
|
||||||
# without having to re-authenticate.
|
# without having to re-authenticate.
|
||||||
if (os_options.get('object_storage_url') and
|
if (os_options.get('object_storage_url') and
|
||||||
@@ -349,10 +375,9 @@ def get_auth(auth_url, user, key, **kwargs):
|
|||||||
return (os_options.get('object_storage_url'),
|
return (os_options.get('object_storage_url'),
|
||||||
os_options.get('auth_token'))
|
os_options.get('auth_token'))
|
||||||
|
|
||||||
# We are handling a special use case here when we were
|
# We are handling a special use case here where the user argument
|
||||||
# allowing specifying the account/tenant_name with the -U
|
# specifies both the user name and tenant name in the form tenant:user
|
||||||
# argument
|
if user and not kwargs.get('tenant_name') and ':' in user:
|
||||||
if not kwargs.get('tenant_name') and ':' in user:
|
|
||||||
(os_options['tenant_name'],
|
(os_options['tenant_name'],
|
||||||
user) = user.split(':')
|
user) = user.split(':')
|
||||||
|
|
||||||
@@ -361,14 +386,17 @@ def get_auth(auth_url, user, key, **kwargs):
|
|||||||
if kwargs.get('tenant_name'):
|
if kwargs.get('tenant_name'):
|
||||||
os_options['tenant_name'] = kwargs['tenant_name']
|
os_options['tenant_name'] = kwargs['tenant_name']
|
||||||
|
|
||||||
if not (os_options.get('tenant_name') or os_options.get('tenant_id')):
|
if not (os_options.get('tenant_name') or os_options.get('tenant_id')
|
||||||
|
or os_options.get('project_name')
|
||||||
|
or os_options.get('project_id')):
|
||||||
raise ClientException('No tenant specified')
|
raise ClientException('No tenant specified')
|
||||||
|
|
||||||
cacert = kwargs.get('cacert', None)
|
cacert = kwargs.get('cacert', None)
|
||||||
storage_url, token = get_keystoneclient_2_0(auth_url, user,
|
storage_url, token = get_auth_keystone(auth_url, user,
|
||||||
key, os_options,
|
key, os_options,
|
||||||
cacert=cacert,
|
cacert=cacert,
|
||||||
insecure=insecure)
|
insecure=insecure,
|
||||||
|
auth_version=auth_version)
|
||||||
else:
|
else:
|
||||||
raise ClientException('Unknown auth_version %s specified.'
|
raise ClientException('Unknown auth_version %s specified.'
|
||||||
% auth_version)
|
% auth_version)
|
||||||
|
@@ -22,7 +22,7 @@ import logging
|
|||||||
|
|
||||||
from errno import EEXIST, ENOENT
|
from errno import EEXIST, ENOENT
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
from optparse import OptionParser, SUPPRESS_HELP
|
from optparse import OptionParser, OptionGroup, SUPPRESS_HELP
|
||||||
from os import environ, listdir, makedirs, utime, _exit as os_exit
|
from os import environ, listdir, makedirs, utime, _exit as os_exit
|
||||||
from os.path import dirname, getmtime, getsize, isdir, join, \
|
from os.path import dirname, getmtime, getsize, isdir, join, \
|
||||||
sep as os_path_sep
|
sep as os_path_sep
|
||||||
@@ -1356,8 +1356,13 @@ def parse_args(parser, args, enforce_requires=True):
|
|||||||
if len(args) > 0 and args[0] == 'tempurl':
|
if len(args) > 0 and args[0] == 'tempurl':
|
||||||
return options, args
|
return options, args
|
||||||
|
|
||||||
if (not (options.auth and options.user and options.key)):
|
if options.auth_version == '3.0':
|
||||||
# Use 2.0 auth if none of the old args are present
|
# tolerate sloppy auth_version
|
||||||
|
options.auth_version = '3'
|
||||||
|
|
||||||
|
if (not (options.auth and options.user and options.key)
|
||||||
|
and options.auth_version != '3'):
|
||||||
|
# Use keystone auth if any of the old-style args are missing
|
||||||
options.auth_version = '2.0'
|
options.auth_version = '2.0'
|
||||||
|
|
||||||
# Use new-style args if old ones not present
|
# Use new-style args if old ones not present
|
||||||
@@ -1370,8 +1375,15 @@ def parse_args(parser, args, enforce_requires=True):
|
|||||||
|
|
||||||
# Specific OpenStack options
|
# Specific OpenStack options
|
||||||
options.os_options = {
|
options.os_options = {
|
||||||
|
'user_id': options.os_user_id,
|
||||||
|
'user_domain_id': options.os_user_domain_id,
|
||||||
|
'user_domain_name': options.os_user_domain_name,
|
||||||
'tenant_id': options.os_tenant_id,
|
'tenant_id': options.os_tenant_id,
|
||||||
'tenant_name': options.os_tenant_name,
|
'tenant_name': options.os_tenant_name,
|
||||||
|
'project_id': options.os_project_id,
|
||||||
|
'project_name': options.os_project_name,
|
||||||
|
'project_domain_id': options.os_project_domain_id,
|
||||||
|
'project_domain_name': options.os_project_domain_name,
|
||||||
'service_type': options.os_service_type,
|
'service_type': options.os_service_type,
|
||||||
'endpoint_type': options.os_endpoint_type,
|
'endpoint_type': options.os_endpoint_type,
|
||||||
'auth_token': options.os_auth_token,
|
'auth_token': options.os_auth_token,
|
||||||
@@ -1384,11 +1396,22 @@ def parse_args(parser, args, enforce_requires=True):
|
|||||||
|
|
||||||
if (options.os_options.get('object_storage_url') and
|
if (options.os_options.get('object_storage_url') and
|
||||||
options.os_options.get('auth_token') and
|
options.os_options.get('auth_token') and
|
||||||
options.auth_version == '2.0'):
|
(options.auth_version == '2.0' or options.auth_version == '3')):
|
||||||
return options, args
|
return options, args
|
||||||
|
|
||||||
if enforce_requires and \
|
if enforce_requires:
|
||||||
not (options.auth and options.user and options.key):
|
if options.auth_version == '3':
|
||||||
|
if not options.auth:
|
||||||
|
exit('Auth version 3 requires OS_AUTH_URL to be set or ' +
|
||||||
|
'overridden with --os-auth-url')
|
||||||
|
if not (options.user or options.os_user_id):
|
||||||
|
exit('Auth version 3 requires either OS_USERNAME or ' +
|
||||||
|
'OS_USER_ID to be set or overridden with ' +
|
||||||
|
'--os-username or --os-user-id respectively.')
|
||||||
|
if not options.key:
|
||||||
|
exit('Auth version 3 requires OS_PASSWORD to be set or ' +
|
||||||
|
'overridden with --os-password')
|
||||||
|
elif not (options.auth and options.user and options.key):
|
||||||
exit('''
|
exit('''
|
||||||
Auth version 1.0 requires ST_AUTH, ST_USER, and ST_KEY environment variables
|
Auth version 1.0 requires ST_AUTH, ST_USER, and ST_KEY environment variables
|
||||||
to be set or overridden with -A, -U, or -K.
|
to be set or overridden with -A, -U, or -K.
|
||||||
@@ -1409,13 +1432,20 @@ def main(arguments=None):
|
|||||||
version = client_version
|
version = client_version
|
||||||
parser = OptionParser(version='%%prog %s' % version,
|
parser = OptionParser(version='%%prog %s' % version,
|
||||||
usage='''
|
usage='''
|
||||||
usage: %%prog [--version] [--help] [--snet] [--verbose]
|
usage: %%prog [--version] [--help] [--os-help] [--snet] [--verbose]
|
||||||
[--debug] [--info] [--quiet] [--auth <auth_url>]
|
[--debug] [--info] [--quiet] [--auth <auth_url>]
|
||||||
[--auth-version <auth_version>] [--user <username>]
|
[--auth-version <auth_version>] [--user <username>]
|
||||||
[--key <api_key>] [--retries <num_retries>]
|
[--key <api_key>] [--retries <num_retries>]
|
||||||
[--os-username <auth-user-name>] [--os-password <auth-password>]
|
[--os-username <auth-user-name>] [--os-password <auth-password>]
|
||||||
|
[--os-user-id <auth-user-id>]
|
||||||
|
[--os-user-domain-id <auth-user-domain-id>]
|
||||||
|
[--os-user-domain-name <auth-user-domain-name>]
|
||||||
[--os-tenant-id <auth-tenant-id>]
|
[--os-tenant-id <auth-tenant-id>]
|
||||||
[--os-tenant-name <auth-tenant-name>]
|
[--os-tenant-name <auth-tenant-name>]
|
||||||
|
[--os-project-id <auth-project-id>]
|
||||||
|
[--os-project-name <auth-project-name>]
|
||||||
|
[--os-project-domain-id <auth-project-domain-id>]
|
||||||
|
[--os-project-domain-name <auth-project-domain-name>]
|
||||||
[--os-auth-url <auth-url>] [--os-auth-token <auth-token>]
|
[--os-auth-url <auth-url>] [--os-auth-token <auth-token>]
|
||||||
[--os-storage-url <storage-url>] [--os-region-name <region-name>]
|
[--os-storage-url <storage-url>] [--os-region-name <region-name>]
|
||||||
[--os-service-type <service-type>]
|
[--os-service-type <service-type>]
|
||||||
@@ -1449,12 +1479,25 @@ Examples:
|
|||||||
%%prog --os-auth-url https://api.example.com/v2.0 --os-tenant-name tenant \\
|
%%prog --os-auth-url https://api.example.com/v2.0 --os-tenant-name tenant \\
|
||||||
--os-username user --os-password password list
|
--os-username user --os-password password list
|
||||||
|
|
||||||
|
%%prog --os-auth-url https://api.example.com/v3 --auth-version 3\\
|
||||||
|
--os-project-name project1 --os-project-domain-name domain1 \\
|
||||||
|
--os-username user --os-user-domain-name domain1 \\
|
||||||
|
--os-password password list
|
||||||
|
|
||||||
|
%%prog --os-auth-url https://api.example.com/v3 --auth-version 3\\
|
||||||
|
--os-project-id 0123456789abcdef0123456789abcdef \\
|
||||||
|
--os-user-id abcdef0123456789abcdef0123456789 \\
|
||||||
|
--os-password password list
|
||||||
|
|
||||||
%%prog --os-auth-token 6ee5eb33efad4e45ab46806eac010566 \\
|
%%prog --os-auth-token 6ee5eb33efad4e45ab46806eac010566 \\
|
||||||
--os-storage-url https://10.1.5.2:8080/v1/AUTH_ced809b6a4baea7aeab61a \\
|
--os-storage-url https://10.1.5.2:8080/v1/AUTH_ced809b6a4baea7aeab61a \\
|
||||||
list
|
list
|
||||||
|
|
||||||
%%prog list --lh
|
%%prog list --lh
|
||||||
'''.strip('\n') % globals())
|
'''.strip('\n') % globals())
|
||||||
|
parser.add_option('--os-help', action='store_true', dest='os_help',
|
||||||
|
help='Show OpenStack authentication options.')
|
||||||
|
parser.add_option('--os_help', action='store_true', help=SUPPRESS_HELP)
|
||||||
parser.add_option('-s', '--snet', action='store_true', dest='snet',
|
parser.add_option('-s', '--snet', action='store_true', dest='snet',
|
||||||
default=False, help='Use SERVICENET internal network.')
|
default=False, help='Use SERVICENET internal network.')
|
||||||
parser.add_option('-v', '--verbose', action='count', dest='verbose',
|
parser.add_option('-v', '--verbose', action='count', dest='verbose',
|
||||||
@@ -1472,7 +1515,9 @@ Examples:
|
|||||||
help='URL for obtaining an auth token.')
|
help='URL for obtaining an auth token.')
|
||||||
parser.add_option('-V', '--auth-version',
|
parser.add_option('-V', '--auth-version',
|
||||||
dest='auth_version',
|
dest='auth_version',
|
||||||
default=environ.get('ST_AUTH_VERSION', '1.0'),
|
default=environ.get('ST_AUTH_VERSION',
|
||||||
|
(environ.get('OS_AUTH_VERSION',
|
||||||
|
'1.0'))),
|
||||||
type=str,
|
type=str,
|
||||||
help='Specify a version for authentication. '
|
help='Specify a version for authentication. '
|
||||||
'Defaults to 1.0.')
|
'Defaults to 1.0.')
|
||||||
@@ -1484,81 +1529,6 @@ Examples:
|
|||||||
help='Key for obtaining an auth token.')
|
help='Key for obtaining an auth token.')
|
||||||
parser.add_option('-R', '--retries', type=int, default=5, dest='retries',
|
parser.add_option('-R', '--retries', type=int, default=5, dest='retries',
|
||||||
help='The number of times to retry a failed connection.')
|
help='The number of times to retry a failed connection.')
|
||||||
parser.add_option('--os-username',
|
|
||||||
metavar='<auth-user-name>',
|
|
||||||
default=environ.get('OS_USERNAME'),
|
|
||||||
help='OpenStack username. Defaults to env[OS_USERNAME].')
|
|
||||||
parser.add_option('--os_username',
|
|
||||||
help=SUPPRESS_HELP)
|
|
||||||
parser.add_option('--os-password',
|
|
||||||
metavar='<auth-password>',
|
|
||||||
default=environ.get('OS_PASSWORD'),
|
|
||||||
help='OpenStack password. Defaults to env[OS_PASSWORD].')
|
|
||||||
parser.add_option('--os_password',
|
|
||||||
help=SUPPRESS_HELP)
|
|
||||||
parser.add_option('--os-tenant-id',
|
|
||||||
metavar='<auth-tenant-id>',
|
|
||||||
default=environ.get('OS_TENANT_ID'),
|
|
||||||
help='OpenStack tenant ID. '
|
|
||||||
'Defaults to env[OS_TENANT_ID].')
|
|
||||||
parser.add_option('--os_tenant_id',
|
|
||||||
help=SUPPRESS_HELP)
|
|
||||||
parser.add_option('--os-tenant-name',
|
|
||||||
metavar='<auth-tenant-name>',
|
|
||||||
default=environ.get('OS_TENANT_NAME'),
|
|
||||||
help='OpenStack tenant name. '
|
|
||||||
'Defaults to env[OS_TENANT_NAME].')
|
|
||||||
parser.add_option('--os_tenant_name',
|
|
||||||
help=SUPPRESS_HELP)
|
|
||||||
parser.add_option('--os-auth-url',
|
|
||||||
metavar='<auth-url>',
|
|
||||||
default=environ.get('OS_AUTH_URL'),
|
|
||||||
help='OpenStack auth URL. Defaults to env[OS_AUTH_URL].')
|
|
||||||
parser.add_option('--os_auth_url',
|
|
||||||
help=SUPPRESS_HELP)
|
|
||||||
parser.add_option('--os-auth-token',
|
|
||||||
metavar='<auth-token>',
|
|
||||||
default=environ.get('OS_AUTH_TOKEN'),
|
|
||||||
help='OpenStack token. Defaults to env[OS_AUTH_TOKEN]. '
|
|
||||||
'Used with --os-storage-url to bypass the '
|
|
||||||
'usual username/password authentication.')
|
|
||||||
parser.add_option('--os_auth_token',
|
|
||||||
help=SUPPRESS_HELP)
|
|
||||||
parser.add_option('--os-storage-url',
|
|
||||||
metavar='<storage-url>',
|
|
||||||
default=environ.get('OS_STORAGE_URL'),
|
|
||||||
help='OpenStack storage URL. '
|
|
||||||
'Defaults to env[OS_STORAGE_URL]. '
|
|
||||||
'Overrides the storage url returned during auth. '
|
|
||||||
'Will bypass authentication when used with '
|
|
||||||
'--os-auth-token.')
|
|
||||||
parser.add_option('--os_storage_url',
|
|
||||||
help=SUPPRESS_HELP)
|
|
||||||
parser.add_option('--os-region-name',
|
|
||||||
metavar='<region-name>',
|
|
||||||
default=environ.get('OS_REGION_NAME'),
|
|
||||||
help='OpenStack region name. '
|
|
||||||
'Defaults to env[OS_REGION_NAME].')
|
|
||||||
parser.add_option('--os_region_name',
|
|
||||||
help=SUPPRESS_HELP)
|
|
||||||
parser.add_option('--os-service-type',
|
|
||||||
metavar='<service-type>',
|
|
||||||
default=environ.get('OS_SERVICE_TYPE'),
|
|
||||||
help='OpenStack Service type. '
|
|
||||||
'Defaults to env[OS_SERVICE_TYPE].')
|
|
||||||
parser.add_option('--os_service_type',
|
|
||||||
help=SUPPRESS_HELP)
|
|
||||||
parser.add_option('--os-endpoint-type',
|
|
||||||
metavar='<endpoint-type>',
|
|
||||||
default=environ.get('OS_ENDPOINT_TYPE'),
|
|
||||||
help='OpenStack Endpoint type. '
|
|
||||||
'Defaults to env[OS_ENDPOINT_TYPE].')
|
|
||||||
parser.add_option('--os-cacert',
|
|
||||||
metavar='<ca-certificate>',
|
|
||||||
default=environ.get('OS_CACERT'),
|
|
||||||
help='Specify a CA bundle file to use in verifying a '
|
|
||||||
'TLS (https) server certificate. '
|
|
||||||
'Defaults to env[OS_CACERT].')
|
|
||||||
default_val = config_true_value(environ.get('SWIFTCLIENT_INSECURE'))
|
default_val = config_true_value(environ.get('SWIFTCLIENT_INSECURE'))
|
||||||
parser.add_option('--insecure',
|
parser.add_option('--insecure',
|
||||||
action="store_true", dest="insecure",
|
action="store_true", dest="insecure",
|
||||||
@@ -1573,7 +1543,143 @@ Examples:
|
|||||||
help='This option is deprecated and not used anymore. '
|
help='This option is deprecated and not used anymore. '
|
||||||
'SSL compression should be disabled by default '
|
'SSL compression should be disabled by default '
|
||||||
'by the system SSL library.')
|
'by the system SSL library.')
|
||||||
|
|
||||||
|
os_grp = OptionGroup(parser, "OpenStack authentication options")
|
||||||
|
os_grp.add_option('--os-username',
|
||||||
|
metavar='<auth-user-name>',
|
||||||
|
default=environ.get('OS_USERNAME'),
|
||||||
|
help='OpenStack username. Defaults to env[OS_USERNAME].')
|
||||||
|
os_grp.add_option('--os_username',
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
os_grp.add_option('--os-user-id',
|
||||||
|
metavar='<auth-user-id>',
|
||||||
|
default=environ.get('OS_USER_ID'),
|
||||||
|
help='OpenStack user ID. '
|
||||||
|
'Defaults to env[OS_USER_ID].')
|
||||||
|
os_grp.add_option('--os_user_id',
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
os_grp.add_option('--os-user-domain-id',
|
||||||
|
metavar='<auth-user-domain-id>',
|
||||||
|
default=environ.get('OS_USER_DOMAIN_ID'),
|
||||||
|
help='OpenStack user domain ID. '
|
||||||
|
'Defaults to env[OS_USER_DOMAIN_ID].')
|
||||||
|
os_grp.add_option('--os_user_domain_id',
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
os_grp.add_option('--os-user-domain-name',
|
||||||
|
metavar='<auth-user-domain-name>',
|
||||||
|
default=environ.get('OS_USER_DOMAIN_NAME'),
|
||||||
|
help='OpenStack user domain name. '
|
||||||
|
'Defaults to env[OS_USER_DOMAIN_NAME].')
|
||||||
|
os_grp.add_option('--os_user_domain_name',
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
os_grp.add_option('--os-password',
|
||||||
|
metavar='<auth-password>',
|
||||||
|
default=environ.get('OS_PASSWORD'),
|
||||||
|
help='OpenStack password. Defaults to env[OS_PASSWORD].')
|
||||||
|
os_grp.add_option('--os_password',
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
os_grp.add_option('--os-tenant-id',
|
||||||
|
metavar='<auth-tenant-id>',
|
||||||
|
default=environ.get('OS_TENANT_ID'),
|
||||||
|
help='OpenStack tenant ID. '
|
||||||
|
'Defaults to env[OS_TENANT_ID].')
|
||||||
|
os_grp.add_option('--os_tenant_id',
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
os_grp.add_option('--os-tenant-name',
|
||||||
|
metavar='<auth-tenant-name>',
|
||||||
|
default=environ.get('OS_TENANT_NAME'),
|
||||||
|
help='OpenStack tenant name. '
|
||||||
|
'Defaults to env[OS_TENANT_NAME].')
|
||||||
|
os_grp.add_option('--os_tenant_name',
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
os_grp.add_option('--os-project-id',
|
||||||
|
metavar='<auth-project-id>',
|
||||||
|
default=environ.get('OS_PROJECT_ID'),
|
||||||
|
help='OpenStack project ID. '
|
||||||
|
'Defaults to env[OS_PROJECT_ID].')
|
||||||
|
os_grp.add_option('--os_project_id',
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
os_grp.add_option('--os-project-name',
|
||||||
|
metavar='<auth-project-name>',
|
||||||
|
default=environ.get('OS_PROJECT_NAME'),
|
||||||
|
help='OpenStack project name. '
|
||||||
|
'Defaults to env[OS_PROJECT_NAME].')
|
||||||
|
os_grp.add_option('--os_project_name',
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
os_grp.add_option('--os-project-domain-id',
|
||||||
|
metavar='<auth-project-domain-id>',
|
||||||
|
default=environ.get('OS_PROJECT_DOMAIN_ID'),
|
||||||
|
help='OpenStack project domain ID. '
|
||||||
|
'Defaults to env[OS_PROJECT_DOMAIN_ID].')
|
||||||
|
os_grp.add_option('--os_project_domain_id',
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
os_grp.add_option('--os-project-domain-name',
|
||||||
|
metavar='<auth-project-domain-name>',
|
||||||
|
default=environ.get('OS_PROJECT_DOMAIN_NAME'),
|
||||||
|
help='OpenStack project domain name. '
|
||||||
|
'Defaults to env[OS_PROJECT_DOMAIN_NAME].')
|
||||||
|
os_grp.add_option('--os_project_domain_name',
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
os_grp.add_option('--os-auth-url',
|
||||||
|
metavar='<auth-url>',
|
||||||
|
default=environ.get('OS_AUTH_URL'),
|
||||||
|
help='OpenStack auth URL. Defaults to env[OS_AUTH_URL].')
|
||||||
|
os_grp.add_option('--os_auth_url',
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
os_grp.add_option('--os-auth-token',
|
||||||
|
metavar='<auth-token>',
|
||||||
|
default=environ.get('OS_AUTH_TOKEN'),
|
||||||
|
help='OpenStack token. Defaults to env[OS_AUTH_TOKEN]. '
|
||||||
|
'Used with --os-storage-url to bypass the '
|
||||||
|
'usual username/password authentication.')
|
||||||
|
os_grp.add_option('--os_auth_token',
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
os_grp.add_option('--os-storage-url',
|
||||||
|
metavar='<storage-url>',
|
||||||
|
default=environ.get('OS_STORAGE_URL'),
|
||||||
|
help='OpenStack storage URL. '
|
||||||
|
'Defaults to env[OS_STORAGE_URL]. '
|
||||||
|
'Overrides the storage url returned during auth. '
|
||||||
|
'Will bypass authentication when used with '
|
||||||
|
'--os-auth-token.')
|
||||||
|
os_grp.add_option('--os_storage_url',
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
os_grp.add_option('--os-region-name',
|
||||||
|
metavar='<region-name>',
|
||||||
|
default=environ.get('OS_REGION_NAME'),
|
||||||
|
help='OpenStack region name. '
|
||||||
|
'Defaults to env[OS_REGION_NAME].')
|
||||||
|
os_grp.add_option('--os_region_name',
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
os_grp.add_option('--os-service-type',
|
||||||
|
metavar='<service-type>',
|
||||||
|
default=environ.get('OS_SERVICE_TYPE'),
|
||||||
|
help='OpenStack Service type. '
|
||||||
|
'Defaults to env[OS_SERVICE_TYPE].')
|
||||||
|
os_grp.add_option('--os_service_type',
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
os_grp.add_option('--os-endpoint-type',
|
||||||
|
metavar='<endpoint-type>',
|
||||||
|
default=environ.get('OS_ENDPOINT_TYPE'),
|
||||||
|
help='OpenStack Endpoint type. '
|
||||||
|
'Defaults to env[OS_ENDPOINT_TYPE].')
|
||||||
|
os_grp.add_option('--os_endpoint_type',
|
||||||
|
help=SUPPRESS_HELP)
|
||||||
|
os_grp.add_option('--os-cacert',
|
||||||
|
metavar='<ca-certificate>',
|
||||||
|
default=environ.get('OS_CACERT'),
|
||||||
|
help='Specify a CA bundle file to use in verifying a '
|
||||||
|
'TLS (https) server certificate. '
|
||||||
|
'Defaults to env[OS_CACERT].')
|
||||||
parser.disable_interspersed_args()
|
parser.disable_interspersed_args()
|
||||||
|
# call parse_args before adding os options group so that -h, --help will
|
||||||
|
# print a condensed help message without the os options
|
||||||
|
(options, args) = parse_args(parser, argv[1:], enforce_requires=False)
|
||||||
|
parser.add_option_group(os_grp)
|
||||||
|
if options.os_help:
|
||||||
|
# if openstack option help has been explicitly requested then force
|
||||||
|
# help message, now that os_options group has been added to parser
|
||||||
|
argv = ['-h']
|
||||||
(options, args) = parse_args(parser, argv[1:], enforce_requires=False)
|
(options, args) = parse_args(parser, argv[1:], enforce_requires=False)
|
||||||
parser.enable_interspersed_args()
|
parser.enable_interspersed_args()
|
||||||
|
|
||||||
|
@@ -4,7 +4,8 @@ auth_host = 127.0.0.1
|
|||||||
auth_port = 8080
|
auth_port = 8080
|
||||||
auth_ssl = no
|
auth_ssl = no
|
||||||
auth_prefix = /auth/
|
auth_prefix = /auth/
|
||||||
## sample config for Swift with Keystone
|
## sample config for Swift with Keystone v2 API
|
||||||
|
# For keystone v3 change auth_version to 3 and auth_prefix to /v3/
|
||||||
#auth_version = 2
|
#auth_version = 2
|
||||||
#auth_host = localhost
|
#auth_host = localhost
|
||||||
#auth_port = 5000
|
#auth_port = 5000
|
||||||
|
@@ -378,3 +378,281 @@ class TestSubcommandHelp(unittest.TestCase):
|
|||||||
self.assertRaises(SystemExit, swiftclient.shell.main, argv)
|
self.assertRaises(SystemExit, swiftclient.shell.main, argv)
|
||||||
expected = 'no help for bad_command'
|
expected = 'no help for bad_command'
|
||||||
self.assertEqual(out.getvalue().strip('\n'), expected)
|
self.assertEqual(out.getvalue().strip('\n'), expected)
|
||||||
|
|
||||||
|
|
||||||
|
class TestParsing(unittest.TestCase):
|
||||||
|
|
||||||
|
def _make_fake_command(self, result):
|
||||||
|
def fake_command(parser, args, thread_manager):
|
||||||
|
result[0], result[1] = swiftclient.shell.parse_args(parser, args)
|
||||||
|
return fake_command
|
||||||
|
|
||||||
|
def _make_args(self, cmd, opts, os_opts, separator='-'):
|
||||||
|
"""
|
||||||
|
Construct command line arguments for given options.
|
||||||
|
"""
|
||||||
|
args = [""]
|
||||||
|
for k, v in opts.items():
|
||||||
|
arg = "--" + k.replace("_", "-")
|
||||||
|
args = args + [arg, v]
|
||||||
|
for k, v in os_opts.items():
|
||||||
|
arg = "--os" + separator + k.replace("_", separator)
|
||||||
|
args = args + [arg, v]
|
||||||
|
args = args + [cmd]
|
||||||
|
return args
|
||||||
|
|
||||||
|
def _make_env(self, opts, os_opts):
|
||||||
|
"""
|
||||||
|
Construct a dict of environment variables for given options.
|
||||||
|
"""
|
||||||
|
env = {}
|
||||||
|
for k, v in opts.items():
|
||||||
|
key = 'ST_' + k.upper()
|
||||||
|
env[key] = v
|
||||||
|
for k, v in os_opts.items():
|
||||||
|
key = 'OS_' + k.upper()
|
||||||
|
env[key] = v
|
||||||
|
return env
|
||||||
|
|
||||||
|
def _verify_opts(self, actual_opts, opts, os_opts={}, os_opts_dict={}):
|
||||||
|
"""
|
||||||
|
Check parsed options are correct.
|
||||||
|
|
||||||
|
:param opts: v1 style options.
|
||||||
|
:param os_opts: openstack style options.
|
||||||
|
:param os_opts_dict: openstack options that should be found in the
|
||||||
|
os_options dict.
|
||||||
|
"""
|
||||||
|
# check the expected opts are set
|
||||||
|
for key, v in opts.items():
|
||||||
|
actual = getattr(actual_opts, key)
|
||||||
|
self.assertEqual(v, actual, 'Expected %s for key %s, found %s'
|
||||||
|
% (v, key, actual))
|
||||||
|
|
||||||
|
for key, v in os_opts.items():
|
||||||
|
actual = getattr(actual_opts, "os_" + key)
|
||||||
|
self.assertEqual(v, actual, 'Expected %s for key %s, found %s'
|
||||||
|
% (v, key, actual))
|
||||||
|
|
||||||
|
# check the os_options dict values are set
|
||||||
|
self.assertTrue(hasattr(actual_opts, 'os_options'))
|
||||||
|
actual_os_opts_dict = getattr(actual_opts, 'os_options')
|
||||||
|
expected_os_opts_keys = ['project_name', 'region_name',
|
||||||
|
'tenant_name',
|
||||||
|
'user_domain_name', 'endpoint_type',
|
||||||
|
'object_storage_url', 'project_domain_id',
|
||||||
|
'user_id', 'user_domain_id', 'tenant_id',
|
||||||
|
'service_type', 'project_id', 'auth_token',
|
||||||
|
'project_domain_name']
|
||||||
|
for key in expected_os_opts_keys:
|
||||||
|
self.assertTrue(key in actual_os_opts_dict)
|
||||||
|
cli_key = key
|
||||||
|
if key == 'object_storage_url':
|
||||||
|
# exceptions to the pattern...
|
||||||
|
cli_key = 'storage_url'
|
||||||
|
if cli_key in os_opts_dict:
|
||||||
|
expect = os_opts_dict[cli_key]
|
||||||
|
else:
|
||||||
|
expect = None
|
||||||
|
actual = actual_os_opts_dict[key]
|
||||||
|
self.assertEqual(expect, actual, 'Expected %s for %s, got %s'
|
||||||
|
% (expect, key, actual))
|
||||||
|
for key in actual_os_opts_dict:
|
||||||
|
self.assertTrue(key in expected_os_opts_keys)
|
||||||
|
|
||||||
|
# check that equivalent keys have equal values
|
||||||
|
equivalents = [('os_username', 'user'),
|
||||||
|
('os_auth_url', 'auth'),
|
||||||
|
('os_password', 'key')]
|
||||||
|
for pair in equivalents:
|
||||||
|
self.assertEqual(getattr(actual_opts, pair[0]),
|
||||||
|
getattr(actual_opts, pair[1]))
|
||||||
|
|
||||||
|
def test_minimum_required_args_v3(self):
|
||||||
|
opts = {"auth_version": "3"}
|
||||||
|
os_opts = {"password": "secret",
|
||||||
|
"username": "user",
|
||||||
|
"auth_url": "http://example.com:5000/v3"}
|
||||||
|
|
||||||
|
# username with domain is sufficient in args because keystone will
|
||||||
|
# assume user is in default domain
|
||||||
|
args = self._make_args("stat", opts, os_opts, '-')
|
||||||
|
result = [None, None]
|
||||||
|
fake_command = self._make_fake_command(result)
|
||||||
|
with mock.patch('swiftclient.shell.st_stat', fake_command):
|
||||||
|
swiftclient.shell.main(args)
|
||||||
|
self._verify_opts(result[0], opts, os_opts, {})
|
||||||
|
|
||||||
|
# check its ok to have user_id instead of username
|
||||||
|
os_opts = {"password": "secret",
|
||||||
|
"auth_url": "http://example.com:5000/v3"}
|
||||||
|
os_opts_dict = {"user_id": "user_ID"}
|
||||||
|
all_os_opts = os_opts.copy()
|
||||||
|
all_os_opts.update(os_opts_dict)
|
||||||
|
|
||||||
|
args = self._make_args("stat", opts, all_os_opts, '-')
|
||||||
|
result = [None, None]
|
||||||
|
fake_command = self._make_fake_command(result)
|
||||||
|
with mock.patch('swiftclient.shell.st_stat', fake_command):
|
||||||
|
swiftclient.shell.main(args)
|
||||||
|
self._verify_opts(result[0], opts, os_opts, os_opts_dict)
|
||||||
|
|
||||||
|
# check no user credentials required if token and url supplied
|
||||||
|
os_opts = {}
|
||||||
|
os_opts_dict = {"storage_url": "http://example.com:8080/v1",
|
||||||
|
"auth_token": "0123abcd"}
|
||||||
|
|
||||||
|
args = self._make_args("stat", opts, os_opts_dict, '-')
|
||||||
|
result = [None, None]
|
||||||
|
fake_command = self._make_fake_command(result)
|
||||||
|
with mock.patch('swiftclient.shell.st_stat', fake_command):
|
||||||
|
swiftclient.shell.main(args)
|
||||||
|
self._verify_opts(result[0], opts, os_opts, os_opts_dict)
|
||||||
|
|
||||||
|
def test_args_v3(self):
|
||||||
|
opts = {"auth_version": "3"}
|
||||||
|
os_opts = {"password": "secret",
|
||||||
|
"username": "user",
|
||||||
|
"auth_url": "http://example.com:5000/v3"}
|
||||||
|
os_opts_dict = {"user_id": "user_ID",
|
||||||
|
"project_id": "project_ID",
|
||||||
|
"tenant_id": "tenant_ID",
|
||||||
|
"project_domain_id": "project_domain_ID",
|
||||||
|
"user_domain_id": "user_domain_ID",
|
||||||
|
"tenant_name": "tenant",
|
||||||
|
"project_name": "project",
|
||||||
|
"project_domain_name": "project_domain",
|
||||||
|
"user_domain_name": "user_domain",
|
||||||
|
"auth_token": "token",
|
||||||
|
"storage_url": "http://example.com:8080/v1",
|
||||||
|
"region_name": "region",
|
||||||
|
"service_type": "service",
|
||||||
|
"endpoint_type": "endpoint"}
|
||||||
|
all_os_opts = os_opts.copy()
|
||||||
|
all_os_opts.update(os_opts_dict)
|
||||||
|
|
||||||
|
# check using hyphen separator
|
||||||
|
args = self._make_args("stat", opts, all_os_opts, '-')
|
||||||
|
result = [None, None]
|
||||||
|
fake_command = self._make_fake_command(result)
|
||||||
|
with mock.patch('swiftclient.shell.st_stat', fake_command):
|
||||||
|
swiftclient.shell.main(args)
|
||||||
|
self._verify_opts(result[0], opts, os_opts, os_opts_dict)
|
||||||
|
|
||||||
|
# check using underscore separator
|
||||||
|
args = self._make_args("stat", opts, all_os_opts, '_')
|
||||||
|
result = [None, None]
|
||||||
|
fake_command = self._make_fake_command(result)
|
||||||
|
with mock.patch('swiftclient.shell.st_stat', fake_command):
|
||||||
|
swiftclient.shell.main(args)
|
||||||
|
self._verify_opts(result[0], opts, os_opts, os_opts_dict)
|
||||||
|
|
||||||
|
# check using environment variables
|
||||||
|
args = self._make_args("stat", {}, {})
|
||||||
|
env = self._make_env(opts, all_os_opts)
|
||||||
|
result = [None, None]
|
||||||
|
fake_command = self._make_fake_command(result)
|
||||||
|
with mock.patch.dict(os.environ, env):
|
||||||
|
with mock.patch('swiftclient.shell.st_stat', fake_command):
|
||||||
|
swiftclient.shell.main(args)
|
||||||
|
self._verify_opts(result[0], opts, os_opts, os_opts_dict)
|
||||||
|
|
||||||
|
# check again using OS_AUTH_VERSION instead of ST_AUTH_VERSION
|
||||||
|
env = self._make_env({}, all_os_opts)
|
||||||
|
env.update({'OS_AUTH_VERSION': '3'})
|
||||||
|
result = [None, None]
|
||||||
|
fake_command = self._make_fake_command(result)
|
||||||
|
with mock.patch.dict(os.environ, env):
|
||||||
|
with mock.patch('swiftclient.shell.st_stat', fake_command):
|
||||||
|
swiftclient.shell.main(args)
|
||||||
|
self._verify_opts(result[0], opts, os_opts, os_opts_dict)
|
||||||
|
|
||||||
|
def test_command_args_v3(self):
|
||||||
|
result = [None, None]
|
||||||
|
fake_command = self._make_fake_command(result)
|
||||||
|
opts = {"auth_version": "3"}
|
||||||
|
os_opts = {"password": "secret",
|
||||||
|
"username": "user",
|
||||||
|
"auth_url": "http://example.com:5000/v3"}
|
||||||
|
args = self._make_args("stat", opts, os_opts)
|
||||||
|
with mock.patch('swiftclient.shell.st_stat', fake_command):
|
||||||
|
swiftclient.shell.main(args)
|
||||||
|
self.assertEqual(['stat'], result[1])
|
||||||
|
with mock.patch('swiftclient.shell.st_stat', fake_command):
|
||||||
|
args = args + ["container_name"]
|
||||||
|
swiftclient.shell.main(args)
|
||||||
|
self.assertEqual(["stat", "container_name"], result[1])
|
||||||
|
|
||||||
|
def test_insufficient_args_v3(self):
|
||||||
|
opts = {"auth_version": "3"}
|
||||||
|
os_opts = {"password": "secret",
|
||||||
|
"auth_url": "http://example.com:5000/v3"}
|
||||||
|
args = self._make_args("stat", opts, os_opts)
|
||||||
|
self.assertRaises(SystemExit, swiftclient.shell.main, args)
|
||||||
|
|
||||||
|
os_opts = {"username": "user",
|
||||||
|
"auth_url": "http://example.com:5000/v3"}
|
||||||
|
args = self._make_args("stat", opts, os_opts)
|
||||||
|
self.assertRaises(SystemExit, swiftclient.shell.main, args)
|
||||||
|
|
||||||
|
os_opts = {"username": "user",
|
||||||
|
"password": "secret"}
|
||||||
|
args = self._make_args("stat", opts, os_opts)
|
||||||
|
self.assertRaises(SystemExit, swiftclient.shell.main, args)
|
||||||
|
|
||||||
|
def test_insufficient_env_vars_v3(self):
|
||||||
|
args = self._make_args("stat", {}, {})
|
||||||
|
opts = {"auth_version": "3"}
|
||||||
|
os_opts = {"password": "secret",
|
||||||
|
"auth_url": "http://example.com:5000/v3"}
|
||||||
|
env = self._make_env(opts, os_opts)
|
||||||
|
with mock.patch.dict(os.environ, env):
|
||||||
|
self.assertRaises(SystemExit, swiftclient.shell.main, args)
|
||||||
|
|
||||||
|
os_opts = {"username": "user",
|
||||||
|
"auth_url": "http://example.com:5000/v3"}
|
||||||
|
env = self._make_env(opts, os_opts)
|
||||||
|
with mock.patch.dict(os.environ, env):
|
||||||
|
self.assertRaises(SystemExit, swiftclient.shell.main, args)
|
||||||
|
|
||||||
|
os_opts = {"username": "user",
|
||||||
|
"password": "secret"}
|
||||||
|
env = self._make_env(opts, os_opts)
|
||||||
|
with mock.patch.dict(os.environ, env):
|
||||||
|
self.assertRaises(SystemExit, swiftclient.shell.main, args)
|
||||||
|
|
||||||
|
def test_help(self):
|
||||||
|
# --help returns condensed help message
|
||||||
|
opts = {"help": ""}
|
||||||
|
os_opts = {}
|
||||||
|
args = self._make_args("stat", opts, os_opts)
|
||||||
|
mock_stdout = six.StringIO()
|
||||||
|
with mock.patch('sys.stdout', mock_stdout):
|
||||||
|
self.assertRaises(SystemExit, swiftclient.shell.main, args)
|
||||||
|
out = mock_stdout.getvalue()
|
||||||
|
self.assertTrue(out.find('[--key <api_key>]') > 0)
|
||||||
|
self.assertEqual(-1, out.find('--os-username=<auth-user-name>'))
|
||||||
|
|
||||||
|
# --help returns condensed help message, overrides --os-help
|
||||||
|
opts = {"help": ""}
|
||||||
|
os_opts = {"help": ""}
|
||||||
|
# "password": "secret",
|
||||||
|
# "username": "user",
|
||||||
|
# "auth_url": "http://example.com:5000/v3"}
|
||||||
|
args = self._make_args("", opts, os_opts)
|
||||||
|
mock_stdout = six.StringIO()
|
||||||
|
with mock.patch('sys.stdout', mock_stdout):
|
||||||
|
self.assertRaises(SystemExit, swiftclient.shell.main, args)
|
||||||
|
out = mock_stdout.getvalue()
|
||||||
|
self.assertTrue(out.find('[--key <api_key>]') > 0)
|
||||||
|
self.assertEqual(-1, out.find('--os-username=<auth-user-name>'))
|
||||||
|
|
||||||
|
## --os-help return os options help
|
||||||
|
opts = {}
|
||||||
|
args = self._make_args("", opts, os_opts)
|
||||||
|
mock_stdout = six.StringIO()
|
||||||
|
with mock.patch('sys.stdout', mock_stdout):
|
||||||
|
self.assertRaises(SystemExit, swiftclient.shell.main, args)
|
||||||
|
out = mock_stdout.getvalue()
|
||||||
|
self.assertTrue(out.find('[--key <api_key>]') > 0)
|
||||||
|
self.assertTrue(out.find('--os-username=<auth-user-name>') > 0)
|
||||||
|
@@ -30,7 +30,7 @@ from six.moves.urllib.parse import urlparse
|
|||||||
from six.moves import reload_module
|
from six.moves import reload_module
|
||||||
|
|
||||||
# TODO: mock http connection class with more control over headers
|
# TODO: mock http connection class with more control over headers
|
||||||
from .utils import fake_http_connect, fake_get_keystoneclient_2_0
|
from .utils import fake_http_connect, fake_get_auth_keystone
|
||||||
|
|
||||||
from swiftclient import client as c
|
from swiftclient import client as c
|
||||||
import swiftclient.utils
|
import swiftclient.utils
|
||||||
@@ -287,7 +287,9 @@ class TestGetAuth(MockHttpTest):
|
|||||||
|
|
||||||
def test_auth_v2_with_tenant_name(self):
|
def test_auth_v2_with_tenant_name(self):
|
||||||
os_options = {'tenant_name': 'asdf'}
|
os_options = {'tenant_name': 'asdf'}
|
||||||
c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0(os_options)
|
req_args = {'auth_version': '2.0'}
|
||||||
|
c.get_auth_keystone = fake_get_auth_keystone(os_options,
|
||||||
|
required_kwargs=req_args)
|
||||||
url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
|
url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
|
||||||
os_options=os_options,
|
os_options=os_options,
|
||||||
auth_version="2.0")
|
auth_version="2.0")
|
||||||
@@ -296,7 +298,31 @@ class TestGetAuth(MockHttpTest):
|
|||||||
|
|
||||||
def test_auth_v2_with_tenant_id(self):
|
def test_auth_v2_with_tenant_id(self):
|
||||||
os_options = {'tenant_id': 'asdf'}
|
os_options = {'tenant_id': 'asdf'}
|
||||||
c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0(os_options)
|
req_args = {'auth_version': '2.0'}
|
||||||
|
c.get_auth_keystone = fake_get_auth_keystone(os_options,
|
||||||
|
required_kwargs=req_args)
|
||||||
|
url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
|
||||||
|
os_options=os_options,
|
||||||
|
auth_version="2.0")
|
||||||
|
self.assertTrue(url.startswith("http"))
|
||||||
|
self.assertTrue(token)
|
||||||
|
|
||||||
|
def test_auth_v2_with_project_name(self):
|
||||||
|
os_options = {'project_name': 'asdf'}
|
||||||
|
req_args = {'auth_version': '2.0'}
|
||||||
|
c.get_auth_keystone = fake_get_auth_keystone(os_options,
|
||||||
|
required_kwargs=req_args)
|
||||||
|
url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
|
||||||
|
os_options=os_options,
|
||||||
|
auth_version="2.0")
|
||||||
|
self.assertTrue(url.startswith("http"))
|
||||||
|
self.assertTrue(token)
|
||||||
|
|
||||||
|
def test_auth_v2_with_project_id(self):
|
||||||
|
os_options = {'project_id': 'asdf'}
|
||||||
|
req_args = {'auth_version': '2.0'}
|
||||||
|
c.get_auth_keystone = fake_get_auth_keystone(os_options,
|
||||||
|
required_kwargs=req_args)
|
||||||
url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
|
url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
|
||||||
os_options=os_options,
|
os_options=os_options,
|
||||||
auth_version="2.0")
|
auth_version="2.0")
|
||||||
@@ -304,7 +330,7 @@ class TestGetAuth(MockHttpTest):
|
|||||||
self.assertTrue(token)
|
self.assertTrue(token)
|
||||||
|
|
||||||
def test_auth_v2_no_tenant_name_or_tenant_id(self):
|
def test_auth_v2_no_tenant_name_or_tenant_id(self):
|
||||||
c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0({})
|
c.get_auth_keystone = fake_get_auth_keystone({})
|
||||||
self.assertRaises(c.ClientException, c.get_auth,
|
self.assertRaises(c.ClientException, c.get_auth,
|
||||||
'http://www.tests.com', 'asdf', 'asdf',
|
'http://www.tests.com', 'asdf', 'asdf',
|
||||||
os_options={},
|
os_options={},
|
||||||
@@ -313,7 +339,7 @@ class TestGetAuth(MockHttpTest):
|
|||||||
def test_auth_v2_with_tenant_name_none_and_tenant_id_none(self):
|
def test_auth_v2_with_tenant_name_none_and_tenant_id_none(self):
|
||||||
os_options = {'tenant_name': None,
|
os_options = {'tenant_name': None,
|
||||||
'tenant_id': None}
|
'tenant_id': None}
|
||||||
c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0(os_options)
|
c.get_auth_keystone = fake_get_auth_keystone(os_options)
|
||||||
self.assertRaises(c.ClientException, c.get_auth,
|
self.assertRaises(c.ClientException, c.get_auth,
|
||||||
'http://www.tests.com', 'asdf', 'asdf',
|
'http://www.tests.com', 'asdf', 'asdf',
|
||||||
os_options=os_options,
|
os_options=os_options,
|
||||||
@@ -321,7 +347,7 @@ class TestGetAuth(MockHttpTest):
|
|||||||
|
|
||||||
def test_auth_v2_with_tenant_user_in_user(self):
|
def test_auth_v2_with_tenant_user_in_user(self):
|
||||||
tenant_option = {'tenant_name': 'foo'}
|
tenant_option = {'tenant_name': 'foo'}
|
||||||
c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0(tenant_option)
|
c.get_auth_keystone = fake_get_auth_keystone(tenant_option)
|
||||||
url, token = c.get_auth('http://www.test.com', 'foo:bar', 'asdf',
|
url, token = c.get_auth('http://www.test.com', 'foo:bar', 'asdf',
|
||||||
os_options={},
|
os_options={},
|
||||||
auth_version="2.0")
|
auth_version="2.0")
|
||||||
@@ -330,7 +356,7 @@ class TestGetAuth(MockHttpTest):
|
|||||||
|
|
||||||
def test_auth_v2_tenant_name_no_os_options(self):
|
def test_auth_v2_tenant_name_no_os_options(self):
|
||||||
tenant_option = {'tenant_name': 'asdf'}
|
tenant_option = {'tenant_name': 'asdf'}
|
||||||
c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0(tenant_option)
|
c.get_auth_keystone = fake_get_auth_keystone(tenant_option)
|
||||||
url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
|
url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
|
||||||
tenant_name='asdf',
|
tenant_name='asdf',
|
||||||
os_options={},
|
os_options={},
|
||||||
@@ -342,7 +368,7 @@ class TestGetAuth(MockHttpTest):
|
|||||||
os_options = {'service_type': 'object-store',
|
os_options = {'service_type': 'object-store',
|
||||||
'endpoint_type': 'internalURL',
|
'endpoint_type': 'internalURL',
|
||||||
'tenant_name': 'asdf'}
|
'tenant_name': 'asdf'}
|
||||||
c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0(os_options)
|
c.get_auth_keystone = fake_get_auth_keystone(os_options)
|
||||||
url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
|
url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
|
||||||
os_options=os_options,
|
os_options=os_options,
|
||||||
auth_version="2.0")
|
auth_version="2.0")
|
||||||
@@ -351,7 +377,7 @@ class TestGetAuth(MockHttpTest):
|
|||||||
|
|
||||||
def test_auth_v2_with_tenant_user_in_user_no_os_options(self):
|
def test_auth_v2_with_tenant_user_in_user_no_os_options(self):
|
||||||
tenant_option = {'tenant_name': 'foo'}
|
tenant_option = {'tenant_name': 'foo'}
|
||||||
c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0(tenant_option)
|
c.get_auth_keystone = fake_get_auth_keystone(tenant_option)
|
||||||
url, token = c.get_auth('http://www.test.com', 'foo:bar', 'asdf',
|
url, token = c.get_auth('http://www.test.com', 'foo:bar', 'asdf',
|
||||||
auth_version="2.0")
|
auth_version="2.0")
|
||||||
self.assertTrue(url.startswith("http"))
|
self.assertTrue(url.startswith("http"))
|
||||||
@@ -360,7 +386,7 @@ class TestGetAuth(MockHttpTest):
|
|||||||
def test_auth_v2_with_os_region_name(self):
|
def test_auth_v2_with_os_region_name(self):
|
||||||
os_options = {'region_name': 'good-region',
|
os_options = {'region_name': 'good-region',
|
||||||
'tenant_name': 'asdf'}
|
'tenant_name': 'asdf'}
|
||||||
c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0(os_options)
|
c.get_auth_keystone = fake_get_auth_keystone(os_options)
|
||||||
url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
|
url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
|
||||||
os_options=os_options,
|
os_options=os_options,
|
||||||
auth_version="2.0")
|
auth_version="2.0")
|
||||||
@@ -370,14 +396,14 @@ class TestGetAuth(MockHttpTest):
|
|||||||
def test_auth_v2_no_endpoint(self):
|
def test_auth_v2_no_endpoint(self):
|
||||||
os_options = {'region_name': 'unknown_region',
|
os_options = {'region_name': 'unknown_region',
|
||||||
'tenant_name': 'asdf'}
|
'tenant_name': 'asdf'}
|
||||||
c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0(
|
c.get_auth_keystone = fake_get_auth_keystone(
|
||||||
os_options, c.ClientException)
|
os_options, c.ClientException)
|
||||||
self.assertRaises(c.ClientException, c.get_auth,
|
self.assertRaises(c.ClientException, c.get_auth,
|
||||||
'http://www.tests.com', 'asdf', 'asdf',
|
'http://www.tests.com', 'asdf', 'asdf',
|
||||||
os_options=os_options, auth_version='2.0')
|
os_options=os_options, auth_version='2.0')
|
||||||
|
|
||||||
def test_auth_v2_ks_exception(self):
|
def test_auth_v2_ks_exception(self):
|
||||||
c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0(
|
c.get_auth_keystone = fake_get_auth_keystone(
|
||||||
{}, c.ClientException)
|
{}, c.ClientException)
|
||||||
self.assertRaises(c.ClientException, c.get_auth,
|
self.assertRaises(c.ClientException, c.get_auth,
|
||||||
'http://www.tests.com', 'asdf', 'asdf',
|
'http://www.tests.com', 'asdf', 'asdf',
|
||||||
@@ -386,7 +412,7 @@ class TestGetAuth(MockHttpTest):
|
|||||||
|
|
||||||
def test_auth_v2_cacert(self):
|
def test_auth_v2_cacert(self):
|
||||||
os_options = {'tenant_name': 'foo'}
|
os_options = {'tenant_name': 'foo'}
|
||||||
c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0(
|
c.get_auth_keystone = fake_get_auth_keystone(
|
||||||
os_options, None)
|
os_options, None)
|
||||||
|
|
||||||
auth_url_secure = 'https://www.tests.com'
|
auth_url_secure = 'https://www.tests.com'
|
||||||
@@ -414,7 +440,7 @@ class TestGetAuth(MockHttpTest):
|
|||||||
|
|
||||||
def test_auth_v2_insecure(self):
|
def test_auth_v2_insecure(self):
|
||||||
os_options = {'tenant_name': 'foo'}
|
os_options = {'tenant_name': 'foo'}
|
||||||
c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0(
|
c.get_auth_keystone = fake_get_auth_keystone(
|
||||||
os_options, None)
|
os_options, None)
|
||||||
|
|
||||||
auth_url_secure = 'https://www.tests.com'
|
auth_url_secure = 'https://www.tests.com'
|
||||||
@@ -439,6 +465,29 @@ class TestGetAuth(MockHttpTest):
|
|||||||
os_options=os_options, auth_version='2.0',
|
os_options=os_options, auth_version='2.0',
|
||||||
insecure=False)
|
insecure=False)
|
||||||
|
|
||||||
|
def test_auth_v3_with_tenant_name(self):
|
||||||
|
# check the correct auth version is passed to get_auth_keystone
|
||||||
|
os_options = {'tenant_name': 'asdf'}
|
||||||
|
req_args = {'auth_version': '3'}
|
||||||
|
c.get_auth_keystone = fake_get_auth_keystone(os_options,
|
||||||
|
required_kwargs=req_args)
|
||||||
|
url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
|
||||||
|
os_options=os_options,
|
||||||
|
auth_version="3")
|
||||||
|
self.assertTrue(url.startswith("http"))
|
||||||
|
self.assertTrue(token)
|
||||||
|
|
||||||
|
def test_get_keystone_client_2_0(self):
|
||||||
|
# check the correct auth version is passed to get_auth_keystone
|
||||||
|
os_options = {'tenant_name': 'asdf'}
|
||||||
|
req_args = {'auth_version': '2.0'}
|
||||||
|
c.get_auth_keystone = fake_get_auth_keystone(os_options,
|
||||||
|
required_kwargs=req_args)
|
||||||
|
url, token = c.get_keystoneclient_2_0('http://www.test.com', 'asdf',
|
||||||
|
'asdf', os_options=os_options)
|
||||||
|
self.assertTrue(url.startswith("http"))
|
||||||
|
self.assertTrue(token)
|
||||||
|
|
||||||
|
|
||||||
class TestGetAccount(MockHttpTest):
|
class TestGetAccount(MockHttpTest):
|
||||||
|
|
||||||
|
@@ -16,8 +16,8 @@ from requests import RequestException
|
|||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
|
|
||||||
def fake_get_keystoneclient_2_0(os_options, exc=None, **kwargs):
|
def fake_get_auth_keystone(os_options, exc=None, **kwargs):
|
||||||
def fake_get_keystoneclient_2_0(auth_url,
|
def fake_get_auth_keystone(auth_url,
|
||||||
user,
|
user,
|
||||||
key,
|
key,
|
||||||
actual_os_options, **actual_kwargs):
|
actual_os_options, **actual_kwargs):
|
||||||
@@ -37,9 +37,13 @@ def fake_get_keystoneclient_2_0(os_options, exc=None, **kwargs):
|
|||||||
actual_kwargs['cacert'] is None:
|
actual_kwargs['cacert'] is None:
|
||||||
from swiftclient import client as c
|
from swiftclient import client as c
|
||||||
raise c.ClientException("unverified-certificate")
|
raise c.ClientException("unverified-certificate")
|
||||||
|
if 'required_kwargs' in kwargs:
|
||||||
|
for k, v in kwargs['required_kwargs'].items():
|
||||||
|
if v != actual_kwargs.get(k):
|
||||||
|
return "", None
|
||||||
|
|
||||||
return "http://url/", "token"
|
return "http://url/", "token"
|
||||||
return fake_get_keystoneclient_2_0
|
return fake_get_auth_keystone
|
||||||
|
|
||||||
|
|
||||||
def fake_http_connect(*code_iter, **kwargs):
|
def fake_http_connect(*code_iter, **kwargs):
|
||||||
|
Reference in New Issue
Block a user