]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/controllers/summary.py
import ceph quincy 17.2.6
[ceph.git] / ceph / src / pybind / mgr / dashboard / controllers / summary.py
1 # -*- coding: utf-8 -*-
2
3 import json
4
5 from .. import mgr
6 from ..controllers.rbd_mirroring import get_daemons_and_pools
7 from ..exceptions import ViewCacheNoDataException
8 from ..security import Permission, Scope
9 from ..services import progress
10 from ..tools import TaskManager
11 from . import APIDoc, APIRouter, BaseController, Endpoint, EndpointDoc
12
13 SUMMARY_SCHEMA = {
14 "health_status": (str, ""),
15 "mgr_id": (str, ""),
16 "mgr_host": (str, ""),
17 "have_mon_connection": (str, ""),
18 "executing_tasks": ([str], ""),
19 "finished_tasks": ([{
20 "name": (str, ""),
21 "metadata": ({
22 "pool": (int, ""),
23 }, ""),
24 "begin_time": (str, ""),
25 "end_time": (str, ""),
26 "duration": (int, ""),
27 "progress": (int, ""),
28 "success": (bool, ""),
29 "ret_value": (str, ""),
30 "exception": (str, ""),
31 }], ""),
32 "version": (str, ""),
33 "rbd_mirroring": ({
34 "warnings": (int, ""),
35 "errors": (int, "")
36 }, "")
37 }
38
39
40 @APIRouter('/summary')
41 @APIDoc("Get Ceph Summary Details", "Summary")
42 class Summary(BaseController):
43 def _health_status(self):
44 health_data = mgr.get("health")
45 return json.loads(health_data["json"])['status']
46
47 def _rbd_mirroring(self):
48 try:
49 _, data = get_daemons_and_pools()
50 except ViewCacheNoDataException: # pragma: no cover
51 return {} # pragma: no cover
52
53 daemons = data.get('daemons', [])
54 pools = data.get('pools', {})
55
56 warnings = 0
57 errors = 0
58 for daemon in daemons:
59 if daemon['health_color'] == 'error': # pragma: no cover
60 errors += 1
61 elif daemon['health_color'] == 'warning': # pragma: no cover
62 warnings += 1
63 for _, pool in pools.items():
64 if pool['health_color'] == 'error': # pragma: no cover
65 errors += 1
66 elif pool['health_color'] == 'warning': # pragma: no cover
67 warnings += 1
68 return {'warnings': warnings, 'errors': errors}
69
70 def _task_permissions(self, name): # pragma: no cover
71 result = True
72 if name == 'pool/create':
73 result = self._has_permissions(Permission.CREATE, Scope.POOL)
74 elif name == 'pool/edit':
75 result = self._has_permissions(Permission.UPDATE, Scope.POOL)
76 elif name == 'pool/delete':
77 result = self._has_permissions(Permission.DELETE, Scope.POOL)
78 elif name in [
79 'rbd/create', 'rbd/copy', 'rbd/snap/create',
80 'rbd/clone', 'rbd/trash/restore']:
81 result = self._has_permissions(Permission.CREATE, Scope.RBD_IMAGE)
82 elif name in [
83 'rbd/edit', 'rbd/snap/edit', 'rbd/flatten',
84 'rbd/snap/rollback']:
85 result = self._has_permissions(Permission.UPDATE, Scope.RBD_IMAGE)
86 elif name in [
87 'rbd/delete', 'rbd/snap/delete', 'rbd/trash/move',
88 'rbd/trash/remove', 'rbd/trash/purge']:
89 result = self._has_permissions(Permission.DELETE, Scope.RBD_IMAGE)
90 return result
91
92 def _get_host(self):
93 # type: () -> str
94 services = mgr.get('mgr_map')['services']
95 return services['dashboard'] if 'dashboard' in services else ''
96
97 @Endpoint()
98 @EndpointDoc("Display Summary",
99 responses={200: SUMMARY_SCHEMA})
100 def __call__(self):
101 exe_t, fin_t = TaskManager.list_serializable()
102 executing_tasks = [task for task in exe_t if self._task_permissions(task['name'])]
103 finished_tasks = [task for task in fin_t if self._task_permissions(task['name'])]
104
105 e, f = progress.get_progress_tasks()
106 executing_tasks.extend(e)
107 finished_tasks.extend(f)
108
109 executing_tasks.sort(key=lambda t: t['begin_time'], reverse=True)
110 finished_tasks.sort(key=lambda t: t['end_time'], reverse=True)
111
112 result = {
113 'health_status': self._health_status(),
114 'mgr_id': mgr.get_mgr_id(),
115 'mgr_host': self._get_host(),
116 'have_mon_connection': mgr.have_mon_connection(),
117 'executing_tasks': executing_tasks,
118 'finished_tasks': finished_tasks,
119 'version': mgr.version
120 }
121 if self._has_permissions(Permission.READ, Scope.RBD_MIRRORING):
122 result['rbd_mirroring'] = self._rbd_mirroring()
123 return result