From 02ec8d03ed53660470ae7623b7c0528a6207e97d Mon Sep 17 00:00:00 2001 From: "shashi.kant" Date: Mon, 10 Oct 2016 16:21:00 +0530 Subject: [PATCH] Updated murano-apste.ini with http_proxy_to_wsgi Murano used to have a custom, always-enabled ssl middleware, to parse X-Forwarded-Proto header, to let murano work correctly behind an SSL proxy. There is now an oslo middleware, that does the same thing, but more thoroughly. This commit replaces custom implementation with oslo one. Co-Authored-By: Kirill Zaitsev Change-Id: I5444542b878434fb656e19b12d0f6e71df1ab95f --- etc/murano/murano-paste.ini | 9 +-- murano/api/middleware/ssl.py | 55 ------------------- murano/opts.py | 2 - murano/tests/unit/api/middleware/test_ssl.py | 46 ---------------- ...e_http_proxy_to_wsgi-9b22d3e60c045689.yaml | 18 ++++++ 5 files changed, 23 insertions(+), 107 deletions(-) delete mode 100644 murano/api/middleware/ssl.py delete mode 100644 murano/tests/unit/api/middleware/test_ssl.py create mode 100644 releasenotes/notes/use_http_proxy_to_wsgi-9b22d3e60c045689.yaml diff --git a/etc/murano/murano-paste.ini b/etc/murano/murano-paste.ini index ed5e67e5..af4b6486 100644 --- a/etc/murano/murano-paste.ini +++ b/etc/murano/murano-paste.ini @@ -1,5 +1,5 @@ [pipeline:murano] -pipeline = cors request_id ssl versionnegotiation faultwrap authtoken context rootapp +pipeline = cors http_proxy_to_wsgi request_id versionnegotiation faultwrap authtoken context rootapp [filter:context] paste.filter_factory = murano.api.middleware.context:ContextMiddleware.factory @@ -30,12 +30,13 @@ paste.filter_factory = murano.api.middleware.fault:FaultWrapper.factory [filter:request_id] paste.filter_factory = oslo_middleware.request_id:RequestId.factory -[filter:ssl] -paste.filter_factory = murano.api.middleware.ssl:SSLMiddleware.factory - [filter:ext_context] paste.filter_factory = murano.api.middleware.ext_context:ExternalContextMiddleware.factory [filter:cors] paste.filter_factory = oslo_middleware.cors:filter_factory oslo_config_project = murano + +[filter:http_proxy_to_wsgi] +paste.filter_factory = oslo_middleware.http_proxy_to_wsgi:HTTPProxyToWSGI.factory +oslo_config_project = murano diff --git a/murano/api/middleware/ssl.py b/murano/api/middleware/ssl.py deleted file mode 100644 index 1ad0fed3..00000000 --- a/murano/api/middleware/ssl.py +++ /dev/null @@ -1,55 +0,0 @@ -# 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 -from oslo_log import log as logging - -from murano.common import wsgi - -ssl_middleware_opts = [ - cfg.StrOpt('secure_proxy_ssl_header', - default='X-Forwarded-Proto', - help="The HTTP Header that will be used to determine which " - "the original request protocol scheme was, even if it was " - "removed by an SSL terminator proxy.") -] -cfg.CONF.register_opts(ssl_middleware_opts) -LOG = logging.getLogger(__name__) - - -class SSLMiddleware(wsgi.Middleware): - """Replaces the request wsgi.url_scheme environment - - A middleware that replaces the request wsgi.url_scheme environment - variable with the value of HTTP header configured in - secure_proxy_ssl_header if exists in the incoming request. - This is useful if the server is behind a SSL termination proxy. - """ - - @classmethod - def factory(cls, global_conf, **local_conf): - def filter(app): - return cls(app) - return filter - - def __init__(self, application): - super(SSLMiddleware, self).__init__(application) - self.secure_proxy_ssl_header = 'HTTP_{0}'.format( - cfg.CONF.secure_proxy_ssl_header.upper().replace('-', '_')) - - def process_request(self, req): - url_scheme = req.environ['wsgi.url_scheme'] - req.environ['wsgi.url_scheme'] = req.environ.get( - self.secure_proxy_ssl_header, req.environ['wsgi.url_scheme']) - if url_scheme != req.environ['wsgi.url_scheme']: - LOG.debug('Changed url_scheme from {0} to {1}'.format( - url_scheme, req.environ['wsgi.url_scheme'])) diff --git a/murano/opts.py b/murano/opts.py index edb84938..33ac8588 100644 --- a/murano/opts.py +++ b/murano/opts.py @@ -22,7 +22,6 @@ import itertools import oslo_service.sslutils -import murano.api.middleware.ssl import murano.common.cf_config import murano.common.config import murano.common.wsgi @@ -50,7 +49,6 @@ _opt_lists = [ murano.common.config.bind_opts, murano.common.config.file_server, murano.common.wsgi.wsgi_opts, - murano.api.middleware.ssl.ssl_middleware_opts ])), ] diff --git a/murano/tests/unit/api/middleware/test_ssl.py b/murano/tests/unit/api/middleware/test_ssl.py deleted file mode 100644 index 25151ab5..00000000 --- a/murano/tests/unit/api/middleware/test_ssl.py +++ /dev/null @@ -1,46 +0,0 @@ -# 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 - -from murano.api.middleware import ssl - -from murano.tests.unit import base - - -class SSLMiddlewareTest(base.MuranoTestCase): - - def test_ssl_middleware_default_forwarded_proto(self): - middleware = ssl.SSLMiddleware(None) - request = webob.Request.blank('/environments', - headers={'X-Forwarded-Proto': 'https'}) - middleware.process_request(request) - self.assertEqual('https', - request.environ['wsgi.url_scheme']) - - def test_ssl_middleware_custon_forwarded_proto(self): - self.override_config('secure_proxy_ssl_header', - 'X-My-Forwarded-Proto') - middleware = ssl.SSLMiddleware(None) - request = webob.Request.blank('/environments', - headers={ - 'X-My-Forwarded-Proto': 'https'}) - middleware.process_request(request) - self.assertEqual('https', - request.environ['wsgi.url_scheme']) - - def test_ssl_middleware_plain_request(self): - middleware = ssl.SSLMiddleware(None) - request = webob.Request.blank('/environments', headers={}) - middleware.process_request(request) - self.assertEqual('http', - request.environ['wsgi.url_scheme']) diff --git a/releasenotes/notes/use_http_proxy_to_wsgi-9b22d3e60c045689.yaml b/releasenotes/notes/use_http_proxy_to_wsgi-9b22d3e60c045689.yaml new file mode 100644 index 00000000..d78b0a17 --- /dev/null +++ b/releasenotes/notes/use_http_proxy_to_wsgi-9b22d3e60c045689.yaml @@ -0,0 +1,18 @@ +--- + +features: + - | + Murano switched to using standard oslo middleware HTTPProxyToWSGI instead + of custom implementation. This middleware parses the X-Forwarded-Proto + HTTP header or the Proxy protocol in order to help murano respond with + the correct URL refs when it's put behind a TLS proxy (such as HAProxy). + This middleware is disabled by default, but can be enabled via a + configuration option in the oslo_middleware group. +upgrade: + - | + File ``murano-paste.ini has been updated to use oslo HTTPProxyToWSGI middleware. + Config option ``secure_proxy_ssl_header`` has been removed. Please refer to + oslo_middleware configuration options if you wish deploy murano behind TLS proxy. + Most notably you would need to set ``enable_proxy_headers_parsing`` under group + ``oslo_middleware`` to True, to enable header parsing. +