]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
moving all middleware code in cinder.api.middleware
authorMike Perez <thingee@gmail.com>
Sun, 4 Nov 2012 09:20:47 +0000 (01:20 -0800)
committerMike Perez <thingee@gmail.com>
Thu, 22 Nov 2012 05:26:40 +0000 (21:26 -0800)
This includes auth, sizelimit, and faultwrapper middleware. Test
directory struture has been adjusted to match.

progress on blueprint apiv2

Change-Id: I62eecb208553abfee8dc8d2679264884b4cec153

13 files changed:
cinder/api/middleware/__init__.py [new file with mode: 0644]
cinder/api/middleware/auth.py [moved from cinder/api/auth.py with 65% similarity]
cinder/api/middleware/fault.py [new file with mode: 0644]
cinder/api/middleware/sizelimit.py [moved from cinder/api/sizelimit.py with 100% similarity]
cinder/api/openstack/__init__.py
cinder/api/openstack/auth.py [deleted file]
cinder/tests/api/middleware/__init__.py [new file with mode: 0644]
cinder/tests/api/middleware/test_auth.py [moved from cinder/tests/api/test_auth.py with 93% similarity]
cinder/tests/api/middleware/test_faults.py [moved from cinder/tests/api/openstack/test_faults.py with 100% similarity]
cinder/tests/api/middleware/test_sizelimit.py [moved from cinder/tests/api/test_sizelimit.py with 91% similarity]
cinder/tests/api/openstack/fakes.py
cinder/tests/test_wsgi.py
etc/cinder/api-paste.ini

