]> git.proxmox.com Git - ceph.git/blame - ceph/src/pybind/mgr/dashboard/grafana.py
buildsys: switch source download to quincy
[ceph.git] / ceph / src / pybind / mgr / dashboard / grafana.py
CommitLineData
81eedcae
TL
1# -*- coding: utf-8 -*-
2from __future__ import absolute_import
3
4import json
9f95a23c 5import logging
81eedcae
TL
6import os
7import time
f67539c2 8
81eedcae
TL
9import requests
10
81eedcae
TL
11from .exceptions import GrafanaError
12from .settings import Settings
13
9f95a23c
TL
14logger = logging.getLogger('grafana')
15
16
81eedcae
TL
17class GrafanaRestClient(object):
18
19 @staticmethod
20 def url_validation(method, path):
21 response = requests.request(
22 method,
92f5a8d4
TL
23 path,
24 verify=Settings.GRAFANA_API_SSL_VERIFY)
81eedcae
TL
25 return response.status_code
26
27 @staticmethod
28 def push_dashboard(dashboard_obj):
29 if not Settings.GRAFANA_API_URL:
30 raise GrafanaError("The Grafana API URL is not set")
31 if not Settings.GRAFANA_API_URL.startswith('http'):
32 raise GrafanaError("The Grafana API URL is invalid")
33 if not Settings.GRAFANA_API_USERNAME:
34 raise GrafanaError("The Grafana API username is not set")
35 if not Settings.GRAFANA_API_PASSWORD:
36 raise GrafanaError("The Grafana API password is not set")
37 url = Settings.GRAFANA_API_URL.rstrip('/') + \
38 '/api/dashboards/db'
39 headers = {
40 'Accept': 'application/json',
41 'Content-Type': 'application/json',
42 }
43 payload = {
44 'dashboard': dashboard_obj,
45 'overwrite': True,
46 }
47 try:
48 response = requests.post(
49 url,
50 headers=headers,
51 data=json.dumps(payload),
52 auth=(Settings.GRAFANA_API_USERNAME,
53 Settings.GRAFANA_API_PASSWORD),
92f5a8d4 54 verify=Settings.GRAFANA_API_SSL_VERIFY
81eedcae
TL
55 )
56 except requests.ConnectionError:
57 raise GrafanaError("Could not connect to Grafana server")
58 response.raise_for_status()
59 return response.status_code, response.json()
60
61
62class Retrier(object):
63 def __init__(self, tries, sleep, func, *args, **kwargs):
64 """
65 Wraps a function. An instance of this class may be called to call that
66 function, retrying if it raises an exception. Sleeps between retries,
67 eventually reraising the original exception when retries are exhausted.
68 Once the function returns a value, that value is returned.
69
70 :param tries: How many times to try, before reraising the exception
71 :type tries: int
72 :param sleep: How many seconds to wait between tries
73 :type sleep: int|float
74 :param func: The function to execute
75 :type func: function
76 :param args: Any arguments to pass to the function
77 :type args: list
78 :param kwargs: Any keyword arguments to pass to the function
79 :type kwargs: dict
80 """
81 assert tries >= 1
82 self.tries = int(tries)
83 self.tried = 0
84 self.sleep = sleep
85 self.func = func
86 self.args = args
87 self.kwargs = kwargs
88
89 def __call__(self):
90 result = None
91 while self.tried < self.tries:
92 try:
93 result = self.func(*self.args, **self.kwargs)
94 except Exception: # pylint: disable=broad-except
95 if self.tried == self.tries - 1:
96 raise
97 else:
98 self.tried += 1
99 time.sleep(self.sleep)
100 else:
101 return result
102
103
104def load_local_dashboards():
105 if os.environ.get('CEPH_DEV') == '1' or 'UNITTEST' in os.environ:
106 path = os.path.abspath(os.path.join(
107 os.path.dirname(__file__),
108 '../../../../monitoring/grafana/dashboards/'
109 ))
110 else:
111 path = '/etc/grafana/dashboards/ceph-dashboard'
112 dashboards = dict()
113 for item in [p for p in os.listdir(path) if p.endswith('.json')]:
114 db_path = os.path.join(path, item)
115 with open(db_path) as f:
116 dashboards[item] = json.loads(f.read())
117 return dashboards
118
119
120def push_local_dashboards(tries=1, sleep=0):
121 try:
122 dashboards = load_local_dashboards()
123 except (EnvironmentError, ValueError):
124 logger.exception("Failed to load local dashboard files")
125 raise
126
127 def push():
128 try:
129 grafana = GrafanaRestClient()
130 for body in dashboards.values():
131 grafana.push_dashboard(body)
132 except Exception:
133 logger.exception("Failed to push dashboards to Grafana")
134 raise
135 retry = Retrier(tries, sleep, push)
136 retry()
137 return True