summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnthony Young <sleepsonthefloor@gmail.com>2011-04-29 22:06:18 +0000
committerTarmac <>2011-04-29 22:06:18 +0000
commite2d77bf9d45c6370f5dda7176ec13db23666f314 (patch)
treeb79eeb7e4d808a937d0cb8670a30116213053557
parent9d76e52e4ac032973dd75d44e4978e7d42d33d40 (diff)
parentdc4beede6bda3b7db5ca5963cc6c48052d2b7c62 (diff)
downloadnova-e2d77bf9d45c6370f5dda7176ec13db23666f314.tar.gz
nova-e2d77bf9d45c6370f5dda7176ec13db23666f314.tar.xz
nova-e2d77bf9d45c6370f5dda7176ec13db23666f314.zip
Uses memcached to cache roles so that ldap is actually usable.
-rw-r--r--nova/api/ec2/__init__.py6
-rw-r--r--nova/auth/manager.py60
-rw-r--r--nova/flags.py3
3 files changed, 50 insertions, 19 deletions
diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py
index e18e7f05e..cd59340bd 100644
--- a/nova/api/ec2/__init__.py
+++ b/nova/api/ec2/__init__.py
@@ -46,8 +46,6 @@ flags.DEFINE_integer('lockout_minutes', 15,
'Number of minutes to lockout if triggered.')
flags.DEFINE_integer('lockout_window', 15,
'Number of minutes for lockout window.')
-flags.DEFINE_list('lockout_memcached_servers', None,
- 'Memcached servers or None for in process cache.')
class RequestLogging(wsgi.Middleware):
@@ -107,11 +105,11 @@ class Lockout(wsgi.Middleware):
def __init__(self, application):
"""middleware can use fake for testing."""
- if FLAGS.lockout_memcached_servers:
+ if FLAGS.memcached_servers:
import memcache
else:
from nova import fakememcache as memcache
- self.mc = memcache.Client(FLAGS.lockout_memcached_servers,
+ self.mc = memcache.Client(FLAGS.memcached_servers,
debug=0)
super(Lockout, self).__init__(application)
diff --git a/nova/auth/manager.py b/nova/auth/manager.py
index b719a0dbd..c5ff348dd 100644
--- a/nova/auth/manager.py
+++ b/nova/auth/manager.py
@@ -223,6 +223,13 @@ class AuthManager(object):
if driver or not getattr(self, 'driver', None):
self.driver = utils.import_class(driver or FLAGS.auth_driver)
+ if FLAGS.memcached_servers:
+ import memcache
+ else:
+ from nova import fakememcache as memcache
+ self.mc = memcache.Client(FLAGS.memcached_servers,
+ debug=0)
+
def authenticate(self, access, signature, params, verb='GET',
server_string='127.0.0.1:8773', path='/',
check_type='ec2', headers=None):
@@ -358,6 +365,27 @@ class AuthManager(object):
if self.has_role(user, role):
return True
+ def _build_mc_key(self, user, role, project=None):
+ key_parts = ['rolecache', User.safe_id(user), str(role)]
+ if project:
+ key_parts.append(Project.safe_id(project))
+ return '-'.join(key_parts)
+
+ def _clear_mc_key(self, user, role, project=None):
+ # NOTE(anthony): it would be better to delete the key
+ self.mc.set(self._build_mc_key(user, role, project), None)
+
+ def _has_role(self, user, role, project=None):
+ mc_key = self._build_mc_key(user, role, project)
+ rslt = self.mc.get(mc_key)
+ if rslt is None:
+ with self.driver() as drv:
+ rslt = drv.has_role(user, role, project)
+ self.mc.set(mc_key, rslt)
+ return rslt
+ else:
+ return rslt
+
def has_role(self, user, role, project=None):
"""Checks existence of role for user
@@ -381,24 +409,24 @@ class AuthManager(object):
@rtype: bool
@return: True if the user has the role.
"""
- with self.driver() as drv:
- if role == 'projectmanager':
- if not project:
- raise exception.Error(_("Must specify project"))
- return self.is_project_manager(user, project)
+ if role == 'projectmanager':
+ if not project:
+ raise exception.Error(_("Must specify project"))
+ return self.is_project_manager(user, project)
+
+ global_role = self._has_role(User.safe_id(user),
+ role,
+ None)
- global_role = drv.has_role(User.safe_id(user),
- role,
- None)
- if not global_role:
- return global_role
+ if not global_role:
+ return global_role
- if not project or role in FLAGS.global_roles:
- return global_role
+ if not project or role in FLAGS.global_roles:
+ return global_role
- return drv.has_role(User.safe_id(user),
- role,
- Project.safe_id(project))
+ return self._has_role(User.safe_id(user),
+ role,
+ Project.safe_id(project))
def add_role(self, user, role, project=None):
"""Adds role for user
@@ -430,6 +458,7 @@ class AuthManager(object):
LOG.audit(_("Adding sitewide role %(role)s to user %(uid)s")
% locals())
with self.driver() as drv:
+ self._clear_mc_key(uid, role, pid)
drv.add_role(uid, role, pid)
def remove_role(self, user, role, project=None):
@@ -458,6 +487,7 @@ class AuthManager(object):
LOG.audit(_("Removing sitewide role %(role)s"
" from user %(uid)s") % locals())
with self.driver() as drv:
+ self._clear_mc_key(uid, role, pid)
drv.remove_role(uid, role, pid)
@staticmethod
diff --git a/nova/flags.py b/nova/flags.py
index 2357fc3a8..519793643 100644
--- a/nova/flags.py
+++ b/nova/flags.py
@@ -369,6 +369,9 @@ DEFINE_string('host', socket.gethostname(),
DEFINE_string('node_availability_zone', 'nova',
'availability zone of this node')
+DEFINE_list('memcached_servers', None,
+ 'Memcached servers or None for in process cache.')
+
DEFINE_string('zone_name', 'nova', 'name of this zone')
DEFINE_list('zone_capabilities',
['hypervisor=xenserver;kvm', 'os=linux;windows'],