diff --git a/cinder/api/middleware/__init__.py b/cinder/api/middleware/__init__.py
new file mode 100644 (file)
index 0000000..d65c689
--- /dev/null
@@ -0,0 +1,16 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2011 OpenStack LLC.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
similarity index 65%
rename from cinder/api/auth.py
rename to cinder/api/middleware/auth.py
index cea6c60c5d7e4f299263fee5dad88cfac19cc3e8..e806576d8e4bb86fc8d03347df1b2963e66176fa 100644 (file)
@@ -1,6 +1,7 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 
-# Copyright (c) 2011 OpenStack, LLC
+# Copyright 2010 OpenStack LLC.
+# All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
 #    not use this file except in compliance with the License. You may obtain
 Common Auth Middleware.
 
 """
+import os
 
 import webob.dec
 import webob.exc
 
+from cinder.api.openstack import wsgi
 from cinder import context
 from cinder import flags
 from cinder.openstack.common import cfg
 from cinder.openstack.common import log as logging
-from cinder import wsgi
+from cinder import wsgi as base_wsgi
 
 
 use_forwarded_for_opt = cfg.BoolOpt('use_forwarded_for',
@@ -53,23 +56,23 @@ def pipeline_factory(loader, global_conf, **local_conf):
     return app
 
 
-class InjectContext(wsgi.Middleware):
+class InjectContext(base_wsgi.Middleware):
     """Add a 'cinder.context' to WSGI environ."""
 
     def __init__(self, context, *args, **kwargs):
         self.context = context
         super(InjectContext, self).__init__(*args, **kwargs)
 
-    @webob.dec.wsgify(RequestClass=wsgi.Request)
+    @webob.dec.wsgify(RequestClass=base_wsgi.Request)
     def __call__(self, req):
         req.environ['cinder.context'] = self.context
         return self.application
 
 
-class CinderKeystoneContext(wsgi.Middleware):
+class CinderKeystoneContext(base_wsgi.Middleware):
     """Make a request context from keystone headers"""
 
-    @webob.dec.wsgify(RequestClass=wsgi.Request)
+    @webob.dec.wsgify(RequestClass=base_wsgi.Request)
     def __call__(self, req):
         user_id = req.headers.get('X_USER')
         user_id = req.headers.get('X_USER_ID', user_id)
@@ -101,3 +104,37 @@ class CinderKeystoneContext(wsgi.Middleware):
 
         req.environ['cinder.context'] = ctx
         return self.application
+
+
+class NoAuthMiddleware(base_wsgi.Middleware):
+    """Return a fake token if one isn't specified."""
+
+    @webob.dec.wsgify(RequestClass=wsgi.Request)
+    def __call__(self, req):
+        if 'X-Auth-Token' not in req.headers:
+            user_id = req.headers.get('X-Auth-User', 'admin')
+            project_id = req.headers.get('X-Auth-Project-Id', 'admin')
+            os_url = os.path.join(req.url, project_id)
+            res = webob.Response()
+            # NOTE(vish): This is expecting and returning Auth(1.1), whereas
+            #             keystone uses 2.0 auth.  We should probably allow
+            #             2.0 auth here as well.
+            res.headers['X-Auth-Token'] = '%s:%s' % (user_id, project_id)
+            res.headers['X-Server-Management-Url'] = os_url
+            res.content_type = 'text/plain'
+            res.status = '204'
+            return res
+
+        token = req.headers['X-Auth-Token']
+        user_id, _sep, project_id = token.partition(':')
+        project_id = project_id or user_id
+        remote_address = getattr(req, 'remote_address', '127.0.0.1')
+        if FLAGS.use_forwarded_for:
+            remote_address = req.headers.get('X-Forwarded-For', remote_address)
+        ctx = context.RequestContext(user_id,
+                                     project_id,
+                                     is_admin=True,
+                                     remote_address=remote_address)
+
+        req.environ['cinder.context'] = ctx
+        return self.application
diff --git a/cinder/api/middleware/fault.py b/cinder/api/middleware/fault.py
new file mode 100644 (file)
index 0000000..15892b4
--- /dev/null
@@ -0,0 +1,75 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2010 United States Government as represented by the
+# Administrator of the National Aeronautics and Space Administration.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import webob.dec
+import webob.exc
+
+from cinder.api.openstack import wsgi
+from cinder.openstack.common import log as logging
+from cinder import utils
+from cinder import wsgi as base_wsgi
+
+
+LOG = logging.getLogger(__name__)
+
+
+class FaultWrapper(base_wsgi.Middleware):
+    """Calls down the middleware stack, making exceptions into faults."""
+
+    _status_to_type = {}
+
+    @staticmethod
+    def status_to_type(status):
+        if not FaultWrapper._status_to_type:
+            for clazz in utils.walk_class_hierarchy(webob.exc.HTTPError):
+                FaultWrapper._status_to_type[clazz.code] = clazz
+        return FaultWrapper._status_to_type.get(
+                                  status, webob.exc.HTTPInternalServerError)()
+
+    def _error(self, inner, req):
+        LOG.exception(_("Caught error: %s"), unicode(inner))
+
+        safe = getattr(inner, 'safe', False)
+        headers = getattr(inner, 'headers', None)
+        status = getattr(inner, 'code', 500)
+        if status is None:
+            status = 500
+
+        msg_dict = dict(url=req.url, status=status)
+        LOG.info(_("%(url)s returned with HTTP %(status)d") % msg_dict)
+        outer = self.status_to_type(status)
+        if headers:
+            outer.headers = headers
+        # NOTE(johannes): We leave the explanation empty here on
+        # purpose. It could possibly have sensitive information
+        # that should not be returned back to the user. See
+        # bugs 868360 and 874472
+        # NOTE(eglynn): However, it would be over-conservative and
+        # inconsistent with the EC2 API to hide every exception,
+        # including those that are safe to expose, see bug 1021373
+        if safe:
+            outer.explanation = '%s: %s' % (inner.__class__.__name__,
+                                            unicode(inner))
+        return wsgi.Fault(outer)
+
+    @webob.dec.wsgify(RequestClass=wsgi.Request)
+    def __call__(self, req):
+        try:
+            return req.get_response(self.application)
+        except Exception as ex:
+            return self._error(ex, req)
index 9f6079dd3a5936673cdd839767a4716ba57931ac..d68639860caa469eacb97d956803731b5e2dd921 100644 (file)
@@ -21,8 +21,6 @@ WSGI middleware for OpenStack API controllers.
 """
 
 import routes
-import webob.dec
-import webob.exc
 
 from cinder.api.openstack import wsgi
 from cinder.openstack.common import log as logging
@@ -33,53 +31,6 @@ from cinder import wsgi as base_wsgi
 LOG = logging.getLogger(__name__)
 
 
-class FaultWrapper(base_wsgi.Middleware):
-    """Calls down the middleware stack, making exceptions into faults."""
-
-    _status_to_type = {}
-
-    @staticmethod
-    def status_to_type(status):
-        if not FaultWrapper._status_to_type:
-            for clazz in utils.walk_class_hierarchy(webob.exc.HTTPError):
-                FaultWrapper._status_to_type[clazz.code] = clazz
-        return FaultWrapper._status_to_type.get(
-                                  status, webob.exc.HTTPInternalServerError)()
-
-    def _error(self, inner, req):
-        LOG.exception(_("Caught error: %s"), unicode(inner))
-
-        safe = getattr(inner, 'safe', False)
-        headers = getattr(inner, 'headers', None)
-        status = getattr(inner, 'code', 500)
-        if status is None:
-            status = 500
-
-        msg_dict = dict(url=req.url, status=status)
-        LOG.info(_("%(url)s returned with HTTP %(status)d") % msg_dict)
-        outer = self.status_to_type(status)
-        if headers:
-            outer.headers = headers
-        # NOTE(johannes): We leave the explanation empty here on
-        # purpose. It could possibly have sensitive information
-        # that should not be returned back to the user. See
-        # bugs 868360 and 874472
-        # NOTE(eglynn): However, it would be over-conservative and
-        # inconsistent with the EC2 API to hide every exception,
-        # including those that are safe to expose, see bug 1021373
-        if safe:
-            outer.explanation = '%s: %s' % (inner.__class__.__name__,
-                                            unicode(inner))
-        return wsgi.Fault(outer)
-
-    @webob.dec.wsgify(RequestClass=wsgi.Request)
-    def __call__(self, req):
-        try:
-            return req.get_response(self.application)
-        except Exception as ex:
-            return self._error(ex, req)
-
-
 class APIMapper(routes.Mapper):
     def routematch(self, url=None, environ=None):
         if url is "":
diff --git a/cinder/api/openstack/auth.py b/cinder/api/openstack/auth.py
deleted file mode 100644 (file)
index 68c98da..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 OpenStack LLC.
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import os
-
-import webob.dec
-import webob.exc
-
-from cinder.api.openstack import wsgi
-from cinder import context
-from cinder import flags
-from cinder.openstack.common import log as logging
-from cinder import wsgi as base_wsgi
-
-LOG = logging.getLogger(__name__)
-FLAGS = flags.FLAGS
-flags.DECLARE('use_forwarded_for', 'cinder.api.auth')
-
-
-class NoAuthMiddleware(base_wsgi.Middleware):
-    """Return a fake token if one isn't specified."""
-
-    @webob.dec.wsgify(RequestClass=wsgi.Request)
-    def __call__(self, req):
-        if 'X-Auth-Token' not in req.headers:
-            user_id = req.headers.get('X-Auth-User', 'admin')
-            project_id = req.headers.get('X-Auth-Project-Id', 'admin')
-            os_url = os.path.join(req.url, project_id)
-            res = webob.Response()
-            # NOTE(vish): This is expecting and returning Auth(1.1), whereas
-            #             keystone uses 2.0 auth.  We should probably allow
-            #             2.0 auth here as well.
-            res.headers['X-Auth-Token'] = '%s:%s' % (user_id, project_id)
-            res.headers['X-Server-Management-Url'] = os_url
-            res.content_type = 'text/plain'
-            res.status = '204'
-            return res
-
-        token = req.headers['X-Auth-Token']
-        user_id, _sep, project_id = token.partition(':')
-        project_id = project_id or user_id
-        remote_address = getattr(req, 'remote_address', '127.0.0.1')
-        if FLAGS.use_forwarded_for:
-            remote_address = req.headers.get('X-Forwarded-For', remote_address)
-        ctx = context.RequestContext(user_id,
-                                     project_id,
-                                     is_admin=True,
-                                     remote_address=remote_address)
-
-        req.environ['cinder.context'] = ctx
-        return self.application
diff --git a/cinder/tests/api/middleware/__init__.py b/cinder/tests/api/middleware/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
similarity index 93%
rename from cinder/tests/api/test_auth.py
rename to cinder/tests/api/middleware/test_auth.py
index cfb8b7775c415619ca30bfd10ffec22f68f2d496..4fca13fe62cba2357b555cff4a165e39c3c13a64 100644 (file)
@@ -14,7 +14,7 @@
 
 import webob
 
