Merge "Add keystone_session property to context"

This commit is contained in:
Jenkins 2016-07-01 08:33:36 +00:00 committed by Gerrit Code Review
commit 835017d8f7
7 changed files with 54 additions and 58 deletions

View File

@ -15,6 +15,7 @@ from keystoneauth1 import access
from keystoneauth1.identity import access as access_plugin
from keystoneauth1.identity import generic
from keystoneauth1 import loading as ks_loading
from keystoneauth1 import session
from keystoneauth1 import token_endpoint
from oslo_config import cfg
from oslo_context import context
@ -24,6 +25,7 @@ from oslo_middleware import request_id as oslo_request_id
from oslo_utils import importutils
import six
from heat.common import config
from heat.common import endpoint_utils
from heat.common import exception
from heat.common.i18n import _LE, _LW
@ -106,6 +108,8 @@ class RequestContext(context.RequestContext):
self.auth_url = auth_url
self._session = None
self._clients = None
self._keystone_session = session.Session(
**config.get_ssl_options('keystone'))
self.trust_id = trust_id
self.trustor_user_id = trustor_user_id
self.policy = policy.Enforcer()
@ -137,12 +141,26 @@ class RequestContext(context.RequestContext):
self._session = db_api.get_session()
return self._session
@property
def keystone_session(self):
if self.auth_needs_refresh():
self.reload_auth_plugin()
self.clients.invalidate_plugins()
self._keystone_session.auth = self.auth_plugin
return self._keystone_session
@property
def clients(self):
if self._clients is None:
self._clients = clients.Clients(self)
return self._clients
def auth_needs_refresh(self):
auth_ref = self.auth_plugin.get_auth_ref(self._keystone_session)
return (cfg.CONF.reauthentication_auth_method == 'trusts'
and auth_ref.will_expire_soon(
cfg.CONF.stale_token_duration))
def to_dict(self):
user_idt = '{user} {tenant}'.format(user=self.user_id or '-',
tenant=self.tenant_id or '-')

View File

