]>
Commit | Line | Data |
---|---|---|
11fdf7f2 | 1 | # -*- coding: utf-8 -*- |
11fdf7f2 TL |
2 | |
3 | import cherrypy | |
4 | ||
11fdf7f2 | 5 | from .. import mgr |
f67539c2 | 6 | from ..exceptions import DashboardException |
11fdf7f2 TL |
7 | from ..security import Scope |
8 | from ..services.ceph_service import CephService | |
a4b75251 | 9 | from . import APIDoc, APIRouter, EndpointDoc, RESTController |
f67539c2 TL |
10 | |
11 | FILTER_SCHEMA = [{ | |
12 | "name": (str, 'Name of the config option'), | |
13 | "type": (str, 'Config option type'), | |
14 | "level": (str, 'Config option level'), | |
15 | "desc": (str, 'Description of the configuration'), | |
16 | "long_desc": (str, 'Elaborated description'), | |
17 | "default": (str, 'Default value for the config option'), | |
18 | "daemon_default": (str, 'Daemon specific default value'), | |
19 | "tags": ([str], 'Tags associated with the cluster'), | |
20 | "services": ([str], 'Services associated with the config option'), | |
21 | "see_also": ([str], 'Related config options'), | |
22 | "enum_values": ([str], 'List of enums allowed'), | |
23 | "min": (str, 'Minimum value'), | |
24 | "max": (str, 'Maximum value'), | |
25 | "can_update_at_runtime": (bool, 'Check if can update at runtime'), | |
26 | "flags": ([str], 'List of flags associated') | |
27 | }] | |
11fdf7f2 TL |
28 | |
29 | ||
a4b75251 TL |
30 | @APIRouter('/cluster_conf', Scope.CONFIG_OPT) |
31 | @APIDoc("Manage Cluster Configurations", "ClusterConfiguration") | |
11fdf7f2 TL |
32 | class ClusterConfiguration(RESTController): |
33 | ||
34 | def _append_config_option_values(self, options): | |
35 | """ | |
36 | Appends values from the config database (if available) to the given options | |
37 | :param options: list of config options | |
38 | :return: list of config options extended by their current values | |
39 | """ | |
40 | config_dump = CephService.send_command('mon', 'config dump') | |
cd265ab1 TL |
41 | mgr_config = mgr.get('config') |
42 | config_dump.append({'name': 'fsid', 'section': 'mgr', 'value': mgr_config['fsid']}) | |
43 | ||
11fdf7f2 TL |
44 | for config_dump_entry in config_dump: |
45 | for i, elem in enumerate(options): | |
46 | if config_dump_entry['name'] == elem['name']: | |
47 | if 'value' not in elem: | |
48 | options[i]['value'] = [] | |
49 | options[i]['source'] = 'mon' | |
50 | ||
51 | options[i]['value'].append({'section': config_dump_entry['section'], | |
52 | 'value': config_dump_entry['value']}) | |
53 | return options | |
54 | ||
55 | def list(self): | |
56 | options = mgr.get('config_options')['options'] | |
57 | return self._append_config_option_values(options) | |
58 | ||
59 | def get(self, name): | |
60 | return self._get_config_option(name) | |
61 | ||
81eedcae | 62 | @RESTController.Collection('GET', query_params=['name']) |
f67539c2 TL |
63 | @EndpointDoc("Get Cluster Configuration by name", |
64 | parameters={ | |
65 | 'names': (str, 'Config option names'), | |
66 | }, | |
67 | responses={200: FILTER_SCHEMA}) | |
81eedcae TL |
68 | def filter(self, names=None): |
69 | config_options = [] | |
70 | ||
71 | if names: | |
72 | for name in names.split(','): | |
73 | try: | |
74 | config_options.append(self._get_config_option(name)) | |
75 | except cherrypy.HTTPError: | |
76 | pass | |
77 | ||
78 | if not config_options: | |
79 | raise cherrypy.HTTPError(404, 'Config options `{}` not found'.format(names)) | |
80 | ||
81 | return config_options | |
82 | ||
11fdf7f2 TL |
83 | def create(self, name, value): |
84 | # Check if config option is updateable at runtime | |
85 | self._updateable_at_runtime([name]) | |
86 | ||
87 | # Update config option | |
9f95a23c | 88 | avail_sections = ['global', 'mon', 'mgr', 'osd', 'mds', 'client'] |
11fdf7f2 | 89 | |
9f95a23c | 90 | for section in avail_sections: |
11fdf7f2 | 91 | for entry in value: |
92f5a8d4 | 92 | if entry['value'] is None: |
11fdf7f2 TL |
93 | break |
94 | ||
95 | if entry['section'] == section: | |
96 | CephService.send_command('mon', 'config set', who=section, name=name, | |
97 | value=str(entry['value'])) | |
98 | break | |
99 | else: | |
100 | CephService.send_command('mon', 'config rm', who=section, name=name) | |
101 | ||
81eedcae TL |
102 | def delete(self, name, section): |
103 | return CephService.send_command('mon', 'config rm', who=section, name=name) | |
104 | ||
11fdf7f2 TL |
105 | def bulk_set(self, options): |
106 | self._updateable_at_runtime(options.keys()) | |
107 | ||
108 | for name, value in options.items(): | |
109 | CephService.send_command('mon', 'config set', who=value['section'], | |
110 | name=name, value=str(value['value'])) | |
111 | ||
112 | def _get_config_option(self, name): | |
113 | for option in mgr.get('config_options')['options']: | |
114 | if option['name'] == name: | |
115 | return self._append_config_option_values([option])[0] | |
116 | ||
117 | raise cherrypy.HTTPError(404) | |
118 | ||
119 | def _updateable_at_runtime(self, config_option_names): | |
120 | not_updateable = [] | |
121 | ||
122 | for name in config_option_names: | |
123 | config_option = self._get_config_option(name) | |
124 | if not config_option['can_update_at_runtime']: | |
125 | not_updateable.append(name) | |
126 | ||
127 | if not_updateable: | |
128 | raise DashboardException( | |
129 | msg='Config option {} is/are not updatable at runtime'.format( | |
130 | ', '.join(not_updateable)), | |
131 | code='config_option_not_updatable_at_runtime', | |
132 | component='cluster_configuration') |