Merge "Create a discoverable plugin"
This commit is contained in:
commit
84c5ddddef
@ -230,6 +230,13 @@ def option_parser():
|
|||||||
default=env('OS_PASSWORD'),
|
default=env('OS_PASSWORD'),
|
||||||
help='Authentication password (Env: OS_PASSWORD)',
|
help='Authentication password (Env: OS_PASSWORD)',
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--os-access-info',
|
||||||
|
dest='access_info',
|
||||||
|
metavar='<access-info>',
|
||||||
|
default=env('OS_ACCESS_INFO'),
|
||||||
|
help='Access info (Env: OS_ACCESS_INFO)',
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--os-api-name',
|
'--os-api-name',
|
||||||
dest='user_preferences',
|
dest='user_preferences',
|
||||||
|
78
openstack/auth/identity/discoverable.py
Normal file
78
openstack/auth/identity/discoverable.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Identity discoverable authorization plugin must be constructed with an
|
||||||
|
auhorization URL and a user id, user name or token. A user id or user name
|
||||||
|
would also require a password. The arguments that apply to the selected v2
|
||||||
|
or v3 plugin will be used. The rest of the arguments will be ignored. For
|
||||||
|
example::
|
||||||
|
|
||||||
|
from openstack.auth.identity import discoverable
|
||||||
|
from openstack import transport
|
||||||
|
|
||||||
|
args = {
|
||||||
|
'password': 'openSesame',
|
||||||
|
'auth_url': 'https://10.1.1.1:5000/v3/',
|
||||||
|
'user_name': 'alibaba',
|
||||||
|
}
|
||||||
|
auth = discoverable.Auth(**args)
|
||||||
|
xport = transport.Transport()
|
||||||
|
accessInfo = auth.authorize(xport)
|
||||||
|
"""
|
||||||
|
|
||||||
|
from openstack.auth.identity import base
|
||||||
|
from openstack.auth.identity import v2
|
||||||
|
from openstack.auth.identity import v3
|
||||||
|
from openstack import exceptions
|
||||||
|
|
||||||
|
|
||||||
|
class Auth(base.BaseIdentityPlugin):
|
||||||
|
|
||||||
|
#: Valid options for this plugin
|
||||||
|
valid_options = list(set(v2.Auth.valid_options + v3.Auth.valid_options))
|
||||||
|
|
||||||
|
def __init__(self, auth_url=None, **auth_args):
|
||||||
|
"""Construct an Identity Authentication Plugin.
|
||||||
|
|
||||||
|
This authorization plugin should be constructed with an auth_url
|
||||||
|
and everything needed by either a v2 or v3 identity plugin.
|
||||||
|
|
||||||
|
:param string auth_url: Identity service endpoint for authentication.
|
||||||
|
|
||||||
|
:raises TypeError: if a user_id, user_name or token is not provided.
|
||||||
|
"""
|
||||||
|
|
||||||
|
super(Auth, self).__init__(auth_url=auth_url)
|
||||||
|
|
||||||
|
if not auth_url:
|
||||||
|
msg = ("The authorization URL auth_url was not provided.")
|
||||||
|
raise exceptions.AuthorizationFailure(msg)
|
||||||
|
endpoint_version = auth_url.split('v')[-1][0]
|
||||||
|
if endpoint_version == '2':
|
||||||
|
plugin = v2.Auth
|
||||||
|
else:
|
||||||
|
plugin = v3.Auth
|
||||||
|
valid_list = plugin.valid_options
|
||||||
|
args = dict((n, auth_args[n]) for n in valid_list if n in auth_args)
|
||||||
|
self.auth_plugin = plugin(auth_url, **args)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def token_url(self):
|
||||||
|
"""The full URL where we will send authentication data."""
|
||||||
|
return self.auth_plugin.token_url
|
||||||
|
|
||||||
|
def authorize(self, transport, **kwargs):
|
||||||
|
return self.auth_plugin.authorize(transport, **kwargs)
|
||||||
|
|
||||||
|
def invalidate(self):
|
||||||
|
return self.auth_plugin.invalidate()
|
@ -41,6 +41,7 @@ class Auth(base.BaseIdentityPlugin):
|
|||||||
|
|
||||||
#: Valid options for this plugin
|
#: Valid options for this plugin
|
||||||
valid_options = [
|
valid_options = [
|
||||||
|
'access_info',
|
||||||
'auth_url',
|
'auth_url',
|
||||||
'user_name',
|
'user_name',
|
||||||
'user_id',
|
'user_id',
|
||||||
@ -53,6 +54,7 @@ class Auth(base.BaseIdentityPlugin):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, auth_url,
|
def __init__(self, auth_url,
|
||||||
|
access_info=None,
|
||||||
user_name=None,
|
user_name=None,
|
||||||
user_id=None,
|
user_id=None,
|
||||||
password='',
|
password='',
|
||||||
@ -68,6 +70,7 @@ class Auth(base.BaseIdentityPlugin):
|
|||||||
:class:`~openstack.auth.identity.base.BaseIdentityPlugin`.
|
:class:`~openstack.auth.identity.base.BaseIdentityPlugin`.
|
||||||
|
|
||||||
:param string auth_url: Identity service endpoint for authorization.
|
:param string auth_url: Identity service endpoint for authorization.
|
||||||
|
:param string access_info: Access info from previous authentication.
|
||||||
:param string user_name: Username for authentication.
|
:param string user_name: Username for authentication.
|
||||||
:param string user_id: User ID for authentication.
|
:param string user_id: User ID for authentication.
|
||||||
:param string password: Password for authentication.
|
:param string password: Password for authentication.
|
||||||
@ -86,6 +89,7 @@ class Auth(base.BaseIdentityPlugin):
|
|||||||
msg = 'You need to specify either a user_name, user_id or token'
|
msg = 'You need to specify either a user_name, user_id or token'
|
||||||
raise TypeError(msg)
|
raise TypeError(msg)
|
||||||
|
|
||||||
|
self.access_info = access_info or None
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
self.user_name = user_name
|
self.user_name = user_name
|
||||||
self.password = password
|
self.password = password
|
||||||
@ -96,6 +100,9 @@ class Auth(base.BaseIdentityPlugin):
|
|||||||
|
|
||||||
def authorize(self, transport, **kwargs):
|
def authorize(self, transport, **kwargs):
|
||||||
"""Obtain access information from an OpenStack Identity Service."""
|
"""Obtain access information from an OpenStack Identity Service."""
|
||||||
|
if self.token and self.access_info:
|
||||||
|
return access.AccessInfoV2(**self.access_info)
|
||||||
|
|
||||||
headers = {'Accept': 'application/json'}
|
headers = {'Accept': 'application/json'}
|
||||||
url = self.auth_url.rstrip('/') + '/tokens'
|
url = self.auth_url.rstrip('/') + '/tokens'
|
||||||
params = {'auth': self.get_auth_data(headers)}
|
params = {'auth': self.get_auth_data(headers)}
|
||||||
@ -132,6 +139,7 @@ class Auth(base.BaseIdentityPlugin):
|
|||||||
def invalidate(self):
|
def invalidate(self):
|
||||||
"""Invalidate the current authentication data."""
|
"""Invalidate the current authentication data."""
|
||||||
if super(Auth, self).invalidate():
|
if super(Auth, self).invalidate():
|
||||||
|
self.access_info = None
|
||||||
self.token = None
|
self.token = None
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
@ -44,6 +44,7 @@ class Auth(base.BaseIdentityPlugin):
|
|||||||
|
|
||||||
#: Valid options for this plugin
|
#: Valid options for this plugin
|
||||||
valid_options = [
|
valid_options = [
|
||||||
|
'access_info',
|
||||||
'auth_url',
|
'auth_url',
|
||||||
'domain_id',
|
'domain_id',
|
||||||
'domain_name',
|
'domain_name',
|
||||||
@ -62,6 +63,7 @@ class Auth(base.BaseIdentityPlugin):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, auth_url,
|
def __init__(self, auth_url,
|
||||||
|
access_info=None,
|
||||||
domain_id=None,
|
domain_id=None,
|
||||||
domain_name=None,
|
domain_name=None,
|
||||||
password='',
|
password='',
|
||||||
@ -84,6 +86,7 @@ class Auth(base.BaseIdentityPlugin):
|
|||||||
base class :class:`~openstack.auth.identity.base.BaseIdentityPlugin`.
|
base class :class:`~openstack.auth.identity.base.BaseIdentityPlugin`.
|
||||||
|
|
||||||
:param string auth_url: Identity service endpoint for authentication.
|
:param string auth_url: Identity service endpoint for authentication.
|
||||||
|
:param string access_info: Access info including service catalog.
|
||||||
:param string domain_id: Domain ID for domain scoping.
|
:param string domain_id: Domain ID for domain scoping.
|
||||||
:param string domain_name: Domain name for domain scoping.
|
:param string domain_name: Domain name for domain scoping.
|
||||||
:param string password: User password for authentication.
|
:param string password: User password for authentication.
|
||||||
@ -109,6 +112,7 @@ class Auth(base.BaseIdentityPlugin):
|
|||||||
msg = 'You need to specify either a user_name, user_id or token'
|
msg = 'You need to specify either a user_name, user_id or token'
|
||||||
raise TypeError(msg)
|
raise TypeError(msg)
|
||||||
|
|
||||||
|
self.access_info = access_info
|
||||||
self.domain_id = domain_id
|
self.domain_id = domain_id
|
||||||
self.domain_name = domain_name
|
self.domain_name = domain_name
|
||||||
self.project_domain_id = project_domain_id
|
self.project_domain_id = project_domain_id
|
||||||
@ -128,6 +132,7 @@ class Auth(base.BaseIdentityPlugin):
|
|||||||
self.token_method = TokenMethod(token=token)
|
self.token_method = TokenMethod(token=token)
|
||||||
self.auth_methods = [self.token_method]
|
self.auth_methods = [self.token_method]
|
||||||
else:
|
else:
|
||||||
|
self.token_method = None
|
||||||
self.auth_methods = [self.password_method]
|
self.auth_methods = [self.password_method]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -141,6 +146,10 @@ class Auth(base.BaseIdentityPlugin):
|
|||||||
body = {'auth': {'identity': {}}}
|
body = {'auth': {'identity': {}}}
|
||||||
ident = body['auth']['identity']
|
ident = body['auth']['identity']
|
||||||
|
|
||||||
|
if self.token_method and self.access_info:
|
||||||
|
return access.AccessInfoV3(self.token_method.token,
|
||||||
|
**self.access_info)
|
||||||
|
|
||||||
for method in self.auth_methods:
|
for method in self.auth_methods:
|
||||||
name, auth_data = method.get_auth_data(transport, self, headers)
|
name, auth_data = method.get_auth_data(transport, self, headers)
|
||||||
ident.setdefault('methods', []).append(name)
|
ident.setdefault('methods', []).append(name)
|
||||||
@ -192,6 +201,7 @@ class Auth(base.BaseIdentityPlugin):
|
|||||||
"""Invalidate the current authentication data."""
|
"""Invalidate the current authentication data."""
|
||||||
if super(Auth, self).invalidate():
|
if super(Auth, self).invalidate():
|
||||||
self.auth_methods = [self.password_method]
|
self.auth_methods = [self.password_method]
|
||||||
|
self.access_info = None
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -63,7 +63,6 @@ import sys
|
|||||||
|
|
||||||
from stevedore import driver
|
from stevedore import driver
|
||||||
|
|
||||||
from openstack import exceptions
|
|
||||||
from openstack import session
|
from openstack import session
|
||||||
from openstack import transport as xport
|
from openstack import transport as xport
|
||||||
|
|
||||||
@ -142,15 +141,7 @@ class Connection(object):
|
|||||||
if authenticator:
|
if authenticator:
|
||||||
return authenticator
|
return authenticator
|
||||||
if auth_plugin is None:
|
if auth_plugin is None:
|
||||||
if 'auth_url' not in auth_args:
|
auth_plugin = 'identity'
|
||||||
msg = ("auth_url was not provided.")
|
|
||||||
raise exceptions.AuthorizationFailure(msg)
|
|
||||||
auth_url = auth_args['auth_url']
|
|
||||||
endpoint_version = auth_url.split('v')[-1][0]
|
|
||||||
if endpoint_version == '2':
|
|
||||||
auth_plugin = 'identity_v2'
|
|
||||||
else:
|
|
||||||
auth_plugin = 'identity_v3'
|
|
||||||
|
|
||||||
mgr = driver.DriverManager(
|
mgr = driver.DriverManager(
|
||||||
namespace=self.AUTH_PLUGIN_NAMESPACE,
|
namespace=self.AUTH_PLUGIN_NAMESPACE,
|
||||||
|
97
openstack/tests/auth/identity/test_discoverable.py
Normal file
97
openstack/tests/auth/identity/test_discoverable.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
import mock
|
||||||
|
import testtools
|
||||||
|
|
||||||
|
from openstack.auth.identity import discoverable
|
||||||
|
from openstack import exceptions
|
||||||
|
from openstack.tests.auth import common
|
||||||
|
|
||||||
|
|
||||||
|
class TestDiscoverableAuth(testtools.TestCase):
|
||||||
|
def test_valid_options(self):
|
||||||
|
expected = [
|
||||||
|
'access_info',
|
||||||
|
'auth_url',
|
||||||
|
'domain_id',
|
||||||
|
'domain_name',
|
||||||
|
'password',
|
||||||
|
'project_domain_id',
|
||||||
|
'project_domain_name',
|
||||||
|
'project_id',
|
||||||
|
'project_name',
|
||||||
|
'reauthenticate',
|
||||||
|
'token',
|
||||||
|
'trust_id',
|
||||||
|
'user_domain_id',
|
||||||
|
'user_domain_name',
|
||||||
|
'user_id',
|
||||||
|
'user_name',
|
||||||
|
]
|
||||||
|
self.assertEqual(expected, sorted(discoverable.Auth.valid_options))
|
||||||
|
|
||||||
|
def test_create2(self):
|
||||||
|
auth_args = {
|
||||||
|
'auth_url': 'http://localhost/v2',
|
||||||
|
'user_name': '1',
|
||||||
|
'password': '2',
|
||||||
|
}
|
||||||
|
auth = discoverable.Auth(**auth_args)
|
||||||
|
self.assertEqual('openstack.auth.identity.v2',
|
||||||
|
auth.auth_plugin.__class__.__module__)
|
||||||
|
|
||||||
|
def test_create3(self):
|
||||||
|
auth_args = {
|
||||||
|
'auth_url': 'http://localhost/v3',
|
||||||
|
'user_name': '1',
|
||||||
|
'password': '2',
|
||||||
|
}
|
||||||
|
auth = discoverable.Auth(**auth_args)
|
||||||
|
self.assertEqual('openstack.auth.identity.v3',
|
||||||
|
auth.auth_plugin.__class__.__module__)
|
||||||
|
|
||||||
|
def test_create_who_knows(self):
|
||||||
|
auth_args = {
|
||||||
|
'auth_url': 'http://localhost:5000/',
|
||||||
|
'user_name': '1',
|
||||||
|
'password': '2',
|
||||||
|
}
|
||||||
|
auth = discoverable.Auth(**auth_args)
|
||||||
|
self.assertEqual('openstack.auth.identity.v3',
|
||||||
|
auth.auth_plugin.__class__.__module__)
|
||||||
|
|
||||||
|
def test_create_authenticator_no_nothing(self):
|
||||||
|
self.assertRaises(
|
||||||
|
exceptions.AuthorizationFailure,
|
||||||
|
discoverable.Auth,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_methods(self):
|
||||||
|
auth_args = {
|
||||||
|
'auth_url': 'http://localhost:5000/',
|
||||||
|
'user_name': '1',
|
||||||
|
'password': '2',
|
||||||
|
}
|
||||||
|
auth = discoverable.Auth(**auth_args)
|
||||||
|
self.assertEqual('http://localhost:5000/auth/tokens', auth.token_url)
|
||||||
|
xport = mock.MagicMock()
|
||||||
|
xport.post = mock.Mock()
|
||||||
|
response = mock.Mock()
|
||||||
|
response.json = mock.Mock()
|
||||||
|
response.json.return_value = common.TEST_RESPONSE_DICT_V3
|
||||||
|
response.headers = {'X-Subject-Token': common.TEST_SUBJECT}
|
||||||
|
xport.post.return_value = response
|
||||||
|
|
||||||
|
result = auth.authorize(xport)
|
||||||
|
self.assertEqual(common.TEST_SUBJECT, result.auth_token)
|
||||||
|
self.assertEqual(True, auth.invalidate())
|
@ -170,6 +170,20 @@ class TestV2Auth(testtools.TestCase):
|
|||||||
ecatalog['version'] = 'v2.0'
|
ecatalog['version'] = 'v2.0'
|
||||||
self.assertEqual(ecatalog, resp._info)
|
self.assertEqual(ecatalog, resp._info)
|
||||||
|
|
||||||
|
def test_authorize_token_access_info(self):
|
||||||
|
ecatalog = TEST_RESPONSE_DICT['access'].copy()
|
||||||
|
ecatalog['version'] = 'v2.0'
|
||||||
|
kargs = {
|
||||||
|
'access_info': ecatalog,
|
||||||
|
'token': common.TEST_TOKEN,
|
||||||
|
}
|
||||||
|
sot = v2.Auth(TEST_URL, **kargs)
|
||||||
|
xport = self.create_mock_transport(TEST_RESPONSE_DICT)
|
||||||
|
|
||||||
|
resp = sot.authorize(xport)
|
||||||
|
|
||||||
|
self.assertEqual(ecatalog, resp._info)
|
||||||
|
|
||||||
def test_authorize_bad_response(self):
|
def test_authorize_bad_response(self):
|
||||||
kargs = {'token': common.TEST_TOKEN}
|
kargs = {'token': common.TEST_TOKEN}
|
||||||
sot = v2.Auth(TEST_URL, **kargs)
|
sot = v2.Auth(TEST_URL, **kargs)
|
||||||
@ -179,6 +193,7 @@ class TestV2Auth(testtools.TestCase):
|
|||||||
|
|
||||||
def test_invalidate(self):
|
def test_invalidate(self):
|
||||||
kargs = {
|
kargs = {
|
||||||
|
'access_info': {'a': 'b'},
|
||||||
'password': common.TEST_PASS,
|
'password': common.TEST_PASS,
|
||||||
'token': common.TEST_TOKEN,
|
'token': common.TEST_TOKEN,
|
||||||
'user_name': common.TEST_USER,
|
'user_name': common.TEST_USER,
|
||||||
@ -194,11 +209,14 @@ class TestV2Auth(testtools.TestCase):
|
|||||||
expected = {'passwordCredentials': {'password': common.TEST_PASS,
|
expected = {'passwordCredentials': {'password': common.TEST_PASS,
|
||||||
'username': common.TEST_USER}}
|
'username': common.TEST_USER}}
|
||||||
headers = {}
|
headers = {}
|
||||||
|
self.assertEqual(None, sot.token)
|
||||||
|
self.assertEqual(None, sot.access_info)
|
||||||
self.assertEqual(expected, sot.get_auth_data(headers))
|
self.assertEqual(expected, sot.get_auth_data(headers))
|
||||||
self.assertEqual({}, headers)
|
self.assertEqual({}, headers)
|
||||||
|
|
||||||
def test_valid_options(self):
|
def test_valid_options(self):
|
||||||
expected = [
|
expected = [
|
||||||
|
'access_info',
|
||||||
'auth_url',
|
'auth_url',
|
||||||
'user_name',
|
'user_name',
|
||||||
'user_id',
|
'user_id',
|
||||||
|
@ -138,6 +138,21 @@ class TestV3Auth(testtools.TestCase):
|
|||||||
ecatalog['version'] = 'v3'
|
ecatalog['version'] = 'v3'
|
||||||
self.assertEqual(ecatalog, resp._info)
|
self.assertEqual(ecatalog, resp._info)
|
||||||
|
|
||||||
|
def test_authorize_token_access_info(self):
|
||||||
|
ecatalog = common.TEST_RESPONSE_DICT_V3['token'].copy()
|
||||||
|
kargs = {
|
||||||
|
'access_info': ecatalog,
|
||||||
|
'token': common.TEST_TOKEN,
|
||||||
|
}
|
||||||
|
sot = v3.Auth(TEST_URL, **kargs)
|
||||||
|
xport = self.create_mock_transport(common.TEST_RESPONSE_DICT_V3)
|
||||||
|
|
||||||
|
resp = sot.authorize(xport)
|
||||||
|
|
||||||
|
ecatalog['auth_token'] = common.TEST_TOKEN
|
||||||
|
ecatalog['version'] = 'v3'
|
||||||
|
self.assertEqual(ecatalog, resp._info)
|
||||||
|
|
||||||
def test_authorize_token_domain_id(self):
|
def test_authorize_token_domain_id(self):
|
||||||
kargs = {
|
kargs = {
|
||||||
'domain_id': common.TEST_DOMAIN_ID,
|
'domain_id': common.TEST_DOMAIN_ID,
|
||||||
@ -317,6 +332,7 @@ class TestV3Auth(testtools.TestCase):
|
|||||||
'user_name': common.TEST_USER,
|
'user_name': common.TEST_USER,
|
||||||
'password': common.TEST_PASS,
|
'password': common.TEST_PASS,
|
||||||
'token': common.TEST_TOKEN,
|
'token': common.TEST_TOKEN,
|
||||||
|
'access_info': {},
|
||||||
}
|
}
|
||||||
sot = v3.Auth(TEST_URL, **kargs)
|
sot = v3.Auth(TEST_URL, **kargs)
|
||||||
self.assertEqual(1, len(sot.auth_methods))
|
self.assertEqual(1, len(sot.auth_methods))
|
||||||
@ -325,6 +341,7 @@ class TestV3Auth(testtools.TestCase):
|
|||||||
|
|
||||||
self.assertEqual(True, sot.invalidate())
|
self.assertEqual(True, sot.invalidate())
|
||||||
|
|
||||||
|
self.assertEqual(None, sot.access_info)
|
||||||
self.assertEqual(1, len(sot.auth_methods))
|
self.assertEqual(1, len(sot.auth_methods))
|
||||||
auther = sot.auth_methods[0]
|
auther = sot.auth_methods[0]
|
||||||
self.assertEqual(common.TEST_USER, auther.user_name)
|
self.assertEqual(common.TEST_USER, auther.user_name)
|
||||||
@ -332,6 +349,7 @@ class TestV3Auth(testtools.TestCase):
|
|||||||
|
|
||||||
def test_valid_options(self):
|
def test_valid_options(self):
|
||||||
expected = [
|
expected = [
|
||||||
|
'access_info',
|
||||||
'auth_url',
|
'auth_url',
|
||||||
'domain_id',
|
'domain_id',
|
||||||
'domain_name',
|
'domain_name',
|
||||||
|
@ -62,24 +62,30 @@ class TestConnection(base.TestCase):
|
|||||||
self.assertEqual('1', conn.authenticator.password_method.user_name)
|
self.assertEqual('1', conn.authenticator.password_method.user_name)
|
||||||
self.assertEqual('2', conn.authenticator.password_method.password)
|
self.assertEqual('2', conn.authenticator.password_method.password)
|
||||||
|
|
||||||
def test_create_authenticator_no_name_2(self):
|
def test_create_authenticator_discoverable(self):
|
||||||
|
auth_args = {
|
||||||
|
'auth_url': '0',
|
||||||
|
'user_name': '1',
|
||||||
|
'password': '2',
|
||||||
|
}
|
||||||
|
conn = connection.Connection(transport='0', auth_plugin='identity',
|
||||||
|
**auth_args)
|
||||||
|
self.assertEqual('0', conn.authenticator.auth_url)
|
||||||
|
self.assertEqual(
|
||||||
|
'1',
|
||||||
|
conn.authenticator.auth_plugin.password_method.user_name)
|
||||||
|
self.assertEqual(
|
||||||
|
'2',
|
||||||
|
conn.authenticator.auth_plugin.password_method.password)
|
||||||
|
|
||||||
|
def test_create_authenticator_no_name(self):
|
||||||
auth_args = {
|
auth_args = {
|
||||||
'auth_url': 'http://localhost/v2',
|
'auth_url': 'http://localhost/v2',
|
||||||
'user_name': '1',
|
'user_name': '1',
|
||||||
'password': '2',
|
'password': '2',
|
||||||
}
|
}
|
||||||
conn = connection.Connection(transport='0', **auth_args)
|
conn = connection.Connection(transport='0', **auth_args)
|
||||||
self.assertEqual('openstack.auth.identity.v2',
|
self.assertEqual('openstack.auth.identity.discoverable',
|
||||||
conn.authenticator.__class__.__module__)
|
|
||||||
|
|
||||||
def test_create_authenticator_no_name_3(self):
|
|
||||||
auth_args = {
|
|
||||||
'auth_url': 'http://localhost/v3',
|
|
||||||
'user_name': '1',
|
|
||||||
'password': '2',
|
|
||||||
}
|
|
||||||
conn = connection.Connection(transport='0', **auth_args)
|
|
||||||
self.assertEqual('openstack.auth.identity.v3',
|
|
||||||
conn.authenticator.__class__.__module__)
|
conn.authenticator.__class__.__module__)
|
||||||
|
|
||||||
def test_create_authenticator_no_nothing(self):
|
def test_create_authenticator_no_nothing(self):
|
||||||
|
@ -52,3 +52,4 @@ universal = 1
|
|||||||
openstack.auth.plugin =
|
openstack.auth.plugin =
|
||||||
identity_v2 = openstack.auth.identity.v2:Auth
|
identity_v2 = openstack.auth.identity.v2:Auth
|
||||||
identity_v3 = openstack.auth.identity.v3:Auth
|
identity_v3 = openstack.auth.identity.v3:Auth
|
||||||
|
identity = openstack.auth.identity.discoverable:Auth
|
||||||
|
Loading…
x
Reference in New Issue
Block a user