Bug 1052674: added support for Swift cache
This patch merely address the Swift cache backward compatibility support. There's another BP which address the elephant-in-the-room, which is unified and consistent caching mechanism for all middleware. See https://blueprints.launchpad.net/keystone/+spec/unifed-caching-system-for-middleware Change-Id: Iab6b4ac61c9aa9e7ad32a394557cb7558bd60a43
This commit is contained in:
@@ -147,6 +147,13 @@ if not CONF:
|
|||||||
# admin_tenant_name = admin
|
# admin_tenant_name = admin
|
||||||
# admin_user = admin
|
# admin_user = admin
|
||||||
# admin_password = badpassword
|
# admin_password = badpassword
|
||||||
|
|
||||||
|
# when deploy Keystone auth_token middleware with Swift, user may elect
|
||||||
|
# to use Swift memcache instead of the local Keystone memcache. Swift memcache
|
||||||
|
# is passed in from the request environment and its identified by the
|
||||||
|
# 'swift.cache' key. However it could be different, depending on deployment.
|
||||||
|
# To use Swift memcache, you must set the 'cache' option to the environment
|
||||||
|
# key where the Swift cache object is stored.
|
||||||
opts = [
|
opts = [
|
||||||
cfg.StrOpt('auth_admin_prefix', default=''),
|
cfg.StrOpt('auth_admin_prefix', default=''),
|
||||||
cfg.StrOpt('auth_host', default='127.0.0.1'),
|
cfg.StrOpt('auth_host', default='127.0.0.1'),
|
||||||
@@ -158,6 +165,7 @@ opts = [
|
|||||||
cfg.StrOpt('admin_user'),
|
cfg.StrOpt('admin_user'),
|
||||||
cfg.StrOpt('admin_password'),
|
cfg.StrOpt('admin_password'),
|
||||||
cfg.StrOpt('admin_tenant_name', default='admin'),
|
cfg.StrOpt('admin_tenant_name', default='admin'),
|
||||||
|
cfg.StrOpt('cache', default=None), # env key for the swift cache
|
||||||
cfg.StrOpt('certfile'),
|
cfg.StrOpt('certfile'),
|
||||||
cfg.StrOpt('keyfile'),
|
cfg.StrOpt('keyfile'),
|
||||||
cfg.StrOpt('signing_dir'),
|
cfg.StrOpt('signing_dir'),
|
||||||
@@ -262,23 +270,35 @@ class AuthProtocol(object):
|
|||||||
# Token caching via memcache
|
# Token caching via memcache
|
||||||
self._cache = None
|
self._cache = None
|
||||||
self._iso8601 = None
|
self._iso8601 = None
|
||||||
memcache_servers = self._conf_get('memcache_servers')
|
self._cache_initialized = False # cache already initialzied?
|
||||||
# By default the token will be cached for 5 minutes
|
# By default the token will be cached for 5 minutes
|
||||||
self.token_cache_time = int(self._conf_get('token_cache_time'))
|
self.token_cache_time = int(self._conf_get('token_cache_time'))
|
||||||
self._token_revocation_list = None
|
self._token_revocation_list = None
|
||||||
self._token_revocation_list_fetched_time = None
|
self._token_revocation_list_fetched_time = None
|
||||||
cache_timeout = datetime.timedelta(seconds=0)
|
cache_timeout = datetime.timedelta(seconds=0)
|
||||||
self.token_revocation_list_cache_timeout = cache_timeout
|
self.token_revocation_list_cache_timeout = cache_timeout
|
||||||
if memcache_servers:
|
|
||||||
try:
|
def _init_cache(self, env):
|
||||||
import memcache
|
cache = self._conf_get('cache')
|
||||||
import iso8601
|
memcache_servers = self._conf_get('memcache_servers')
|
||||||
self.LOG.info('Using memcache for caching token')
|
if cache and env.get(cache, None) is not None:
|
||||||
self._cache = memcache.Client(memcache_servers)
|
# use the cache from the upstream filter
|
||||||
self._iso8601 = iso8601
|
self.LOG.info('Using %s memcache for caching token', cache)
|
||||||
except ImportError as e:
|
self._cache = env.get(cache)
|
||||||
self.LOG.warn(
|
else:
|
||||||
'disabled caching due to missing libraries %s', e)
|
# use Keystone memcache
|
||||||
|
memcache_servers = self._conf_get('memcache_servers')
|
||||||
|
if memcache_servers:
|
||||||
|
try:
|
||||||
|
import memcache
|
||||||
|
import iso8601
|
||||||
|
self.LOG.info('Using Keystone memcache for caching token')
|
||||||
|
self._cache = memcache.Client(memcache_servers)
|
||||||
|
self._iso8601 = iso8601
|
||||||
|
except ImportError as e:
|
||||||
|
msg = 'disabled caching due to missing libraries %s' % (e)
|
||||||
|
self.LOG.warn(msg)
|
||||||
|
self._cache_initialized = True
|
||||||
|
|
||||||
def _conf_get(self, name):
|
def _conf_get(self, name):
|
||||||
# try config from paste-deploy first
|
# try config from paste-deploy first
|
||||||
@@ -295,6 +315,11 @@ class AuthProtocol(object):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
self.LOG.debug('Authenticating user token')
|
self.LOG.debug('Authenticating user token')
|
||||||
|
|
||||||
|
# initialize memcache if we haven't done so
|
||||||
|
if not self._cache_initialized:
|
||||||
|
self._init_cache(env)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._remove_auth_headers(env)
|
self._remove_auth_headers(env)
|
||||||
user_token = self._get_user_token_from_header(env)
|
user_token = self._get_user_token_from_header(env)
|
||||||
|
|||||||
@@ -652,6 +652,32 @@ class AuthTokenMiddlewareTest(test.NoModule, BaseAuthTokenMiddlewareTest):
|
|||||||
|
|
||||||
auth_token.AuthProtocol(FakeApp(), conf)
|
auth_token.AuthProtocol(FakeApp(), conf)
|
||||||
|
|
||||||
|
def test_use_cache_from_env(self):
|
||||||
|
env = {'swift.cache': 'CACHE_TEST'}
|
||||||
|
conf = {
|
||||||
|
'admin_token': 'admin_token1',
|
||||||
|
'auth_host': 'keystone.example.com',
|
||||||
|
'auth_port': 1234,
|
||||||
|
'cache': 'swift.cache',
|
||||||
|
'memcache_servers': 'localhost:11211',
|
||||||
|
}
|
||||||
|
auth = auth_token.AuthProtocol(FakeApp(), conf)
|
||||||
|
auth._init_cache(env)
|
||||||
|
self.assertEqual(auth._cache, 'CACHE_TEST')
|
||||||
|
|
||||||
|
def test_not_use_cache_from_env(self):
|
||||||
|
self.disable_module('memcache')
|
||||||
|
env = {'swift.cache': 'CACHE_TEST'}
|
||||||
|
conf = {
|
||||||
|
'admin_token': 'admin_token1',
|
||||||
|
'auth_host': 'keystone.example.com',
|
||||||
|
'auth_port': 1234,
|
||||||
|
'memcache_servers': 'localhost:11211',
|
||||||
|
}
|
||||||
|
auth = auth_token.AuthProtocol(FakeApp(), conf)
|
||||||
|
auth._init_cache(env)
|
||||||
|
self.assertEqual(auth._cache, None)
|
||||||
|
|
||||||
def test_request_prevent_service_catalog_injection(self):
|
def test_request_prevent_service_catalog_injection(self):
|
||||||
req = webob.Request.blank('/')
|
req = webob.Request.blank('/')
|
||||||
req.headers['X-Service-Catalog'] = '[]'
|
req.headers['X-Service-Catalog'] = '[]'
|
||||||
|
|||||||
Reference in New Issue
Block a user