-import cinder.api.auth
+import cinder.api.middleware.auth
 from cinder import test
 
 
@@ -29,7 +29,8 @@ class TestCinderKeystoneContextMiddleware(test.TestCase):
             return webob.Response()
 
         self.context = None
-        self.middleware = cinder.api.auth.CinderKeystoneContext(fake_app)
+        self.middleware = (cinder.api.middleware.auth
+                           .CinderKeystoneContext(fake_app))
         self.request = webob.Request.blank('/')
         self.request.headers['X_TENANT_ID'] = 'testtenantid'
         self.request.headers['X_AUTH_TOKEN'] = 'testauthtoken'
similarity index 91%
rename from cinder/tests/api/test_sizelimit.py
rename to cinder/tests/api/middleware/test_sizelimit.py
index 280ee9c29d78ec79db958aba1b4812112f116f3e..0a151dabf4f558a0da40cb34e06b976f08a186ff 100644 (file)
@@ -14,7 +14,7 @@
 
 import webob
 
-import cinder.api.sizelimit
+import cinder.api.middleware.sizelimit
 from cinder import flags
 from cinder import test
 
@@ -31,7 +31,8 @@ class TestRequestBodySizeLimiter(test.TestCase):
         def fake_app(req):
             return webob.Response()
 
-        self.middleware = cinder.api.sizelimit.RequestBodySizeLimiter(fake_app)
+        self.middleware = (cinder.api.middleware.sizelimit
+                           .RequestBodySizeLimiter(fake_app))
         self.request = webob.Request.blank('/', method='POST')
 
     def test_content_length_acceptable(self):
