Add possibility to configure application root

SCRIPT_NAME should be used to correctly construct the returned links.
This patch also adds ProxyFix from werkzeug to allow using inspector
behind SSL terminating proxy while still keeping the links correct.

Change-Id: I4f40e9266a55d237f7aa68324b11f59b667cc940
This commit is contained in:
Vladyslav Drok 2020-10-07 13:45:50 +02:00
parent d77ce5cabd
commit 6728160ae2
3 changed files with 39 additions and 3 deletions

View File

@ -19,6 +19,7 @@ import re
import flask
from oslo_utils import strutils
from oslo_utils import uuidutils
from werkzeug.middleware import proxy_fix
from ironic_inspector import api_tools
from ironic_inspector.common import context
@ -54,8 +55,14 @@ def _init_middleware():
:returns: None
"""
# ensure original root app is restored before wrapping it
_app.wsgi_app = _wsgi_app
# Ensure original root app is restored and wrap it with ProxyFix,
# respecting only the last entry in each header if it contains a list of
# values. The following headers are respected: X-Forwarded-For,
# X-Forwarded-Proto, X-Forwarded-Host, X-Forwarded-Port,
# X-Forwarded-Prefix (the last one sets SCRIPT_NAME environment variable
# that is used to construct links).
_app.wsgi_app = proxy_fix.ProxyFix(
_wsgi_app, x_for=1, x_proto=1, x_host=1, x_port=1, x_prefix=1)
if CONF.auth_strategy == 'keystone':
utils.add_auth_middleware(_app)
elif CONF.auth_strategy == 'http_basic':
@ -206,7 +213,10 @@ def create_link_object(urls):
for url in urls:
links.append({
"rel": "self",
"href": os.path.join(flask.request.url_root, url).rstrip('/')})
"href": os.path.join(
os.path.join(flask.request.url_root,
os.environ.get('SCRIPT_NAME', '/').lstrip('/')),
url).rstrip('/')})
return links

View File

@ -65,6 +65,20 @@ class BaseAPITest(test_base.BaseTest):
class TestApiIntrospect(BaseAPITest):
def test_root_endpoint_with_prefix(self):
res = self.app.get(
'/', headers={'X-Forwarded-Proto': 'https',
'X-Forwarded-Host': 'myhost',
'X-Forwarded-Prefix': '/ironic_inspector'})
self.assertEqual(200, res.status_code)
self.assertEqual('application/json',
res.headers['content-type'])
cur_version = res.json['versions'][0]
hrefs = [link['href'] for link in cur_version['links']]
for href in hrefs:
self.assertTrue(href.startswith('https://myhost/ironic_inspector'))
def test_introspect(self):
res = self.app.post('/v1/introspection/%s' % self.uuid,

View File

@ -0,0 +1,12 @@
---
features:
- |
Adds a possibility to setup ironic inspector behind a proxy, while
allowing the links of the resources API returns to remain correct.
Inspector now respects the following headers that are passed with
API requests: ``X-Forwarded-For``, ``X-Forwarded-Proto``,
``X-Forwarded-Host``, ``X-Forwarded-Port``, ``X-Forwarded-Prefix``.
If the API is run providing ``SCRIPT_NAME`` environment variable,
it is now also respected, and it allows to return the correct links
in response to requests, even if inspector API is not placed at the
web server root resource.