]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Dashboard can't handle self-signed cert on Grafana API 31792/head
authorVolker Theile <vtheile@suse.com>
Thu, 24 Oct 2019 11:51:08 +0000 (13:51 +0200)
committerAlfonso Martínez <almartin@redhat.com>
Thu, 21 Nov 2019 16:30:18 +0000 (17:30 +0100)
To configure SSL certificate verification use the following command:
$ ceph dashboard set-grafana-api-ssl-verify true|false

Fixes: https://tracker.ceph.com/issues/42445
Signed-off-by: Volker Theile <vtheile@suse.com>
(cherry picked from commit e047ffd20d4c73bae5ca88303a8ca65f51d73e9d)

doc/mgr/dashboard.rst
src/pybind/mgr/dashboard/grafana.py
src/pybind/mgr/dashboard/settings.py
src/pybind/mgr/dashboard/tests/test_grafana.py

index 8ba2111d2ac18315d65926d18047a0bcf8a61b5f..26c95ca0316eec209fbb9bb750e156240848e1b4 100644 (file)
@@ -425,6 +425,12 @@ The format of url is : `<protocol>:<IP-address>:<port>`
   above, check your browser's documentation on how to unblock mixed content.
   Alternatively, consider enabling SSL/TLS support in Grafana.
 
+If you are using a self-signed certificate in your Grafana setup, then you should
+disable certificate verification in the dashboard to avoid refused connections,
+e.g. caused by certificates signed by unknown CA or not matching the host name::
+
+  $ ceph dashboard set-grafana-api-ssl-verify False
+
 You can directly access Grafana Instance as well to monitor your cluster.
 
 .. _dashboard-sso-support:
index 1399dce3c4b2348e92ca7342b5975845002de2ea..e1157553967548e0d0c075183efb26f3e15578f3 100644 (file)
@@ -17,8 +17,8 @@ class GrafanaRestClient(object):
     def url_validation(method, path):
         response = requests.request(
             method,
-            path)
-
+            path,
+            verify=Settings.GRAFANA_API_SSL_VERIFY)
         return response.status_code
 
     @staticmethod
@@ -48,6 +48,7 @@ class GrafanaRestClient(object):
                 data=json.dumps(payload),
                 auth=(Settings.GRAFANA_API_USERNAME,
                       Settings.GRAFANA_API_PASSWORD),
+                verify=Settings.GRAFANA_API_SSL_VERIFY
             )
         except requests.ConnectionError:
             raise GrafanaError("Could not connect to Grafana server")
index 8b57d1bed4c17d1bff634338a57ffd614a2912e9..bda0dda04133d29a2e31cd91eaefa02578d72e59 100644 (file)
@@ -39,6 +39,7 @@ class Options(object):
     GRAFANA_API_URL = ('', str)
     GRAFANA_API_USERNAME = ('admin', str)
     GRAFANA_API_PASSWORD = ('admin', str)
+    GRAFANA_API_SSL_VERIFY = (True, bool)
     GRAFANA_UPDATE_DASHBOARDS = (False, bool)
 
     # NFS Ganesha settings
index f880400b06c22cfe289c3a5a7754bee976562d7c..aa3f9f8cb950338a7110ffce810431365904bae0 100644 (file)
@@ -1,5 +1,15 @@
-from . import ControllerTestCase
+import json
+import unittest
+
+try:
+    from mock import patch
+except ImportError:
+    from unittest.mock import patch
+
+from . import ControllerTestCase, KVStoreMockMixin
 from ..controllers.grafana import Grafana
+from ..grafana import GrafanaRestClient
+from ..settings import Settings
 from .. import mgr
 
 
@@ -48,3 +58,57 @@ class GrafanaTest(ControllerTestCase):
         self.server_settings(password=None)
         self._post('/api/grafana/dashboards')
         self.assertStatus(500)
+
+
+class GrafanaRestClientTest(unittest.TestCase, KVStoreMockMixin):
+    headers = {
+        'Accept': 'application/json',
+        'Content-Type': 'application/json',
+    }
+    payload = json.dumps({
+        'dashboard': 'foo',
+        'overwrite': True
+    })
+
+    def setUp(self):
+        self.mock_kv_store()
+        Settings.GRAFANA_API_URL = 'https://foo/bar'
+        Settings.GRAFANA_API_USERNAME = 'xyz'
+        Settings.GRAFANA_API_PASSWORD = 'abc'
+        Settings.GRAFANA_API_SSL_VERIFY = True
+
+    def test_ssl_verify_url_validation(self):
+        with patch('requests.request') as mock_request:
+            rest_client = GrafanaRestClient()
+            rest_client.url_validation('FOO', Settings.GRAFANA_API_URL)
+            mock_request.assert_called_with('FOO', Settings.GRAFANA_API_URL,
+                                            verify=True)
+
+    def test_no_ssl_verify_url_validation(self):
+        Settings.GRAFANA_API_SSL_VERIFY = False
+        with patch('requests.request') as mock_request:
+            rest_client = GrafanaRestClient()
+            rest_client.url_validation('BAR', Settings.GRAFANA_API_URL)
+            mock_request.assert_called_with('BAR', Settings.GRAFANA_API_URL,
+                                            verify=False)
+
+    def test_ssl_verify_push_dashboard(self):
+        with patch('requests.post') as mock_request:
+            rest_client = GrafanaRestClient()
+            rest_client.push_dashboard('foo')
+            mock_request.assert_called_with(
+                Settings.GRAFANA_API_URL + '/api/dashboards/db',
+                auth=(Settings.GRAFANA_API_USERNAME,
+                      Settings.GRAFANA_API_PASSWORD),
+                data=self.payload, headers=self.headers, verify=True)
+
+    def test_no_ssl_verify_push_dashboard(self):
+        Settings.GRAFANA_API_SSL_VERIFY = False
+        with patch('requests.post') as mock_request:
+            rest_client = GrafanaRestClient()
+            rest_client.push_dashboard('foo')
+            mock_request.assert_called_with(
+                Settings.GRAFANA_API_URL + '/api/dashboards/db',
+                auth=(Settings.GRAFANA_API_USERNAME,
+                      Settings.GRAFANA_API_PASSWORD),
+                data=self.payload, headers=self.headers, verify=False)