Merge "Adding keystoneauth sessions support"
This commit is contained in:
commit
e9887703d0
@ -18,6 +18,28 @@ version are detailed below, but are
|
||||
just a subset of those that can be used to successfully authenticate. These
|
||||
are the most common and recommended combinations.
|
||||
|
||||
Keystone Session
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from keystoneauth1 import session
|
||||
from keystoneauth1 import v3
|
||||
|
||||
# Create a password auth plugin
|
||||
auth = v3.Password(auth_url='http://127.0.0.1:5000/v3/',
|
||||
username='tester',
|
||||
password='testing',
|
||||
user_domain_name='Default',
|
||||
project_name='Default',
|
||||
project_domain_name='Default')
|
||||
|
||||
# Create session
|
||||
session = session.Session(auth=auth)
|
||||
|
||||
# Create swiftclient Connection
|
||||
swift_conn = Connection(session=session)
|
||||
|
||||
Keystone v3
|
||||
~~~~~~~~~~~
|
||||
|
||||
|
@ -616,6 +616,7 @@ def get_auth(auth_url, user, key, **kwargs):
|
||||
use of this network path causes no bandwidth charges but requires the
|
||||
client to be running on Rackspace's ServiceNet network.
|
||||
"""
|
||||
session = kwargs.get('session', None)
|
||||
auth_version = kwargs.get('auth_version', '1')
|
||||
os_options = kwargs.get('os_options', {})
|
||||
|
||||
@ -624,7 +625,14 @@ def get_auth(auth_url, user, key, **kwargs):
|
||||
cert = kwargs.get('cert')
|
||||
cert_key = kwargs.get('cert_key')
|
||||
timeout = kwargs.get('timeout', None)
|
||||
if auth_version in AUTH_VERSIONS_V1:
|
||||
|
||||
if session:
|
||||
service_type = os_options.get('service_type', 'object-store')
|
||||
interface = os_options.get('endpoint_type', 'public')
|
||||
storage_url = session.get_endpoint(service_type=service_type,
|
||||
interface=interface)
|
||||
token = session.get_token()
|
||||
elif auth_version in AUTH_VERSIONS_V1:
|
||||
storage_url, token = get_auth_1_0(auth_url,
|
||||
user,
|
||||
key,
|
||||
@ -661,8 +669,8 @@ def get_auth(auth_url, user, key, **kwargs):
|
||||
timeout=timeout,
|
||||
auth_version=auth_version)
|
||||
else:
|
||||
raise ClientException('Unknown auth_version %s specified.'
|
||||
% auth_version)
|
||||
raise ClientException('Unknown auth_version %s specified and no '
|
||||
'session found.' % auth_version)
|
||||
|
||||
# Override storage url, if necessary
|
||||
if os_options.get('object_storage_url'):
|
||||
@ -1498,7 +1506,7 @@ class Connection(object):
|
||||
os_options=None, auth_version="1", cacert=None,
|
||||
insecure=False, cert=None, cert_key=None,
|
||||
ssl_compression=True, retry_on_ratelimit=False,
|
||||
timeout=None):
|
||||
timeout=None, session=None):
|
||||
"""
|
||||
:param authurl: authentication URL
|
||||
:param user: user name to authenticate as
|
||||
@ -1533,7 +1541,9 @@ class Connection(object):
|
||||
this parameter to True will cause a retry
|
||||
after a backoff.
|
||||
:param timeout: The connect timeout for the HTTP connection.
|
||||
:param session: A keystoneauth session object.
|
||||
"""
|
||||
self.session = session
|
||||
self.authurl = authurl
|
||||
self.user = user
|
||||
self.key = key
|
||||
@ -1577,7 +1587,7 @@ class Connection(object):
|
||||
|
||||
def get_auth(self):
|
||||
self.url, self.token = get_auth(self.authurl, self.user, self.key,
|
||||
snet=self.snet,
|
||||
session=self.session, snet=self.snet,
|
||||
auth_version=self.auth_version,
|
||||
os_options=self.os_options,
|
||||
cacert=self.cacert,
|
||||
@ -1596,8 +1606,8 @@ class Connection(object):
|
||||
None)
|
||||
service_user = opts.get('service_username', None)
|
||||
service_key = opts.get('service_key', None)
|
||||
return get_auth(self.authurl, service_user,
|
||||
service_key,
|
||||
return get_auth(self.authurl, service_user, service_key,
|
||||
session=self.session,
|
||||
snet=self.snet,
|
||||
auth_version=self.auth_version,
|
||||
os_options=service_options,
|
||||
@ -1658,10 +1668,15 @@ class Connection(object):
|
||||
except ClientException as err:
|
||||
self._add_response_dict(caller_response_dict, kwargs)
|
||||
if err.http_status == 401:
|
||||
if self.session:
|
||||
should_retry = self.session.invalidate()
|
||||
else:
|
||||
# Without a proper session, just check for auth creds
|
||||
should_retry = all((self.authurl, self.user, self.key))
|
||||
|
||||
self.url = self.token = self.service_token = None
|
||||
if retried_auth or not all((self.authurl,
|
||||
self.user,
|
||||
self.key)):
|
||||
|
||||
if retried_auth or not should_retry:
|
||||
logger.exception(err)
|
||||
raise
|
||||
retried_auth = True
|
||||
|
@ -573,6 +573,15 @@ class TestGetAuth(MockHttpTest):
|
||||
self.assertTrue(url.startswith("http"))
|
||||
self.assertTrue(token)
|
||||
|
||||
def test_auth_with_session(self):
|
||||
mock_session = mock.MagicMock()
|
||||
mock_session.get_endpoint.return_value = 'http://storagehost/v1/acct'
|
||||
mock_session.get_token.return_value = 'token'
|
||||
url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf',
|
||||
session=mock_session)
|
||||
self.assertEqual(url, 'http://storagehost/v1/acct')
|
||||
self.assertTrue(token)
|
||||
|
||||
|
||||
class TestGetAccount(MockHttpTest):
|
||||
|
||||
@ -2028,6 +2037,39 @@ class TestConnection(MockHttpTest):
|
||||
('HEAD', '/v1/AUTH_test', '', {'x-auth-token': 'token'}),
|
||||
])
|
||||
|
||||
def test_session_no_invalidate(self):
|
||||
mock_session = mock.MagicMock()
|
||||
mock_session.get_endpoint.return_value = 'http://storagehost/v1/acct'
|
||||
mock_session.get_token.return_value = 'expired'
|
||||
mock_session.invalidate.return_value = False
|
||||
conn = c.Connection(session=mock_session)
|
||||
fake_conn = self.fake_http_connection(401)
|
||||
with mock.patch.multiple('swiftclient.client',
|
||||
http_connection=fake_conn,
|
||||
sleep=mock.DEFAULT):
|
||||
self.assertRaises(c.ClientException, conn.head_account)
|
||||
self.assertEqual(mock_session.get_token.mock_calls, [mock.call()])
|
||||
self.assertEqual(mock_session.invalidate.mock_calls, [mock.call()])
|
||||
|
||||
def test_session_can_invalidate(self):
|
||||
mock_session = mock.MagicMock()
|
||||
mock_session.get_endpoint.return_value = 'http://storagehost/v1/acct'
|
||||
mock_session.get_token.side_effect = ['expired', 'token']
|
||||
mock_session.invalidate.return_value = True
|
||||
conn = c.Connection(session=mock_session)
|
||||
fake_conn = self.fake_http_connection(401, 200)
|
||||
with mock.patch.multiple('swiftclient.client',
|
||||
http_connection=fake_conn,
|
||||
sleep=mock.DEFAULT):
|
||||
conn.head_account()
|
||||
self.assertRequests([
|
||||
('HEAD', '/v1/acct', '', {'x-auth-token': 'expired'}),
|
||||
('HEAD', '/v1/acct', '', {'x-auth-token': 'token'}),
|
||||
])
|
||||
self.assertEqual(mock_session.get_token.mock_calls, [
|
||||
mock.call(), mock.call()])
|
||||
self.assertEqual(mock_session.invalidate.mock_calls, [mock.call()])
|
||||
|
||||
def test_preauth_token_with_no_storage_url_requires_auth(self):
|
||||
conn = c.Connection(
|
||||
'http://auth.example.com', 'user', 'password',
|
||||
|
Loading…
x
Reference in New Issue
Block a user