summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorCerberus <matt.dietz@rackspace.com>2010-12-22 13:18:26 -0600
committerCerberus <matt.dietz@rackspace.com>2010-12-22 13:18:26 -0600
commitc4fb755b169895f9ffab6ab4d18f5227688b7ae4 (patch)
tree53c9a8e64850fc3a7a9d0f88c3eea3a15b810354 /nova/api
parentaa1c251eecdf16a7e819602207bf5c65a55e914d (diff)
Abstracted auth and ratelimiting more
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/openstack/__init__.py56
-rw-r--r--nova/api/openstack/auth.py22
-rw-r--r--nova/api/openstack/ratelimiting/__init__.py22
3 files changed, 43 insertions, 57 deletions
diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py
index cdc25e2b7..b18edc8e7 100644
--- a/nova/api/openstack/__init__.py
+++ b/nova/api/openstack/__init__.py
@@ -45,12 +45,12 @@ from nova.auth import manager
FLAGS = flags.FLAGS
-flags.DEFINE_string('nova_api_auth',
- 'nova.api.openstack.auth.BasicApiAuthManager',
+flags.DEFINE_string('os_api_auth',
+ 'nova.api.openstack.auth.AuthMiddleware',
'The auth mechanism to use for the OpenStack API implemenation')
flags.DEFINE_string('os_api_ratelimiting',
- 'nova.api.openstack.ratelimiting.BasicRateLimiting',
+ 'nova.api.openstack.ratelimiting.RateLimitingMiddleware',
'Default ratelimiting implementation for the Openstack API')
flags.DEFINE_bool('allow_admin_api',
@@ -62,7 +62,10 @@ class API(wsgi.Middleware):
"""WSGI entry point for all OpenStack API requests."""
def __init__(self):
- app = AuthMiddleware(RateLimitingMiddleware(APIRouter()))
+ auth_middleware = utils.import_class(FLAGS.os_api_auth)
+ ratelimiting_middleware = \
+ utils.import_class(FLAGS.os_api_ratelimiting)
+ app = auth_middleware(ratelimiting_middleware(APIRouter()))
super(API, self).__init__(app)
@webob.dec.wsgify
@@ -76,51 +79,6 @@ class API(wsgi.Middleware):
return faults.Fault(exc)
-class AuthMiddleware(wsgi.Middleware):
- """Authorize the openstack API request or return an HTTP Forbidden."""
-
- def __init__(self, application):
- self.auth_driver = utils.import_class(FLAGS.nova_api_auth)()
- super(AuthMiddleware, self).__init__(application)
-
- @webob.dec.wsgify
- def __call__(self, req):
- if not self.auth_driver.has_authentication(req):
- return self.auth_driver.authenticate(req)
-
- user = self.auth_driver.get_user_by_authentication(req)
-
- if not user:
- return faults.Fault(webob.exc.HTTPUnauthorized())
-
- req.environ['nova.context'] = context.RequestContext(user, user)
- return self.application
-
-
-class RateLimitingMiddleware(wsgi.Middleware):
- """Rate limit incoming requests according to the OpenStack rate limits."""
-
- def __init__(self, application, service_host=None):
- """Create a rate limiting middleware that wraps the given application.
-
- By default, rate counters are stored in memory. If service_host is
- specified, the middleware instead relies on the ratelimiting.WSGIApp
- at the given host+port to keep rate counters.
- """
- super(RateLimitingMiddleware, self).__init__(application)
- self._limiting_driver = \
- utils.import_class(FLAGS.os_api_ratelimiting)(service_host)
-
- @webob.dec.wsgify
- def __call__(self, req):
- """Rate limit the request.
-
- If the request should be rate limited, return a 413 status with a
- Retry-After header giving the time when the request would succeed.
- """
- return self._limiting_driver.limited_request(req, self.application)
-
-
class APIRouter(wsgi.Router):
"""
Routes requests on the OpenStack API to the appropriate controller
diff --git a/nova/api/openstack/auth.py b/nova/api/openstack/auth.py
index 26cb50dca..3850dd1f0 100644
--- a/nova/api/openstack/auth.py
+++ b/nova/api/openstack/auth.py
@@ -16,16 +16,28 @@ from nova.api.openstack import faults
FLAGS = flags.FLAGS
+class AuthMiddleware(wsgi.Middleware):
+ """Authorize the openstack API request or return an HTTP Forbidden."""
-class BasicApiAuthManager(object):
- """ Implements a somewhat rudimentary version of OpenStack Auth"""
-
- def __init__(self, db_driver=None):
+ def __init__(self, application):
if not db_driver:
db_driver = FLAGS.db_driver
self.db = utils.import_object(db_driver)
self.auth = auth.manager.AuthManager()
- super(BasicApiAuthManager, self).__init__()
+ super(AuthMiddleware, self).__init__(application)
+
+ @webob.dec.wsgify
+ def __call__(self, req):
+ if not self.has_authentication(req):
+ return self.authenticate(req)
+
+ user = self.get_user_by_authentication(req)
+
+ if not user:
+ return faults.Fault(webob.exc.HTTPUnauthorized())
+
+ req.environ['nova.context'] = context.RequestContext(user, user)
+ return self.application
def has_authentication(self, req):
return 'X-Auth-Token' in req.headers
diff --git a/nova/api/openstack/ratelimiting/__init__.py b/nova/api/openstack/ratelimiting/__init__.py
index 1bf44bc7b..9892e792e 100644
--- a/nova/api/openstack/ratelimiting/__init__.py
+++ b/nova/api/openstack/ratelimiting/__init__.py
@@ -14,11 +14,16 @@ PER_MINUTE = 60
PER_HOUR = 60 * 60
PER_DAY = 60 * 60 * 24
+class RateLimitingMiddleware(wsgi.Middleware):
+ """Rate limit incoming requests according to the OpenStack rate limits."""
-class BasicRateLimiting(object):
- """ Implements Rate limits as per the Rackspace CloudServers API spec. """
+ def __init__(self, application, service_host=None):
+ """Create a rate limiting middleware that wraps the given application.
- def __init__(self, service_host):
+ By default, rate counters are stored in memory. If service_host is
+ specified, the middleware instead relies on the ratelimiting.WSGIApp
+ at the given host+port to keep rate counters.
+ """
if not service_host:
#TODO(gundlach): These limits were based on limitations of Cloud
#Servers. We should revisit them in Nova.
@@ -31,6 +36,16 @@ class BasicRateLimiting(object):
})
else:
self.limiter = WSGIAppProxy(service_host)
+ super(RateLimitingMiddleware, self).__init__(application)
+
+ @webob.dec.wsgify
+ def __call__(self, req):
+ """Rate limit the request.
+
+ If the request should be rate limited, return a 413 status with a
+ Retry-After header giving the time when the request would succeed.
+ """
+ return self.limited_request(req, self.application)
def limited_request(self, req, application):
"""Rate limit the request.
@@ -75,6 +90,7 @@ class BasicRateLimiting(object):
return req.method
return None
+
class Limiter(object):
"""Class providing rate limiting of arbitrary actions."""