@ -83,14 +83,6 @@ class OpenStackClients(object):
return client
LOG.warning(_LW('Requested client "%s" not found'), name)
@property
def auth_token(self):
# Always use the auth_token from the keystone() client, as
# this may be refreshed if the context contains credentials
# which allow reissuing of a new token before the context
# auth_token expiry (e.g trust_id or username/password)
return self.client('keystone').auth_token
class ClientBackend(object):
"""Class for delaying choosing the backend client module.

View File

@ -19,7 +19,6 @@ import weakref
from keystoneauth1 import exceptions
from keystoneauth1.identity import generic
from keystoneauth1 import plugin
from keystoneauth1 import session
from oslo_config import cfg
import requests
import six
@ -107,7 +106,6 @@ class ClientPlugin(object):
self._context = weakref.ref(context)
self._clients = weakref.ref(context.clients)
self.invalidate()
self._keystone_session_obj = None
@property
def context(self):
@ -121,18 +119,6 @@ class ClientPlugin(object):
_get_client_option = staticmethod(config.get_client_option)
@property
def _keystone_session(self):
# FIXME(jamielennox): This session object is essentially static as the
# options won't change. Further it is allowed to be shared by multiple
# authentication requests so there is no reason to construct it fresh
# for every client plugin. It should be global and shared amongst them.
if not self._keystone_session_obj:
self._keystone_session_obj = session.Session(
**config.get_ssl_options('keystone'))
return self._keystone_session_obj
def invalidate(self):
"""Invalidate/clear any cached client."""
self._client_instances = {}
@ -141,18 +127,9 @@ class ClientPlugin(object):
if not version:
version = self.default_version
if version in self._client_instances:
auth_ref = self.context.auth_plugin.get_auth_ref(
self._keystone_session)
if (cfg.CONF.reauthentication_auth_method == 'trusts'
and auth_ref.will_expire_soon(
cfg.CONF.stale_token_duration)):
# If the token is near expiry, force creating a new client,
# which will get a new token via another call to auth_token
# We also have to invalidate all other cached clients
self.clients.invalidate_plugins()
else:
return self._client_instances[version]
if (version in self._client_instances
and not self.context.auth_needs_refresh()):
return self._client_instances[version]
# Back-ward compatibility
if version is None:
@ -174,15 +151,17 @@ class ClientPlugin(object):
@property
def auth_token(self):
# NOTE(jamielennox): use the session defined by the keystoneclient
# options as traditionally the token was always retrieved from
# keystoneclient.
return self.context.auth_plugin.get_token(self._keystone_session)
# Always use the auth_token from the keystone_session, as
# this may be refreshed if the context contains credentials
# which allow reissuing of a new token before the context
# auth_token expiry (e.g trust_id or username/password)
return self.context.keystone_session.get_token()
def url_for(self, **kwargs):
keystone_session = self.context.keystone_session
def get_endpoint():
auth_plugin = self.context.auth_plugin
return auth_plugin.get_endpoint(self._keystone_session, **kwargs)
return keystone_session.get_endpoint(**kwargs)
# NOTE(jamielennox): use the session defined by the keystoneclient
# options as traditionally the token was always retrieved from
@ -198,12 +177,11 @@ class ClientPlugin(object):
try:
url = get_endpoint()
except exceptions.EmptyCatalog:
auth_plugin = self.context.auth_plugin
endpoint = auth_plugin.get_endpoint(
endpoint = keystone_session.get_endpoint(
None, interface=plugin.AUTH_INTERFACE)
token = auth_plugin.get_token(None)
token = keystone_session.get_token(None)
token_obj = generic.Token(endpoint, token)
auth_ref = token_obj.get_access(self._keystone_session)
auth_ref = token_obj.get_access(keystone_session)
if auth_ref.has_service_catalog():
self.context.reload_auth_plugin()
url = get_endpoint()

View File

@ -30,13 +30,11 @@ class AodhClientPlugin(client_plugin.ClientPlugin):
default_version = V2
def _create(self, version=None):
interface = self._get_client_option(CLIENT_NAME, 'endpoint_type')
self._keystone_session.auth = self.context.auth_plugin
return ac.Client(
version,
session=self._keystone_session,
session=self.context.keystone_session,
interface=interface,
service_type=self.ALARMING)

View File

@ -29,9 +29,8 @@ class BarbicanClientPlugin(client_plugin.ClientPlugin):
endpoint_type = self._get_client_option(CLIENT_NAME, 'endpoint_type')
endpoint = self.url_for(service_type=self.KEY_MANAGER,
endpoint_type=endpoint_type)
self._keystone_session.auth = self.context.auth_plugin
client = barbican_client.Client(
session=self._keystone_session, endpoint=endpoint)
session=self.context.keystone_session, endpoint=endpoint)
return client

View File

@ -287,14 +287,14 @@ class ClientPluginTest(common.HeatTestCase):
c = clients.Clients(con)
con.clients = c
con.auth_plugin = mock.Mock(name="auth_plugin")
con.auth_plugin.get_endpoint = mock.Mock(name="get_endpoint")
con.auth_plugin.get_endpoint.return_value = 'http://192.0.2.1/foo'
con.keystone_session = mock.Mock(name="keystone_Session")
con.keystone_session.get_endpoint = mock.Mock(name="get_endpoint")
con.keystone_session.get_endpoint.return_value = 'http://192.0.2.1/foo'
plugin = FooClientsPlugin(con)
self.assertEqual('http://192.0.2.1/foo',
plugin.url_for(service_type='foo'))
self.assertTrue(con.auth_plugin.get_endpoint.called)
self.assertTrue(con.keystone_session.get_endpoint.called)
@mock.patch.object(generic, "Token", name="v3_token")
def test_get_missing_service_catalog(self, mock_v3):
@ -309,10 +309,10 @@ class ClientPluginTest(common.HeatTestCase):
c = clients.Clients(con)
con.clients = c
con.auth_plugin = mock.Mock(name="auth_plugin")
con.keystone_session = mock.Mock(name="keystone_session")
get_endpoint_side_effects = [
keystone_exc.EmptyCatalog(), None, 'http://192.0.2.1/bar']
con.auth_plugin.get_endpoint = mock.Mock(
con.keystone_session.get_endpoint = mock.Mock(
name="get_endpoint", side_effect=get_endpoint_side_effects)
mock_token_obj = mock.Mock()
@ -337,9 +337,9 @@ class ClientPluginTest(common.HeatTestCase):
c = clients.Clients(con)
con.clients = c
con.auth_plugin = mock.Mock(name="auth_plugin")
con.keystone_session = mock.Mock(name="keystone_session")
get_endpoint_side_effects = [keystone_exc.EmptyCatalog(), None]
con.auth_plugin.get_endpoint = mock.Mock(
con.keystone_session.get_endpoint = mock.Mock(
name="get_endpoint", side_effect=get_endpoint_side_effects)
mock_token_obj = mock.Mock()
@ -380,7 +380,13 @@ class ClientPluginTest(common.HeatTestCase):
self.assertEqual(2, plugin._create.call_count)
def test_create_client_on_invalidate(self):
con = mock.Mock()
cfg.CONF.set_override('reauthentication_auth_method', 'trusts',
enforce_type=True)
con = utils.dummy_context()
auth_ref = mock.Mock()
self.patchobject(con.auth_plugin, 'get_auth_ref',
return_value=auth_ref)
auth_ref.will_expire_soon.return_value = False
plugin = FooClientsPlugin(con)
plugin._create = mock.Mock()
plugin.client()

View File

@ -20,6 +20,7 @@ places where actual behavior differs from the spec.
from keystoneauth1 import plugin
from keystoneauth1 import session
import mock
from heat.common import context
@ -89,6 +90,10 @@ class FakeAuth(plugin.BaseAuthPlugin):
return 'http://example.com:1234/v1'
def get_auth_ref(self, session):
auth_ref = mock.Mock()
return auth_ref
class FakeKeystoneClient(object):
def __init__(self, username='test_username', password='password',