Allow to get option from paste-deploy
This change allows any middleware that use oslo.config to be configured via paste-deploy, like the cors does. Related-bug: #1482086 Change-Id: Ibb3e951b45b51c9bc602c9113df18a58226d92d1
This commit is contained in:
parent
e744501c47
commit
41ac7aeec2
@ -2,5 +2,8 @@
|
||||
Healthcheck middleware plugins
|
||||
================================
|
||||
|
||||
.. automodule:: oslo_middleware.healthcheck
|
||||
:members:
|
||||
|
||||
.. automodule:: oslo_middleware.healthcheck.disable_by_file
|
||||
:members:
|
||||
|
@ -10,4 +10,5 @@ Contents
|
||||
api
|
||||
healthcheck_plugins
|
||||
cors
|
||||
oslo_config
|
||||
contributing
|
||||
|
53
doc/source/oslo_config.rst
Normal file
53
doc/source/oslo_config.rst
Normal file
@ -0,0 +1,53 @@
|
||||
=============================
|
||||
Middlewares and configuration
|
||||
=============================
|
||||
|
||||
Middlewares can be configured in multiple fashion depending of the
|
||||
application needs. Here is some use-cases:
|
||||
|
||||
Configuration from the application
|
||||
----------------------------------
|
||||
|
||||
The application code will looks like::
|
||||
|
||||
from oslo_middleware import sizelimit
|
||||
from oslo_config import cfg
|
||||
|
||||
conf = cfg.ConfigOpts()
|
||||
app = sizelimit.RequestBodySizeLimiter(your_wsgi_application, conf)
|
||||
|
||||
|
||||
Configuration with paste-deploy and the oslo.config
|
||||
---------------------------------------------------
|
||||
|
||||
The paste filter (in /etc/my_app/api-paste.ini) will looks like::
|
||||
|
||||
[filter:sizelimit]
|
||||
paste.filter_factory = oslo_middleware.sizelimit:RequestBodySizeLimiter.factory
|
||||
# In case of the application doesn't use the global oslo.config
|
||||
# object. The middleware must known the app name to load
|
||||
# the application configuration, by setting this:
|
||||
# oslo_config_project = my_app
|
||||
|
||||
The oslo.config file of the application (eg: /etc/my_app/my_app.conf) will looks like::
|
||||
|
||||
[oslo_middleware]
|
||||
max_request_body_size=1000
|
||||
|
||||
|
||||
Configuration with pastedeploy only
|
||||
-----------------------------------
|
||||
|
||||
The paste filter (in /etc/my_app/api-paste.ini) will looks like::
|
||||
|
||||
[filter:sizelimit]
|
||||
paste.filter_factory = oslo_middleware.sizelimit:RequestBodySizeLimiter.factory
|
||||
max_request_body_size=1000
|
||||
|
||||
This will override any configuration done via oslo.config
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
healtcheck middleware does not yet use oslo.config, see :doc:`healthcheck_plugins`
|
||||
|
@ -63,6 +63,13 @@ class Middleware(object):
|
||||
# Fallback to global object
|
||||
self.oslo_conf = cfg.CONF
|
||||
|
||||
def _conf_get(self, key, group="oslo_middleware"):
|
||||
if key in self.conf:
|
||||
# Validate value type
|
||||
self.oslo_conf.set_override(key, self.conf[key], group=group,
|
||||
enforce_type=True)
|
||||
return getattr(getattr(self.oslo_conf, group), key)
|
||||
|
||||
def process_request(self, req):
|
||||
"""Called on each request.
|
||||
|
||||
|
@ -76,19 +76,11 @@ class CORS(base.Middleware):
|
||||
super(CORS, self).__init__(application, conf)
|
||||
# Begin constructing our configuration hash.
|
||||
self.allowed_origins = {}
|
||||
|
||||
self._init_from_oslo(self.oslo_conf)
|
||||
self._init_from_conf()
|
||||
self._init_conf()
|
||||
|
||||
@classmethod
|
||||
def factory(cls, global_conf, allowed_origin, **local_conf):
|
||||
# Ensures allowed_origin config exists
|
||||
return super(CORS, cls).factory(global_conf,
|
||||
allowed_origin=allowed_origin,
|
||||
**local_conf)
|
||||
|
||||
def _init_from_conf(self):
|
||||
"""Load configuration from paste.deploy
|
||||
"""factory method for paste.deploy
|
||||
|
||||
allowed_origin: Protocol, host, and port for the allowed origin.
|
||||
allow_credentials: Whether to permit credentials.
|
||||
@ -98,20 +90,23 @@ class CORS(base.Middleware):
|
||||
allow_headers: List of HTTP headers to permit from the client.
|
||||
"""
|
||||
|
||||
if 'allowed_origin' in self.conf:
|
||||
self.add_origin(
|
||||
allowed_origin=self.conf['allowed_origin'],
|
||||
allow_credentials=self.conf.get('allow_credentials', True),
|
||||
expose_headers=self.conf.get('expose_headers'),
|
||||
max_age=self.conf.get('max_age'),
|
||||
allow_methods=self.conf.get('allow_methods'),
|
||||
allow_headers=self.conf.get('allow_headers'))
|
||||
# Ensures allowed_origin config exists
|
||||
return super(CORS, cls).factory(global_conf,
|
||||
allowed_origin=allowed_origin,
|
||||
**local_conf)
|
||||
|
||||
def _init_from_oslo(self, conf):
|
||||
def _init_conf(self):
|
||||
'''Initialize this middleware from an oslo.config instance.'''
|
||||
|
||||
# First, check the configuration and register global options.
|
||||
conf.register_opts(CORS_OPTS, 'cors')
|
||||
self.oslo_conf.register_opts(CORS_OPTS, 'cors')
|
||||
|
||||
allowed_origin = self._conf_get('allowed_origin', 'cors')
|
||||
allow_credentials = self._conf_get('allow_credentials', 'cors')
|
||||
expose_headers = self._conf_get('expose_headers', 'cors')
|
||||
max_age = self._conf_get('max_age', 'cors')
|
||||
allow_methods = self._conf_get('allow_methods', 'cors')
|
||||
allow_headers = self._conf_get('allow_headers', 'cors')
|
||||
|
||||
# Clone our original CORS_OPTS, and set the defaults to whatever is
|
||||
# set in the global conf instance. This is done explicitly (instead
|
||||
@ -119,24 +114,29 @@ class CORS(base.Middleware):
|
||||
# allowed_origin.
|
||||
subgroup_opts = copy.deepcopy(CORS_OPTS)
|
||||
cfg.set_defaults(subgroup_opts,
|
||||
allow_credentials=conf.cors.allow_credentials,
|
||||
expose_headers=conf.cors.expose_headers,
|
||||
max_age=conf.cors.max_age,
|
||||
allow_methods=conf.cors.allow_methods,
|
||||
allow_headers=conf.cors.allow_headers)
|
||||
allow_credentials=allow_credentials,
|
||||
expose_headers=expose_headers,
|
||||
max_age=max_age,
|
||||
allow_methods=allow_methods,
|
||||
allow_headers=allow_headers)
|
||||
|
||||
# If the default configuration contains an allowed_origin, don't
|
||||
# forget to register that.
|
||||
if conf.cors.allowed_origin:
|
||||
self.add_origin(**conf.cors)
|
||||
if allowed_origin:
|
||||
self.add_origin(allowed_origin=allowed_origin,
|
||||
allow_credentials=allow_credentials,
|
||||
expose_headers=expose_headers,
|
||||
max_age=max_age,
|
||||
allow_methods=allow_methods,
|
||||
allow_headers=allow_headers)
|
||||
|
||||
# Iterate through all the loaded config sections, looking for ones
|
||||
# prefixed with 'cors.'
|
||||
for section in conf.list_all_sections():
|
||||
for section in self.oslo_conf.list_all_sections():
|
||||
if section.startswith('cors.'):
|
||||
# Register with the preconstructed defaults
|
||||
conf.register_opts(subgroup_opts, section)
|
||||
self.add_origin(**conf[section])
|
||||
self.oslo_conf.register_opts(subgroup_opts, section)
|
||||
self.add_origin(**self.oslo_conf[section])
|
||||
|
||||
def add_origin(self, allowed_origin, allow_credentials=True,
|
||||
expose_headers=None, max_age=None, allow_methods=None,
|
||||
|
@ -84,7 +84,7 @@ class RequestBodySizeLimiter(base.Middleware):
|
||||
|
||||
@webob.dec.wsgify
|
||||
def __call__(self, req):
|
||||
max_size = self.oslo_conf.oslo_middleware.max_request_body_size
|
||||
max_size = self._conf_get('max_request_body_size')
|
||||
if (req.content_length is not None and
|
||||
req.content_length > max_size):
|
||||
msg = _("Request is too large.")
|
||||
|
@ -37,7 +37,7 @@ class SSLMiddleware(base.Middleware):
|
||||
|
||||
def process_request(self, req):
|
||||
self.header_name = 'HTTP_{0}'.format(
|
||||
self.oslo_conf.oslo_middleware.secure_proxy_ssl_header.upper()
|
||||
self._conf_get('secure_proxy_ssl_header').upper()
|
||||
.replace('-', '_'))
|
||||
req.environ['wsgi.url_scheme'] = req.environ.get(
|
||||
self.header_name, req.environ['wsgi.url_scheme'])
|
||||
|
@ -131,11 +131,11 @@ class CORSTestFilterFactory(test_base.BaseTestCase):
|
||||
self.assertIn('http://valid.example.com', application.allowed_origins)
|
||||
|
||||
config = application.allowed_origins['http://valid.example.com']
|
||||
self.assertEqual('False', config['allow_credentials'])
|
||||
self.assertEqual('', config['max_age'])
|
||||
self.assertEqual('', config['expose_headers'])
|
||||
self.assertEqual('GET', config['allow_methods'])
|
||||
self.assertEqual('', config['allow_headers'])
|
||||
self.assertEqual(False, config['allow_credentials'])
|
||||
self.assertEqual(None, config['max_age'])
|
||||
self.assertEqual([], config['expose_headers'])
|
||||
self.assertEqual(['GET'], config['allow_methods'])
|
||||
self.assertEqual([], config['allow_headers'])
|
||||
|
||||
def test_no_origin_fail(self):
|
||||
'''Assert that a filter factory with no allowed_origin fails.'''
|
||||
|
Loading…
x
Reference in New Issue
Block a user