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
|
just a subset of those that can be used to successfully authenticate. These
|
||||||
are the most common and recommended combinations.
|
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
|
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
|
use of this network path causes no bandwidth charges but requires the
|
||||||
client to be running on Rackspace's ServiceNet network.
|
client to be running on Rackspace's ServiceNet network.
|
||||||
"""
|
"""
|
||||||
|
session = kwargs.get('session', None)
|
||||||
auth_version = kwargs.get('auth_version', '1')
|
auth_version = kwargs.get('auth_version', '1')
|
||||||
os_options = kwargs.get('os_options', {})
|
os_options = kwargs.get('os_options', {})
|
||||||
|
|
||||||
@ -624,7 +625,14 @@ def get_auth(auth_url, user, key, **kwargs):
|
|||||||
cert = kwargs.get('cert')
|
cert = kwargs.get('cert')
|
||||||
cert_key = kwargs.get('cert_key')
|
cert_key = kwargs.get('cert_key')
|
||||||
timeout = kwargs.get('timeout', None)
|
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,
|
storage_url, token = get_auth_1_0(auth_url,
|
||||||
user,
|
user,
|
||||||
key,
|
key,
|
||||||
@ -661,8 +669,8 @@ def get_auth(auth_url, user, key, **kwargs):
|
|||||||
timeout=timeout,
|
timeout=timeout,
|
||||||
auth_version=auth_version)
|
auth_version=auth_version)
|
||||||
else:
|
else:
|
||||||
raise ClientException('Unknown auth_version %s specified.'
|
raise ClientException('Unknown auth_version %s specified and no '
|
||||||
% auth_version)
|
'session found.' % auth_version)
|
||||||
|
|
||||||
# Override storage url, if necessary
|
# Override storage url, if necessary
|
||||||
if os_options.get('object_storage_url'):
|
if os_options.get('object_storage_url'):
|
||||||
@ -1498,7 +1506,7 @@ class Connection(object):
|
|||||||
os_options=None, auth_version="1", cacert=None,
|
os_options=None, auth_version="1", cacert=None,
|
||||||
insecure=False, cert=None, cert_key=None,
|
insecure=False, cert=None, cert_key=None,
|
||||||
ssl_compression=True, retry_on_ratelimit=False,
|
ssl_compression=True, retry_on_ratelimit=False,
|
||||||
timeout=None):
|
timeout=None, session=None):
|
||||||
"""
|
"""
|
||||||
:param authurl: authentication URL
|
:param authurl: authentication URL
|
||||||
:param user: user name to authenticate as
|
:param user: user name to authenticate as
|
||||||
@ -1533,7 +1541,9 @@ class Connection(object):
|
|||||||
this parameter to True will cause a retry
|
this parameter to True will cause a retry
|
||||||
after a backoff.
|
after a backoff.
|
||||||
:param timeout: The connect timeout for the HTTP connection.
|
:param timeout: The connect timeout for the HTTP connection.
|
||||||
|
:param session: A keystoneauth session object.
|
||||||
"""
|
"""
|
||||||
|
self.session = session
|
||||||
self.authurl = authurl
|
self.authurl = authurl
|
||||||
self.user = user
|
self.user = user
|
||||||
self.key = key
|
self.key = key
|
||||||
@ -1577,7 +1587,7 @@ class Connection(object):
|
|||||||
|
|
||||||
def get_auth(self):
|
def get_auth(self):
|
||||||
self.url, self.token = get_auth(self.authurl, self.user, self.key,
|
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,
|
auth_version=self.auth_version,
|
||||||
os_options=self.os_options,
|
os_options=self.os_options,
|
||||||
cacert=self.cacert,
|
cacert=self.cacert,
|
||||||
@ -1596,8 +1606,8 @@ class Connection(object):
|
|||||||
None)
|
None)
|
||||||
service_user = opts.get('service_username', None)
|
service_user = opts.get('service_username', None)
|
||||||
service_key = opts.get('service_key', None)
|
service_key = opts.get('service_key', None)
|
||||||
return get_auth(self.authurl, service_user,
|
return get_auth(self.authurl, service_user, service_key,
|
||||||
service_key,
|
session=self.session,
|
||||||
snet=self.snet,
|
snet=self.snet,
|
||||||
auth_version=self.auth_version,
|
auth_version=self.auth_version,
|
||||||
os_options=service_options,
|
os_options=service_options,
|
||||||
@ -1658,10 +1668,15 @@ class Connection(object):
|
|||||||
except ClientException as err:
|
except ClientException as err:
|
||||||
self._add_response_dict(caller_response_dict, kwargs)
|
self._add_response_dict(caller_response_dict, kwargs)
|
||||||
if err.http_status == 401:
|
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
|
self.url = self.token = self.service_token = None
|
||||||
if retried_auth or not all((self.authurl,
|
|
||||||
self.user,
|
if retried_auth or not should_retry:
|
||||||
self.key)):
|
|
||||||
logger.exception(err)
|
logger.exception(err)
|
||||||
raise
|
raise
|
||||||
retried_auth = True
|
retried_auth = True
|
||||||
|
@ -573,6 +573,15 @@ class TestGetAuth(MockHttpTest):
|
|||||||
self.assertTrue(url.startswith("http"))
|
self.assertTrue(url.startswith("http"))
|
||||||
self.assertTrue(token)
|
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):
|
class TestGetAccount(MockHttpTest):
|
||||||
|
|
||||||
@ -2028,6 +2037,39 @@ class TestConnection(MockHttpTest):
|
|||||||
('HEAD', '/v1/AUTH_test', '', {'x-auth-token': 'token'}),
|
('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):
|
def test_preauth_token_with_no_storage_url_requires_auth(self):
|
||||||
conn = c.Connection(
|
conn = c.Connection(
|
||||||
'http://auth.example.com', 'user', 'password',
|
'http://auth.example.com', 'user', 'password',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user