Move to the oslo.middleware library
This patch moves Cinder to using olso.middleware, updates us so we are using the oslo_middleware namespace and syncs the latest middleware code from oslo-incubator to support grenade jobs. The details for the middleware sync from oslo-incubator are as follows: Current HEAD in OSLO: --------------------- commit e589dde0721a0a67e4030813e582afec6e70d042 Date: Wed Feb 18 03:08:12 2015 +0000 Merge "Have a little fun with release notes" Changes merged with this patch: --------------------- __init__.py 4ffc4c87 - Add middleware.request_id shim for Kilo 4504e4f4 - Remove middleware catch_errors.py a01a8527 - Use oslo_middleware instead of deprecated oslo.middleware ce8f8fa4 - Add middleware.catch_errors shim for Kilo 4504e4f4 - Remove middleware 5d40e143 - Remove code that moved to oslo.i18n 76183592 - add deprecation note to middleware 463e6916 - remove oslo log from middleware fcf517d7 - Update oslo log messages with translation domains request_id.py a01a8527 - Use oslo_middleware instead of deprecated oslo.middleware 66d8d613 - Fix oslo.middleware deprecation error 4ffc4c87 - Add middleware.request_id shim for Kilo 4504e4f4 - Remove middleware 76183592 - add deprecation note to middleware d7bd9dc3 - Don't store the request ID value in middleware as class variable Some notes on this change. It is based on the change made in Nova: https://review.openstack.org/#/c/130771 and is the recommended method for cleaning up the unused portions of middleware from oslo-incubator, moving to the oslo.middleware library and not breaking grenade in the gate. Change-Id: Ia99ab479cb8ef63a0db1a1208cc2501abba6132c
This commit is contained in:
parent
99c0701ae1
commit
c489747177
cinder
api/middleware
openstack/common/middleware
tests/api/middleware
etc/cinder
requirements.txtsetup.cfg@ -22,6 +22,7 @@ import os
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_middleware import request_id
|
||||
from oslo_serialization import jsonutils
|
||||
import webob.dec
|
||||
import webob.exc
|
||||
@ -29,7 +30,6 @@ import webob.exc
|
||||
from cinder.api.openstack import wsgi
|
||||
from cinder import context
|
||||
from cinder.i18n import _
|
||||
from cinder.openstack.common.middleware import request_id
|
||||
from cinder import wsgi as base_wsgi
|
||||
|
||||
|
||||
|
@ -13,17 +13,14 @@
|
||||
# under the License.
|
||||
"""
|
||||
Request Body limiting middleware.
|
||||
|
||||
Compatibility shim for Kilo, while operators migrate to oslo.middleware.
|
||||
"""
|
||||
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
import webob.dec
|
||||
import webob.exc
|
||||
from oslo_middleware import sizelimit
|
||||
|
||||
from cinder.i18n import _
|
||||
from cinder import wsgi
|
||||
from cinder.openstack.common import versionutils
|
||||
|
||||
|
||||
# Default request size is 112k
|
||||
@ -34,52 +31,9 @@ max_request_body_size_opt = cfg.IntOpt('osapi_max_request_body_size',
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opt(max_request_body_size_opt)
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LimitingReader(object):
|
||||
"""Reader to limit the size of an incoming request."""
|
||||
def __init__(self, data, limit):
|
||||
"""Initialize LimitingReader.
|
||||
|
||||
:param data: Underlying data object
|
||||
:param limit: maximum number of bytes the reader should allow
|
||||
"""
|
||||
self.data = data
|
||||
self.limit = limit
|
||||
self.bytes_read = 0
|
||||
|
||||
def __iter__(self):
|
||||
for chunk in self.data:
|
||||
self.bytes_read += len(chunk)
|
||||
if self.bytes_read > self.limit:
|
||||
msg = _("Request is too large.")
|
||||
raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg)
|
||||
else:
|
||||
yield chunk
|
||||
|
||||
def read(self, i=None):
|
||||
result = self.data.read(i)
|
||||
self.bytes_read += len(result)
|
||||
if self.bytes_read > self.limit:
|
||||
msg = _("Request is too large.")
|
||||
raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg)
|
||||
return result
|
||||
|
||||
|
||||
class RequestBodySizeLimiter(wsgi.Middleware):
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.KILO,
|
||||
in_favor_of='oslo_middleware.RequestBodySizeLimiter')
|
||||
class RequestBodySizeLimiter(sizelimit.RequestBodySizeLimiter):
|
||||
"""Add a 'cinder.context' to WSGI environ."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(RequestBodySizeLimiter, self).__init__(*args, **kwargs)
|
||||
|
||||
@webob.dec.wsgify(RequestClass=wsgi.Request)
|
||||
def __call__(self, req):
|
||||
if req.content_length > CONF.osapi_max_request_body_size:
|
||||
msg = _("Request is too large.")
|
||||
raise webob.exc.HTTPRequestEntityTooLarge(explanation=msg)
|
||||
if req.content_length is None and req.is_body_readable:
|
||||
limiter = LimitingReader(req.body_file,
|
||||
CONF.osapi_max_request_body_size)
|
||||
req.body_file = limiter
|
||||
return self.application
|
||||
pass
|
||||
|
@ -1,56 +0,0 @@
|
||||
# Copyright 2011 OpenStack Foundation.
|
||||
# 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.
|
||||
|
||||
"""Base class(es) for WSGI Middleware."""
|
||||
|
||||
import webob.dec
|
||||
|
||||
|
||||
class Middleware(object):
|
||||
"""Base WSGI middleware wrapper.
|
||||
|
||||
These classes require an application to be initialized that will be called
|
||||
next. By default the middleware will simply call its wrapped app, or you
|
||||
can override __call__ to customize its behavior.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def factory(cls, global_conf, **local_conf):
|
||||
"""Factory method for paste.deploy."""
|
||||
return cls
|
||||
|
||||
def __init__(self, application):
|
||||
self.application = application
|
||||
|
||||
def process_request(self, req):
|
||||
"""Called on each request.
|
||||
|
||||
If this returns None, the next application down the stack will be
|
||||
executed. If it returns a response then that response will be returned
|
||||
and execution will stop here.
|
||||
"""
|
||||
return None
|
||||
|
||||
def process_response(self, response):
|
||||
"""Do whatever you'd like to the response."""
|
||||
return response
|
||||
|
||||
@webob.dec.wsgify
|
||||
def __call__(self, req):
|
||||
response = self.process_request(req)
|
||||
if response:
|
||||
return response
|
||||
response = req.get_response(self.application)
|
||||
return self.process_response(response)
|
@ -12,12 +12,12 @@
|
||||
|
||||
"""Compatibility shim for Kilo, while operators migrate to oslo.middleware."""
|
||||
|
||||
from oslo.middleware import catch_errors
|
||||
from oslo_middleware import catch_errors
|
||||
|
||||
from cinder.openstack.common import versionutils
|
||||
|
||||
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.KILO,
|
||||
in_favor_of='oslo.middleware.CatchErrors')
|
||||
in_favor_of='oslo_middleware.CatchErrors')
|
||||
class CatchErrorsMiddleware(catch_errors.CatchErrors):
|
||||
pass
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
"""Compatibility shim for Kilo, while operators migrate to oslo.middleware."""
|
||||
|
||||
from oslo.middleware import request_id
|
||||
from oslo_middleware import request_id
|
||||
|
||||
from cinder.openstack.common import versionutils
|
||||
|
||||
@ -22,6 +22,6 @@ HTTP_RESP_HEADER_REQUEST_ID = 'x-openstack-request-id'
|
||||
|
||||
|
||||
@versionutils.deprecated(as_of=versionutils.deprecated.KILO,
|
||||
in_favor_of='oslo.middleware.RequestId')
|
||||
in_favor_of='oslo_middleware.RequestId')
|
||||
class RequestIdMiddleware(request_id.RequestId):
|
||||
pass
|
||||
|
@ -12,10 +12,10 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_middleware import request_id
|
||||
import webob
|
||||
|
||||
import cinder.api.middleware.auth
|
||||
from cinder.openstack.common.middleware import request_id
|
||||
from cinder import test
|
||||
|
||||
|
||||
|
@ -1,102 +0,0 @@
|
||||
# Copyright (c) 2012 OpenStack Foundation
|
||||
#
|
||||
# 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.
|
||||
|
||||
from oslo_config import cfg
|
||||
import six
|
||||
import webob
|
||||
|
||||
from cinder.api.middleware import sizelimit
|
||||
from cinder import test
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
MAX_REQUEST_BODY_SIZE = CONF.osapi_max_request_body_size
|
||||
|
||||
|
||||
class TestLimitingReader(test.TestCase):
|
||||
|
||||
def test_limiting_reader(self):
|
||||
BYTES = 1024
|
||||
bytes_read = 0
|
||||
data = six.StringIO("*" * BYTES)
|
||||
for chunk in sizelimit.LimitingReader(data, BYTES):
|
||||
bytes_read += len(chunk)
|
||||
|
||||
self.assertEqual(bytes_read, BYTES)
|
||||
|
||||
bytes_read = 0
|
||||
data = six.StringIO("*" * BYTES)
|
||||
reader = sizelimit.LimitingReader(data, BYTES)
|
||||
byte = reader.read(1)
|
||||
while len(byte) != 0:
|
||||
bytes_read += 1
|
||||
byte = reader.read(1)
|
||||
|
||||
self.assertEqual(bytes_read, BYTES)
|
||||
|
||||
def test_limiting_reader_fails(self):
|
||||
BYTES = 1024
|
||||
|
||||
def _consume_all_iter():
|
||||
bytes_read = 0
|
||||
data = six.StringIO("*" * BYTES)
|
||||
for chunk in sizelimit.LimitingReader(data, BYTES - 1):
|
||||
bytes_read += len(chunk)
|
||||
|
||||
self.assertRaises(webob.exc.HTTPRequestEntityTooLarge,
|
||||
_consume_all_iter)
|
||||
|
||||
def _consume_all_read():
|
||||
bytes_read = 0
|
||||
data = six.StringIO("*" * BYTES)
|
||||
reader = sizelimit.LimitingReader(data, BYTES - 1)
|
||||
byte = reader.read(1)
|
||||
while len(byte) != 0:
|
||||
bytes_read += 1
|
||||
byte = reader.read(1)
|
||||
|
||||
self.assertRaises(webob.exc.HTTPRequestEntityTooLarge,
|
||||
_consume_all_read)
|
||||
|
||||
|
||||
class TestRequestBodySizeLimiter(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestRequestBodySizeLimiter, self).setUp()
|
||||
|
||||
@webob.dec.wsgify()
|
||||
def fake_app(req):
|
||||
return webob.Response(req.body)
|
||||
|
||||
self.middleware = sizelimit.RequestBodySizeLimiter(fake_app)
|
||||
self.request = webob.Request.blank('/', method='POST')
|
||||
|
||||
def test_content_length_acceptable(self):
|
||||
self.request.headers['Content-Length'] = MAX_REQUEST_BODY_SIZE
|
||||
self.request.body = "0" * MAX_REQUEST_BODY_SIZE
|
||||
response = self.request.get_response(self.middleware)
|
||||
self.assertEqual(response.status_int, 200)
|
||||
|
||||
def test_content_length_too_large(self):
|
||||
self.request.headers['Content-Length'] = MAX_REQUEST_BODY_SIZE + 1
|
||||
self.request.body = "0" * (MAX_REQUEST_BODY_SIZE + 1)
|
||||
response = self.request.get_response(self.middleware)
|
||||
self.assertEqual(response.status_int, 413)
|
||||
|
||||
def test_request_too_large_no_content_length(self):
|
||||
self.request.body = "0" * (MAX_REQUEST_BODY_SIZE + 1)
|
||||
self.request.headers['Content-Length'] = None
|
||||
response = self.request.get_response(self.middleware)
|
||||
self.assertEqual(response.status_int, 413)
|
@ -21,7 +21,7 @@ keystone = request_id faultwrap sizelimit osprofiler authtoken keystonecontext a
|
||||
keystone_nolimit = request_id faultwrap sizelimit osprofiler authtoken keystonecontext apiv2
|
||||
|
||||
[filter:request_id]
|
||||
paste.filter_factory = cinder.openstack.common.middleware.request_id:RequestIdMiddleware.factory
|
||||
paste.filter_factory = oslo_middleware.request_id:RequestId.factory
|
||||
|
||||
[filter:faultwrap]
|
||||
paste.filter_factory = cinder.api.middleware.fault:FaultWrapper.factory
|
||||
|
@ -18,6 +18,7 @@ oslo.context>=0.1.0
|
||||
oslo.db>=1.4.1 # Apache-2.0
|
||||
oslo.log>=0.4.0 # Apache-2.0
|
||||
oslo.messaging>=1.6.0 # Apache-2.0
|
||||
oslo.middleware>=0.3.0 # Apache-2.0
|
||||
oslo.rootwrap>=1.5.0 # Apache-2.0
|
||||
oslo.serialization>=1.2.0 # Apache-2.0
|
||||
oslo.utils>=1.2.0 # Apache-2.0
|
||||
|
@ -59,6 +59,10 @@ oslo_messaging.notify.drivers =
|
||||
cinder.openstack.common.notifier.rpc_notifier2 = oslo_messaging.notify._impl_messaging:MessagingV2Driver
|
||||
cinder.openstack.common.notifier.rpc_notifier = oslo_messaging.notify._impl_messaging:MessagingDriver
|
||||
cinder.openstack.common.notifier.test_notifier = oslo_messaging.notify._impl_test:TestDriver
|
||||
# These are for backwards compatibility with Juno middleware configurations
|
||||
oslo_middleware =
|
||||
cinder.api.middleware.sizelimit = oslo_middleware.sizelimit
|
||||
cinder.openstack.common.middleware.request_id = oslo_middleware.request_id
|
||||
|
||||
cinder.database.migration_backend =
|
||||
sqlalchemy = oslo_db.sqlalchemy.migration
|
||||
|
Loading…
x
Reference in New Issue
Block a user