From be5be4d7db8098f48a40a1e479b7782c44752b0c Mon Sep 17 00:00:00 2001 From: Patrick Seidensal Date: Tue, 3 Nov 2020 13:47:23 +0100 Subject: [PATCH] mgr/dashboard: enable different URL for users of browser to Grafana Fixes: https://tracker.ceph.com/issues/47386 Signed-off-by: Patrick Seidensal (cherry picked from commit 676f82923d875cfe9528a401963c09f29a6de7f4) Conflicts: doc/mgr/dashboard.rst src/pybind/mgr/dashboard/controllers/grafana.py Resolved some trivial conflicts and replaced the heading of the newly added section in the documentation to another level, as the documentation between master and octopus differs quite much. (cherry picked from commit 56f304d31b154d87362620f08046720a3e0f3203) Conflicts: Removed cephadm documentation from cherry-picked commit as cephadm is not part of Ceph Nautilus. Removed paragraph that mentioned cephadm in dashboard documentation. --- doc/mgr/dashboard.rst | 32 ++++++++++++++++++- .../mgr/dashboard/controllers/grafana.py | 13 ++++++-- src/pybind/mgr/dashboard/settings.py | 1 + 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/doc/mgr/dashboard.rst b/doc/mgr/dashboard.rst index 5d14be6c91cf..f92bd19d5a4f 100644 --- a/doc/mgr/dashboard.rst +++ b/doc/mgr/dashboard.rst @@ -439,7 +439,8 @@ More details can be found in the documentation of the :ref:`mgr-prometheus`. After you have set up Grafana and Prometheus, you will need to configure the connection information that the Ceph Dashboard will use to access Grafana. -You need to tell the dashboard on which url Grafana instance is running/deployed:: +You need to tell the dashboard on which URL the Grafana instance is +running/deployed:: $ ceph dashboard set-grafana-api-url # default: '' @@ -462,6 +463,35 @@ e.g. caused by certificates signed by unknown CA or not matching the host name:: You can directly access Grafana Instance as well to monitor your cluster. +Alternative URL for Browsers +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The Ceph Dashboard backend requires the Grafana URL to be able to verify the +existence of Grafana Dashboards before the frontend even loads them. Due to the +nature of how Grafana is implemented in Ceph Dashboard, this means that two +working connections are required in order to be able to see Grafana graphs in +Ceph Dashboard: + +- The backend (Ceph Mgr module) needs to verify the existence of the requested + graph. If this request succeeds, it lets the frontend know that it can safely + access Grafana. +- The frontend then requests the Grafana graphs directly from the user's + browser using an iframe. The Grafana instance is accessed directly without any + detour through Ceph Dashboard. + +Now, it might be the case that your environment makes it difficult for the +user's browser to directly access the URL configured in Ceph Dashboard. To solve +this issue, a separate URL can be configured which will solely be used to tell +the frontend (the user's browser) which URL it should use to access Grafana. + +To change the URL that is returned to the frontend issue the following command:: + + $ ceph dashboard set-grafana-frontend-api-url + +If no value is set for that option, it will simply fall back to the value of the +GRAFANA_API_URL option. If set, it will instruct the browser to use this URL to +access Grafana. + .. _dashboard-sso-support: Enabling Single Sign-On (SSO) diff --git a/src/pybind/mgr/dashboard/controllers/grafana.py b/src/pybind/mgr/dashboard/controllers/grafana.py index 0d4331ff2463..001367c7c291 100644 --- a/src/pybind/mgr/dashboard/controllers/grafana.py +++ b/src/pybind/mgr/dashboard/controllers/grafana.py @@ -3,6 +3,7 @@ from __future__ import absolute_import from . import (ApiController, BaseController, Endpoint, ReadPermission, UpdatePermission) +from .. import mgr from ..exceptions import DashboardException from ..grafana import GrafanaRestClient, push_local_dashboards from ..security import Scope @@ -11,11 +12,17 @@ from ..settings import Settings @ApiController('/grafana', Scope.GRAFANA) class Grafana(BaseController): - @Endpoint() @ReadPermission def url(self): - response = {'instance': Settings.GRAFANA_API_URL} + grafana_url = mgr.get_module_option('GRAFANA_API_URL') + grafana_frontend_url = mgr.get_module_option('GRAFANA_FRONTEND_API_URL') + if grafana_frontend_url != '' and grafana_url == '': + url = '' + else: + url = (mgr.get_module_option('GRAFANA_FRONTEND_API_URL') + or mgr.get_module_option('GRAFANA_API_URL')).rstrip('/') + response = {'instance': url} return response @Endpoint() @@ -23,7 +30,7 @@ class Grafana(BaseController): def validation(self, params): grafana = GrafanaRestClient() method = 'GET' - url = Settings.GRAFANA_API_URL.rstrip('/') + \ + url = str(Settings.GRAFANA_API_URL).rstrip('/') + \ '/api/dashboards/uid/' + params response = grafana.url_validation(method, url) return response diff --git a/src/pybind/mgr/dashboard/settings.py b/src/pybind/mgr/dashboard/settings.py index d9936b5008d4..95b1cdf4194d 100644 --- a/src/pybind/mgr/dashboard/settings.py +++ b/src/pybind/mgr/dashboard/settings.py @@ -39,6 +39,7 @@ class Options(object): # Grafana settings GRAFANA_API_URL = ('', str) + GRAFANA_FRONTEND_API_URL = ('', str) GRAFANA_API_USERNAME = ('admin', str) GRAFANA_API_PASSWORD = ('admin', str) GRAFANA_API_SSL_VERIFY = (True, bool) -- 2.47.3