Improve keystone client 'lazyness'
Change-Id: Ib6ac662344edaf5167da532991e34c430385001f
This commit is contained in:
parent
1dfc6ccc6b
commit
5996055ab6
|
@ -17,10 +17,13 @@ from tobiko.openstack.keystone import _credentials
|
|||
from tobiko.openstack.keystone import _session
|
||||
|
||||
keystone_credentials = _credentials.keystone_credentials
|
||||
get_keystone_credentials = _credentials.get_keystone_credentials
|
||||
default_keystone_credentials = _credentials.default_keystone_credentials
|
||||
KeystoneCredentials = _credentials.KeystoneCredentials
|
||||
KeystoneCredentialsFixture = _credentials.KeystoneCredentialsFixture
|
||||
InvalidKeystoneCredentials = _credentials.InvalidKeystoneCredentials
|
||||
|
||||
keystone_session = _session.keystone_session
|
||||
KeystoneSessionFixture = _session.KeystoneSessionFixture
|
||||
KeystoneSessionManager = _session.KeystoneSessionManager
|
||||
get_keystone_session = _session.get_keystone_session
|
||||
|
|
|
@ -23,8 +23,26 @@ import tobiko
|
|||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
def get_keystone_credentials(obj=None):
|
||||
if not obj:
|
||||
return default_keystone_credentials()
|
||||
if tobiko.is_fixture(obj):
|
||||
obj = tobiko.get_fixture(obj)
|
||||
if isinstance(obj, KeystoneCredentialsFixture):
|
||||
obj = tobiko.setup_fixture(obj).credentials
|
||||
if isinstance(obj, KeystoneCredentials):
|
||||
return obj
|
||||
|
||||
message = "Can't get {!r} object from {!r}".format(
|
||||
KeystoneCredentials, obj)
|
||||
raise TypeError(message)
|
||||
|
||||
|
||||
def default_keystone_credentials():
|
||||
return tobiko.setup_fixture(DefaultKeystoneCredentialsFixture).credentials
|
||||
credentials = tobiko.setup_fixture(DefaultKeystoneCredentialsFixture
|
||||
).credentials
|
||||
tobiko.check_valid_type(credentials, KeystoneCredentials)
|
||||
return credentials
|
||||
|
||||
|
||||
class KeystoneCredentials(collections.namedtuple(
|
||||
|
@ -93,16 +111,47 @@ class InvalidKeystoneCredentials(tobiko.TobikoException):
|
|||
message = "invalid Keystone credentials; {reason!s}; {credentials!r}"
|
||||
|
||||
|
||||
class EnvironKeystoneCredentialsFixture(tobiko.SharedFixture):
|
||||
class KeystoneCredentialsFixture(tobiko.SharedFixture):
|
||||
|
||||
credentials = None
|
||||
|
||||
def __init__(self, credentials=None):
|
||||
super(KeystoneCredentialsFixture, self).__init__()
|
||||
if credentials:
|
||||
self.credentials = credentials
|
||||
|
||||
def setup_fixture(self):
|
||||
self.setup_credentials()
|
||||
|
||||
def setup_credentials(self):
|
||||
credentials = self.credentials
|
||||
if not self.credentials:
|
||||
credentials = self.get_credentials()
|
||||
if credentials:
|
||||
try:
|
||||
credentials.validate()
|
||||
except InvalidKeystoneCredentials as ex:
|
||||
LOG.info("No such valid credentials from environment: %r",
|
||||
ex)
|
||||
else:
|
||||
self.addCleanup(self.cleanup_credentials)
|
||||
self.credentials = credentials
|
||||
|
||||
def cleanup_credentials(self):
|
||||
del self.credentials
|
||||
|
||||
def get_credentials(self):
|
||||
return None
|
||||
|
||||
|
||||
class EnvironKeystoneCredentialsFixture(KeystoneCredentialsFixture):
|
||||
|
||||
def get_credentials(self):
|
||||
from tobiko import config
|
||||
auth_url = config.get_env('OS_AUTH_URL')
|
||||
if not auth_url:
|
||||
LOG.debug("OS_AUTH_URL environment variable not defined")
|
||||
return
|
||||
return None
|
||||
|
||||
api_version = (
|
||||
config.get_int_env('OS_IDENTITY_API_VERSION') or
|
||||
|
@ -117,7 +166,7 @@ class EnvironKeystoneCredentialsFixture(tobiko.SharedFixture):
|
|||
config.get_env('OS_PROJECT_ID') or
|
||||
config.get_env('OS_TENANT_ID'))
|
||||
if api_version == 2:
|
||||
credentials = keystone_credentials(
|
||||
return keystone_credentials(
|
||||
api_version=api_version,
|
||||
auth_url=auth_url,
|
||||
username=username,
|
||||
|
@ -135,7 +184,7 @@ class EnvironKeystoneCredentialsFixture(tobiko.SharedFixture):
|
|||
project_domain_id = (
|
||||
config.get_env('OS_PROJECT_DOMAIN_ID'))
|
||||
trust_id = config.get_env('OS_TRUST_ID')
|
||||
credentials = keystone_credentials(
|
||||
return keystone_credentials(
|
||||
api_version=api_version,
|
||||
auth_url=auth_url,
|
||||
username=username,
|
||||
|
@ -146,38 +195,30 @@ class EnvironKeystoneCredentialsFixture(tobiko.SharedFixture):
|
|||
project_domain_name=project_domain_name,
|
||||
project_domain_id=project_domain_id,
|
||||
trust_id=trust_id)
|
||||
try:
|
||||
credentials.validate()
|
||||
except InvalidKeystoneCredentials as ex:
|
||||
LOG.info("No such valid credentials from environment: %r", ex)
|
||||
else:
|
||||
self.credentials = credentials
|
||||
|
||||
|
||||
class ConfigKeystoneCredentialsFixture(tobiko.SharedFixture):
|
||||
class ConfigKeystoneCredentialsFixture(KeystoneCredentialsFixture):
|
||||
|
||||
credentials = None
|
||||
|
||||
def setup_fixture(self):
|
||||
def get_credentials(self):
|
||||
from tobiko import config
|
||||
conf = config.CONF.tobiko.keystone
|
||||
auth_url = conf.auth_url
|
||||
if not auth_url:
|
||||
LOG.debug("auth_url option not defined in 'keystone' section of "
|
||||
"tobiko.conf")
|
||||
return
|
||||
return None
|
||||
|
||||
api_version = (conf.api_version or
|
||||
api_version_from_url(auth_url))
|
||||
if api_version == 2:
|
||||
credentials = keystone_credentials(
|
||||
return keystone_credentials(
|
||||
api_version=api_version,
|
||||
auth_url=auth_url,
|
||||
username=conf.username,
|
||||
password=conf.password,
|
||||
project_name=conf.project_name)
|
||||
else:
|
||||
credentials = keystone_credentials(
|
||||
return keystone_credentials(
|
||||
api_version=api_version,
|
||||
auth_url=auth_url,
|
||||
username=conf.username,
|
||||
|
@ -188,12 +229,6 @@ class ConfigKeystoneCredentialsFixture(tobiko.SharedFixture):
|
|||
project_domain_name=conf.project_domain_name,
|
||||
project_domain_id=conf.project_domain_id,
|
||||
trust_id=conf.trust_id)
|
||||
try:
|
||||
credentials.validate()
|
||||
except InvalidKeystoneCredentials as ex:
|
||||
LOG.info("No such valid credentials from tobiko.conf: %r", ex)
|
||||
else:
|
||||
self.credentials = credentials
|
||||
|
||||
|
||||
DEFAULT_KEYSTONE_CREDENTIALS_FIXTURES = [
|
||||
|
@ -201,32 +236,30 @@ DEFAULT_KEYSTONE_CREDENTIALS_FIXTURES = [
|
|||
ConfigKeystoneCredentialsFixture]
|
||||
|
||||
|
||||
class DefaultKeystoneCredentialsFixture(tobiko.SharedFixture):
|
||||
class DefaultKeystoneCredentialsFixture(KeystoneCredentialsFixture):
|
||||
|
||||
fixtures = DEFAULT_KEYSTONE_CREDENTIALS_FIXTURES
|
||||
credentials = None
|
||||
|
||||
def setup_fixture(self):
|
||||
def get_credentials(self):
|
||||
for fixture in self.fixtures:
|
||||
try:
|
||||
credentials = tobiko.setup_fixture(fixture).credentials
|
||||
except Exception:
|
||||
LOG.exception("Error setting up fixture %r", fixture)
|
||||
else:
|
||||
if credentials:
|
||||
LOG.info("Got default credentials from %r: %r",
|
||||
fixture, credentials)
|
||||
self.credentials = credentials
|
||||
return credentials
|
||||
raise RuntimeError('Unable to found any valid credentials')
|
||||
continue
|
||||
|
||||
if credentials:
|
||||
LOG.info("Got default credentials from fixture %r: %r",
|
||||
fixture, credentials)
|
||||
return credentials
|
||||
|
||||
|
||||
def api_version_from_url(auth_url):
|
||||
if auth_url.endswith('/v2.0'):
|
||||
LOG.info('Got Keystone API version 2 from auth_url: %r', auth_url)
|
||||
LOG.debug('Got Keystone API version 2 from auth_url: %r', auth_url)
|
||||
return 2
|
||||
elif auth_url.endswith('/v3'):
|
||||
LOG.info('Got Keystone API version 3 from auth_url: %r', auth_url)
|
||||
LOG.debug('Got Keystone API version 3 from auth_url: %r', auth_url)
|
||||
return 3
|
||||
else:
|
||||
LOG.warning('Unable to get Keystone API version from auth_url: %r',
|
||||
|
|
|
@ -24,57 +24,80 @@ from tobiko.openstack.keystone import _credentials
|
|||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
def keystone_session(obj):
|
||||
if not obj:
|
||||
return default_keystone_session()
|
||||
if tobiko.is_fixture(obj):
|
||||
obj = tobiko.get_fixture(obj)
|
||||
if isinstance(obj, KeystoneSessionFixture):
|
||||
obj = tobiko.setup_fixture(obj).session
|
||||
if isinstance(obj, _session.Session):
|
||||
return obj
|
||||
raise TypeError("Can't get {!r} object from {!r}".format(
|
||||
_session.Session, obj))
|
||||
|
||||
|
||||
class KeystoneSessionFixture(tobiko.SharedFixture):
|
||||
|
||||
session = None
|
||||
credentials = None
|
||||
credentials_fixture = None
|
||||
|
||||
def __init__(self, credentials=None):
|
||||
VALID_CREDENTIALS_TYPES = (_credentials.KeystoneCredentials,
|
||||
_credentials.KeystoneCredentialsFixture,
|
||||
type, str)
|
||||
|
||||
def __init__(self, credentials=None, session=None):
|
||||
super(KeystoneSessionFixture, self).__init__()
|
||||
if credentials:
|
||||
if tobiko.is_fixture(credentials):
|
||||
self.credentials_fixture = credentials
|
||||
else:
|
||||
self.credentials = credentials
|
||||
tobiko.check_valid_type(credentials, *self.VALID_CREDENTIALS_TYPES)
|
||||
self.credentials = credentials
|
||||
if session:
|
||||
self.session = session
|
||||
|
||||
def setup_fixture(self):
|
||||
self.setup_credentials()
|
||||
self.setup_session(credentials=self.credentials)
|
||||
self.setup_session()
|
||||
|
||||
def setup_credentials(self):
|
||||
credentials_fixture = self.credentials_fixture
|
||||
if credentials_fixture:
|
||||
self.credentials = tobiko.setup_fixture(
|
||||
credentials_fixture).credentials
|
||||
elif not self.credentials:
|
||||
self.credentials = _credentials.default_keystone_credentials()
|
||||
def setup_session(self):
|
||||
session = self.session
|
||||
if not session:
|
||||
credentials = _credentials.get_keystone_credentials(
|
||||
self.credentials)
|
||||
|
||||
def setup_session(self, credentials):
|
||||
LOG.debug("Create session for credentials %r", credentials)
|
||||
loader = loading.get_plugin_loader('password')
|
||||
params = credentials.to_dict()
|
||||
del params['api_version'] # parameter not required
|
||||
auth = loader.load_from_options(**params)
|
||||
self.session = _session.Session(auth=auth, verify=False)
|
||||
LOG.debug("Create Keystone session with credentials %r",
|
||||
credentials)
|
||||
credentials.validate()
|
||||
loader = loading.get_plugin_loader('password')
|
||||
params = credentials.to_dict()
|
||||
del params['api_version'] # parameter not required
|
||||
auth = loader.load_from_options(**params)
|
||||
self.session = _session.Session(auth=auth, verify=False)
|
||||
self.credentials = credentials
|
||||
|
||||
|
||||
class KeystoneSessionManager(object):
|
||||
|
||||
def __init__(self):
|
||||
self._sessions = {}
|
||||
self.sessions = {}
|
||||
|
||||
def get_session(self, credentials=None, shared=True, init_session=None):
|
||||
def get_session(self, credentials=None, init_session=None, shared=True):
|
||||
if shared:
|
||||
shared_key, session = self.get_shared_session(credentials)
|
||||
else:
|
||||
shared_key = session = None
|
||||
return session or self.create_session(credentials=credentials,
|
||||
init_session=init_session,
|
||||
shared=shared,
|
||||
shared_key=shared_key)
|
||||
|
||||
def get_shared_session(self, credentials):
|
||||
if tobiko.is_fixture(credentials):
|
||||
key = tobiko.get_fixture_name(credentials)
|
||||
else:
|
||||
key = credentials
|
||||
if credentials:
|
||||
if tobiko.is_fixture(credentials):
|
||||
key = tobiko.get_fixture_name(credentials)
|
||||
|
||||
session = self._sessions.get(key)
|
||||
if session:
|
||||
return session
|
||||
return key, self.sessions.get(key)
|
||||
|
||||
def create_session(self, credentials=None, init_session=None, shared=True,
|
||||
shared_key=None):
|
||||
init_session = init_session or KeystoneSessionFixture
|
||||
assert callable(init_session)
|
||||
LOG.debug('Initialize Keystone session: %r(credentials=%r)',
|
||||
|
@ -82,17 +105,21 @@ class KeystoneSessionManager(object):
|
|||
session = init_session(credentials=credentials)
|
||||
|
||||
if shared:
|
||||
self._sessions[key] = session
|
||||
self.sessions[shared_key] = session
|
||||
return session
|
||||
|
||||
|
||||
SESSIONS = KeystoneSessionManager()
|
||||
|
||||
|
||||
def default_keystone_session(shared=True, init_session=None, manager=None):
|
||||
return get_keystone_session(shared=shared, init_session=init_session,
|
||||
manager=manager)
|
||||
|
||||
|
||||
def get_keystone_session(credentials=None, shared=True, init_session=None,
|
||||
manager=None):
|
||||
manager = manager or SESSIONS
|
||||
session = manager.get_session(credentials=credentials, shared=shared,
|
||||
init_session=init_session)
|
||||
session.setUp()
|
||||
return session.session
|
||||
return tobiko.setup_fixture(session).session
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
# under the License.
|
||||
from __future__ import absolute_import
|
||||
|
||||
import inspect
|
||||
|
||||
from keystoneauth1 import session as keystonesession
|
||||
import mock
|
||||
|
||||
|
@ -34,22 +32,6 @@ CREDENTIALS = keystone.keystone_credentials(
|
|||
project_domain_name='Default')
|
||||
|
||||
|
||||
class CredentialsFixture(tobiko.SharedFixture):
|
||||
|
||||
credentials = None
|
||||
|
||||
def setup_fixture(self):
|
||||
self.credentials = CREDENTIALS
|
||||
|
||||
|
||||
class DefaultCredentialsFixture(tobiko.SharedFixture):
|
||||
|
||||
credentials = None
|
||||
|
||||
def setup_fixture(self):
|
||||
self.credentials = DEFAULT_CREDENTIALS
|
||||
|
||||
|
||||
DEFAULT_CREDENTIALS = keystone.keystone_credentials(
|
||||
api_version=2,
|
||||
auth_url='http://127.0.0.1:5000/identiy/v2.0',
|
||||
|
@ -58,23 +40,17 @@ DEFAULT_CREDENTIALS = keystone.keystone_credentials(
|
|||
password='this is a secret')
|
||||
|
||||
|
||||
class CheckSessionCredentialsMixin(object):
|
||||
class CredentialsFixture(keystone.KeystoneCredentialsFixture):
|
||||
|
||||
def check_session_credentials(self, session, credentials):
|
||||
if credentials:
|
||||
if tobiko.is_fixture(credentials):
|
||||
self.assertIsNone(session.credentials)
|
||||
self.assertIs(credentials, session.credentials_fixture)
|
||||
else:
|
||||
self.assertIs(credentials, session.credentials)
|
||||
self.assertIsNone(session.credentials_fixture)
|
||||
else:
|
||||
self.assertIsNone(session.credentials)
|
||||
self.assertIsNone(session.credentials_fixture)
|
||||
credentials = CREDENTIALS
|
||||
|
||||
|
||||
class KeystoneSessionFixtureTest(CheckSessionCredentialsMixin,
|
||||
openstack.OpenstackTest):
|
||||
class DefaultCredentialsFixture(CredentialsFixture):
|
||||
|
||||
credentials = DEFAULT_CREDENTIALS
|
||||
|
||||
|
||||
class KeystoneSessionFixtureTest(openstack.OpenstackTest):
|
||||
|
||||
default_credentials_fixture = (
|
||||
'tobiko.openstack.keystone._credentials.'
|
||||
|
@ -83,15 +59,17 @@ class KeystoneSessionFixtureTest(CheckSessionCredentialsMixin,
|
|||
def setUp(self):
|
||||
super(KeystoneSessionFixtureTest, self).setUp()
|
||||
from tobiko.openstack.keystone import _credentials
|
||||
from tobiko.openstack.keystone import _session
|
||||
|
||||
tobiko.remove_fixture(self.default_credentials_fixture)
|
||||
self.patch(_credentials, 'DefaultKeystoneCredentialsFixture',
|
||||
DefaultCredentialsFixture)
|
||||
self.patch(_session, 'SESSIONS',
|
||||
_session.KeystoneSessionManager())
|
||||
|
||||
def test_init(self, credentials=None):
|
||||
session = keystone.KeystoneSessionFixture(credentials=credentials)
|
||||
self.check_session_credentials(session=session,
|
||||
credentials=credentials)
|
||||
self.assertIs(credentials or None, session.credentials)
|
||||
|
||||
def test_init_with_credentials(self):
|
||||
self.test_init(credentials=CREDENTIALS)
|
||||
|
@ -105,15 +83,12 @@ class KeystoneSessionFixtureTest(CheckSessionCredentialsMixin,
|
|||
def test_setup(self, credentials=None):
|
||||
session = keystone.KeystoneSessionFixture(credentials=credentials)
|
||||
session.setUp()
|
||||
if credentials:
|
||||
if tobiko.is_fixture(credentials):
|
||||
if inspect.isclass(credentials):
|
||||
credentials = tobiko.get_fixture(credentials)
|
||||
self.assertIs(credentials.credentials, session.credentials)
|
||||
else:
|
||||
self.assertIs(credentials, session.credentials)
|
||||
if tobiko.is_fixture(credentials):
|
||||
credentials = tobiko.get_fixture(credentials)
|
||||
self.assertIs(credentials.credentials, session.credentials)
|
||||
else:
|
||||
self.assertEqual(DEFAULT_CREDENTIALS, session.credentials)
|
||||
self.assertIs(credentials or DEFAULT_CREDENTIALS,
|
||||
session.credentials)
|
||||
|
||||
def test_setup_with_credentials(self):
|
||||
self.test_setup(credentials=CREDENTIALS)
|
||||
|
@ -125,21 +100,20 @@ class KeystoneSessionFixtureTest(CheckSessionCredentialsMixin,
|
|||
self.test_setup(credentials=CredentialsFixture)
|
||||
|
||||
|
||||
class KeystoneSessionManagerTest(CheckSessionCredentialsMixin,
|
||||
openstack.OpenstackTest):
|
||||
class KeystoneSessionManagerTest(openstack.OpenstackTest):
|
||||
|
||||
def test_init(self):
|
||||
manager = keystone.KeystoneSessionManager()
|
||||
|
||||
self.assertTrue(manager)
|
||||
self.assertEqual({}, manager.sessions)
|
||||
|
||||
def test_get_session(self, credentials=None, shared=True):
|
||||
manager = keystone.KeystoneSessionManager()
|
||||
session = manager.get_session(credentials=credentials,
|
||||
shared=shared)
|
||||
self.assertIs(credentials or None, session.credentials)
|
||||
|
||||
self.assertIsInstance(session, keystone.KeystoneSessionFixture)
|
||||
self.check_session_credentials(session=session,
|
||||
credentials=credentials)
|
||||
if shared:
|
||||
self.assertIs(session, manager.get_session(
|
||||
credentials=credentials))
|
||||
|
|
Loading…
Reference in New Issue