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