Merge "Add keystone_session property to context"
This commit is contained in:
commit
835017d8f7
@ -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 '-')
|
||||
|
@ -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.
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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',
|
||||
|
Loading…
Reference in New Issue
Block a user