]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/controllers/prometheus.py
af90f0d60088866045729debcedda8afa2239a24
[ceph.git] / ceph / src / pybind / mgr / dashboard / controllers / prometheus.py
1 # -*- coding: utf-8 -*-
2
3 import json
4 from datetime import datetime
5
6 import requests
7
8 from ..exceptions import DashboardException
9 from ..security import Scope
10 from ..settings import Settings
11 from . import APIDoc, APIRouter, BaseController, Endpoint, RESTController, Router
12
13
14 @Router('/api/prometheus_receiver', secure=False)
15 class PrometheusReceiver(BaseController):
16 """
17 The receiver is needed in order to receive alert notifications (reports)
18 """
19 notifications = []
20
21 @Endpoint('POST', path='/', version=None)
22 def fetch_alert(self, **notification):
23 notification['notified'] = datetime.now().isoformat()
24 notification['id'] = str(len(self.notifications))
25 self.notifications.append(notification)
26
27
28 class PrometheusRESTController(RESTController):
29 def prometheus_proxy(self, method, path, params=None, payload=None):
30 # type (str, str, dict, dict)
31 return self._proxy(self._get_api_url(Settings.PROMETHEUS_API_HOST),
32 method, path, 'Prometheus', params, payload,
33 verify=Settings.PROMETHEUS_API_SSL_VERIFY)
34
35 def alert_proxy(self, method, path, params=None, payload=None):
36 # type (str, str, dict, dict)
37 return self._proxy(self._get_api_url(Settings.ALERTMANAGER_API_HOST),
38 method, path, 'Alertmanager', params, payload,
39 verify=Settings.ALERTMANAGER_API_SSL_VERIFY)
40
41 def _get_api_url(self, host):
42 return host.rstrip('/') + '/api/v1'
43
44 def _proxy(self, base_url, method, path, api_name, params=None, payload=None, verify=True):
45 # type (str, str, str, str, dict, dict, bool)
46 try:
47 response = requests.request(method, base_url + path, params=params,
48 json=payload, verify=verify)
49 except Exception:
50 raise DashboardException(
51 "Could not reach {}'s API on {}".format(api_name, base_url),
52 http_status_code=404,
53 component='prometheus')
54 try:
55 content = json.loads(response.content, strict=False)
56 except json.JSONDecodeError as e:
57 raise DashboardException(
58 "Error parsing Prometheus Alertmanager response: {}".format(e.msg),
59 component='prometheus')
60 if content['status'] == 'success':
61 if 'data' in content:
62 return content['data']
63 return content
64 raise DashboardException(content, http_status_code=400, component='prometheus')
65
66
67 @APIRouter('/prometheus', Scope.PROMETHEUS)
68 @APIDoc("Prometheus Management API", "Prometheus")
69 class Prometheus(PrometheusRESTController):
70 def list(self, **params):
71 return self.alert_proxy('GET', '/alerts', params)
72
73 @RESTController.Collection(method='GET')
74 def rules(self, **params):
75 return self.prometheus_proxy('GET', '/rules', params)
76
77 @RESTController.Collection(method='GET', path='/silences')
78 def get_silences(self, **params):
79 return self.alert_proxy('GET', '/silences', params)
80
81 @RESTController.Collection(method='POST', path='/silence', status=201)
82 def create_silence(self, **params):
83 return self.alert_proxy('POST', '/silences', payload=params)
84
85 @RESTController.Collection(method='DELETE', path='/silence/{s_id}', status=204)
86 def delete_silence(self, s_id):
87 return self.alert_proxy('DELETE', '/silence/' + s_id) if s_id else None
88
89
90 @APIRouter('/prometheus/notifications', Scope.PROMETHEUS)
91 @APIDoc("Prometheus Notifications Management API", "PrometheusNotifications")
92 class PrometheusNotifications(RESTController):
93
94 def list(self, **params):
95 if 'from' in params:
96 f = params['from']
97 if f == 'last':
98 return PrometheusReceiver.notifications[-1:]
99 return PrometheusReceiver.notifications[int(f) + 1:]
100 return PrometheusReceiver.notifications