From 89c143d3aa03a16a5703123647b0a2203b0c9f5c Mon Sep 17 00:00:00 2001 From: Khachatur Ashotyan Date: Sun, 23 Aug 2020 17:27:34 +0400 Subject: [PATCH] Add ROUTE_PREFIX parameter for working with reverse proxies. (#256) * Add ROUTE_PREFIX parameter for working with reverse proxies. * [flake8/E304] remove blank line after function decoder * Add APPLICATION_ROOT and use route_prefix in requests. * [black/code-styling] use double quotes instead of single. * handle right events url depending route path * properly handle redirects * [flake8] remove unused module, fix styling issues Co-authored-by: Henning Jacobs --- README.rst | 3 ++- app/src/app.js | 3 ++- kube_ops_view/main.py | 21 +++++++++++++++++---- kube_ops_view/templates/index.html | 6 +++--- kube_ops_view/templates/screen-tokens.html | 2 +- 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/README.rst b/README.rst index 8d32e3c..55e04b4 100644 --- a/README.rst +++ b/README.rst @@ -163,7 +163,8 @@ The following environment variables are supported: Template to make Nodes clickable, e.g. can point to `kube-web-view `_. ``{cluster}`` (cluster ID) and ``{name}`` (Node name) will be replaced in the URL template. ``POD_LINK_URL_TEMPLATE`` Template to make Pods clickable, e.g. can point to `kube-web-view `_. ``{cluster}`` (cluster ID), ``{namespace}`` (Pod's namespace), and ``{name}`` (Pod name) will be replaced in the URL template. - +``ROUTE_PREFIX`` + The URL prefix under which kube-ops-view is externally reachable (for example, if kube-ops-view is served via a reverse proxy). Used for generating relative and absolute links back to kube-ops-view itself. If the URL has a path portion, it will be used to prefix all HTTP endpoints served by kube-ops-view. If omitted, relevant URL components will be derived automatically. Supported Browsers ================== diff --git a/app/src/app.js b/app/src/app.js index 48495ed..05318cb 100644 --- a/app/src/app.js +++ b/app/src/app.js @@ -20,6 +20,7 @@ export default class App { this.config = Config.fromParams(params) this.config.nodeLinkUrlTemplate = config['node_link_url_template'] this.config.podLinkUrlTemplate = config['pod_link_url_template'] + this.config.route_prefix = config['route_prefix'] this.filterString = (params.get('q') && decodeURIComponent(params.get('q'))) || '' this.selectedClusters = new Set((params.get('clusters') || '').split(',').filter(x => x)) @@ -658,7 +659,7 @@ export default class App { this.disconnect() const that = this // NOTE: path must be relative to work with kubectl proxy out of the box - let url = 'events' + let url = this.config.route_prefix + (this.config.route_prefix === '/' ? 'events' : '/events') const clusterIds = Array.from(this.selectedClusters).join(',') if (clusterIds) { url += '?cluster_ids=' + clusterIds diff --git a/kube_ops_view/main.py b/kube_ops_view/main.py index 7bc9408..1d9f654 100644 --- a/kube_ops_view/main.py +++ b/kube_ops_view/main.py @@ -19,7 +19,6 @@ from pathlib import Path from flask import Flask, redirect, url_for from .oauth import OAuth2ConsumerBlueprintWithClientRefresh -from urllib.parse import urljoin from .mock import query_mock_cluster from .kubernetes import query_kubernetes_cluster @@ -39,7 +38,6 @@ logger = logging.getLogger(__name__) SERVER_STATUS = {"shutdown": False} AUTHORIZE_URL = os.getenv("AUTHORIZE_URL") ACCESS_TOKEN_URL = os.getenv("ACCESS_TOKEN_URL") -APP_URL = os.getenv("APP_URL") or "" SCOPE = os.getenv("SCOPE") app = Flask(__name__) @@ -97,6 +95,7 @@ def index(): "index.html", app_js=app_js, version=kube_ops_view.__version__, + route_prefix=app.app_config["route_prefix"], app_config_json=json.dumps(app.app_config), ) @@ -168,13 +167,13 @@ def redeem_screen_token(token: str): except Exception: flask.abort(401) flask.session["auth_token"] = (token, "") - return redirect(urljoin(APP_URL, "/")) + return redirect(app.config["APPLICATION_ROOT"]) @app.route("/logout") def logout(): flask.session.pop("auth_token", None) - return redirect(urljoin(APP_URL, "/")) + return redirect(app.config["APPLICATION_ROOT"]) def shutdown(): @@ -228,6 +227,17 @@ class CommaSeparatedValues(click.ParamType): envvar="SERVER_PORT", default=8080, ) +@click.option( + "--route-prefix", + help="""The URL prefix under which kube-ops-view is externally reachable + (for example, if kube-ops-view is served via a reverse proxy). Used for + generating relative and absolute links back to kube-ops-view itself. If the + URL has a path portion, it will be used to prefix all HTTP endpoints served + by kube-ops-view. If omitted, relevant URL components will be derived + automatically.""", + envvar="ROUTE_PREFIX", + default="/", +) @click.option( "-d", "--debug", is_flag=True, help="Run in debugging mode", envvar="DEBUG" ) @@ -300,6 +310,7 @@ def main( query_interval, node_link_url_template: str, pod_link_url_template: str, + route_prefix: str, ): logging.basicConfig(level=logging.DEBUG if debug else logging.INFO) @@ -308,9 +319,11 @@ def main( app.debug = debug app.secret_key = secret_key app.store = store + app.config["APPLICATION_ROOT"] = route_prefix app.app_config = { "node_link_url_template": node_link_url_template, "pod_link_url_template": pod_link_url_template, + "route_prefix": route_prefix, } discoverer: Union[ diff --git a/kube_ops_view/templates/index.html b/kube_ops_view/templates/index.html index bf1d503..d4c42ed 100644 --- a/kube_ops_view/templates/index.html +++ b/kube_ops_view/templates/index.html @@ -4,7 +4,7 @@ Kubernetes Operational View {{ version }} - + @@ -22,7 +22,7 @@
Loading..
- + diff --git a/kube_ops_view/templates/screen-tokens.html b/kube_ops_view/templates/screen-tokens.html index ef3ba56..6df8461 100644 --- a/kube_ops_view/templates/screen-tokens.html +++ b/kube_ops_view/templates/screen-tokens.html @@ -4,7 +4,7 @@ Screen Tokens - +

Screen Tokens