index cbc8613b3ffff1d3ccb7bd423bf880e58be7a4d6..87c2a61d3c3bb42385016b9e4b28be9284aa8310 100644 (file)
@@ -23,9 +23,8 @@ import webob
 import webob.dec
 import webob.request
 
-from cinder.api import auth as api_auth
-from cinder.api import openstack as openstack_api
-from cinder.api.openstack import auth
+from cinder.api.middleware import auth
+from cinder.api.middleware import fault
 from cinder.api.openstack import volume
 from cinder.api.openstack.volume import limits
 from cinder.api.openstack import wsgi as os_wsgi
@@ -72,18 +71,18 @@ def wsgi_app(inner_app_v1=None, fake_auth=True, fake_auth_context=None,
             ctxt = fake_auth_context
         else:
             ctxt = context.RequestContext('fake', 'fake', auth_token=True)
-        api_v1 = openstack_api.FaultWrapper(api_auth.InjectContext(ctxt,
+        api_v1 = fault.FaultWrapper(auth.InjectContext(ctxt,
               inner_app_v1))
     elif use_no_auth:
-        api_v1 = openstack_api.FaultWrapper(auth.NoAuthMiddleware(
+        api_v1 = fault.FaultWrapper(auth.NoAuthMiddleware(
               limits.RateLimitingMiddleware(inner_app_v1)))
     else:
-        api_v1 = openstack_api.FaultWrapper(auth.AuthMiddleware(
+        api_v1 = fault.FaultWrapper(auth.AuthMiddleware(
               limits.RateLimitingMiddleware(inner_app_v1)))
 
     mapper = urlmap.URLMap()
     mapper['/v1'] = api_v1
-    mapper['/'] = openstack_api.FaultWrapper(versions.Versions())
+    mapper['/'] = fault.FaultWrapper(versions.Versions())
     return mapper
 
 
index f9189afa77047b2283e382e2db082c4055c242e7..08b933809050092a32745925f470007c194d287f 100644 (file)
@@ -24,7 +24,7 @@ import tempfile
 import unittest
 import webob.dec
 
-from cinder.api import openstack as openstack_api
+from cinder.api.middleware import fault
 from cinder import exception
 from cinder import test
 import cinder.wsgi
@@ -97,7 +97,7 @@ class TestWSGIServer(unittest.TestCase):
 class ExceptionTest(test.TestCase):
 
     def _wsgi_app(self, inner_app):
-        return openstack_api.FaultWrapper(inner_app)
+        return fault.FaultWrapper(inner_app)
 
     def _do_test_exception_safety_reflected_in_faults(self, expose):
         class ExceptionWithSafety(exception.CinderException):
index 575f4bd6a6d03eb606c2d2fabb7fd24b1470ea70..c7c5baf7e90265675b86084a10ca591ab61d868b 100644 (file)
@@ -8,19 +8,19 @@ use = call:cinder.api.urlmap:urlmap_factory
 /v1: openstack_volume_api_v1
 
 [composite:openstack_volume_api_v1]
-use = call:cinder.api.auth:pipeline_factory
+use = call:cinder.api.middleware.auth:pipeline_factory
 noauth = faultwrap sizelimit noauth osapi_volume_app_v1
 keystone = faultwrap sizelimit authtoken keystonecontext osapi_volume_app_v1
 keystone_nolimit = faultwrap sizelimit authtoken keystonecontext osapi_volume_app_v1
 
 [filter:faultwrap]
-paste.filter_factory = cinder.api.openstack:FaultWrapper.factory
+paste.filter_factory = cinder.api.middleware.fault:FaultWrapper.factory
 
 [filter:noauth]
-paste.filter_factory = cinder.api.openstack.auth:NoAuthMiddleware.factory
+paste.filter_factory = cinder.api.middleware.auth:NoAuthMiddleware.factory
 
 [filter:sizelimit]
-paste.filter_factory = cinder.api.sizelimit:RequestBodySizeLimiter.factory
+paste.filter_factory = cinder.api.middleware.sizelimit:RequestBodySizeLimiter.factory
 
 [app:osapi_volume_app_v1]
 paste.app_factory = cinder.api.openstack.volume:APIRouter.factory
@@ -36,7 +36,7 @@ paste.app_factory = cinder.api.versions:Versions.factory
 ##########
 
 [filter:keystonecontext]
-paste.filter_factory = cinder.api.auth:CinderKeystoneContext.factory
+paste.filter_factory = cinder.api.middleware.auth:CinderKeystoneContext.factory
 
 [filter:authtoken]
 paste.filter_factory = keystone.middleware.auth_token:filter_factory