]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/settings.py
aab54ab9489ab743108d4b17b978a1c5dfdb6e5b
[ceph.git] / ceph / src / pybind / mgr / dashboard / settings.py
1 # -*- coding: utf-8 -*-
2 from __future__ import absolute_import
3
4 import errno
5 import inspect
6 from six import add_metaclass
7
8 from . import mgr
9
10
11 class Options(object):
12 """
13 If you need to store some configuration value please add the config option
14 name as a class attribute to this class.
15
16 Example::
17
18 GRAFANA_API_HOST = ('localhost', str)
19 GRAFANA_API_PORT = (3000, int)
20 """
21 ENABLE_BROWSABLE_API = (True, bool)
22 REST_REQUESTS_TIMEOUT = (45, int)
23
24 # AUTHENTICATION ATTEMPTS
25 ACCOUNT_LOCKOUT_ATTEMPTS = (10, int)
26
27 # API auditing
28 AUDIT_API_ENABLED = (False, bool)
29 AUDIT_API_LOG_PAYLOAD = (True, bool)
30
31 # RGW settings
32 RGW_API_HOST = ('', str)
33 RGW_API_PORT = (80, int)
34 RGW_API_ACCESS_KEY = ('', str)
35 RGW_API_SECRET_KEY = ('', str)
36 RGW_API_ADMIN_RESOURCE = ('admin', str)
37 RGW_API_SCHEME = ('http', str)
38 RGW_API_USER_ID = ('', str)
39 RGW_API_SSL_VERIFY = (True, bool)
40
41 # Grafana settings
42 GRAFANA_API_URL = ('', str)
43 GRAFANA_FRONTEND_API_URL = ('', str)
44 GRAFANA_API_USERNAME = ('admin', str)
45 GRAFANA_API_PASSWORD = ('admin', str)
46 GRAFANA_API_SSL_VERIFY = (True, bool)
47 GRAFANA_UPDATE_DASHBOARDS = (False, bool)
48
49 # NFS Ganesha settings
50 GANESHA_CLUSTERS_RADOS_POOL_NAMESPACE = ('', str)
51
52 # Prometheus settings
53 PROMETHEUS_API_HOST = ('', str)
54 ALERTMANAGER_API_HOST = ('', str)
55
56 # iSCSI management settings
57 ISCSI_API_SSL_VERIFICATION = (True, bool)
58
59 # user management settings
60 # Time span of user passwords to expire in days.
61 # The default value is '0' which means that user passwords are
62 # never going to expire.
63 USER_PWD_EXPIRATION_SPAN = (0, int)
64 # warning levels to notify the user that the password is going
65 # to expire soon
66 USER_PWD_EXPIRATION_WARNING_1 = (10, int)
67 USER_PWD_EXPIRATION_WARNING_2 = (5, int)
68
69 # Password policy
70 PWD_POLICY_ENABLED = (True, bool)
71 # Individual checks
72 PWD_POLICY_CHECK_LENGTH_ENABLED = (True, bool)
73 PWD_POLICY_CHECK_OLDPWD_ENABLED = (True, bool)
74 PWD_POLICY_CHECK_USERNAME_ENABLED = (False, bool)
75 PWD_POLICY_CHECK_EXCLUSION_LIST_ENABLED = (False, bool)
76 PWD_POLICY_CHECK_COMPLEXITY_ENABLED = (False, bool)
77 PWD_POLICY_CHECK_SEQUENTIAL_CHARS_ENABLED = (False, bool)
78 PWD_POLICY_CHECK_REPETITIVE_CHARS_ENABLED = (False, bool)
79 # Settings
80 PWD_POLICY_MIN_LENGTH = (8, int)
81 PWD_POLICY_MIN_COMPLEXITY = (10, int)
82 PWD_POLICY_EXCLUSION_LIST = (','.join(['osd', 'host',
83 'dashboard', 'pool',
84 'block', 'nfs',
85 'ceph', 'monitors',
86 'gateway', 'logs',
87 'crush', 'maps']),
88 str)
89
90 @staticmethod
91 def has_default_value(name):
92 return getattr(Settings, name, None) is None or \
93 getattr(Settings, name) == getattr(Options, name)[0]
94
95
96 class SettingsMeta(type):
97 def __getattr__(cls, attr):
98 default, stype = getattr(Options, attr)
99 if stype == bool and str(mgr.get_module_option(
100 attr,
101 default)).lower() == 'false':
102 value = False
103 else:
104 value = stype(mgr.get_module_option(attr, default))
105 return value
106
107 def __setattr__(cls, attr, value):
108 if not attr.startswith('_') and hasattr(Options, attr):
109 mgr.set_module_option(attr, str(value))
110 else:
111 setattr(SettingsMeta, attr, value)
112
113 def __delattr__(cls, attr):
114 if not attr.startswith('_') and hasattr(Options, attr):
115 mgr.set_module_option(attr, None)
116
117
118 # pylint: disable=no-init
119 @add_metaclass(SettingsMeta)
120 class Settings(object):
121 pass
122
123
124 def _options_command_map():
125 def filter_attr(member):
126 return not inspect.isroutine(member)
127
128 cmd_map = {}
129 for option, value in inspect.getmembers(Options, filter_attr):
130 if option.startswith('_'):
131 continue
132 key_get = 'dashboard get-{}'.format(option.lower().replace('_', '-'))
133 key_set = 'dashboard set-{}'.format(option.lower().replace('_', '-'))
134 key_reset = 'dashboard reset-{}'.format(option.lower().replace('_', '-'))
135 cmd_map[key_get] = {'name': option, 'type': None}
136 cmd_map[key_set] = {'name': option, 'type': value[1]}
137 cmd_map[key_reset] = {'name': option, 'type': None}
138 return cmd_map
139
140
141 _OPTIONS_COMMAND_MAP = _options_command_map()
142
143
144 def options_command_list():
145 """
146 This function generates a list of ``get`` and ``set`` commands
147 for each declared configuration option in class ``Options``.
148 """
149 def py2ceph(pytype):
150 if pytype == str:
151 return 'CephString'
152 elif pytype == int:
153 return 'CephInt'
154 return 'CephString'
155
156 cmd_list = []
157 for cmd, opt in _OPTIONS_COMMAND_MAP.items():
158 if cmd.startswith('dashboard get'):
159 cmd_list.append({
160 'cmd': '{}'.format(cmd),
161 'desc': 'Get the {} option value'.format(opt['name']),
162 'perm': 'r'
163 })
164 elif cmd.startswith('dashboard set'):
165 cmd_list.append({
166 'cmd': '{} name=value,type={}'
167 .format(cmd, py2ceph(opt['type'])),
168 'desc': 'Set the {} option value'.format(opt['name']),
169 'perm': 'w'
170 })
171 elif cmd.startswith('dashboard reset'):
172 desc = 'Reset the {} option to its default value'.format(
173 opt['name'])
174 cmd_list.append({
175 'cmd': '{}'.format(cmd),
176 'desc': desc,
177 'perm': 'w'
178 })
179
180 return cmd_list
181
182
183 def options_schema_list():
184 def filter_attr(member):
185 return not inspect.isroutine(member)
186
187 result = []
188 for option, value in inspect.getmembers(Options, filter_attr):
189 if option.startswith('_'):
190 continue
191 result.append({'name': option, 'default': value[0],
192 'type': value[1].__name__})
193
194 return result
195
196
197 def handle_option_command(cmd):
198 if cmd['prefix'] not in _OPTIONS_COMMAND_MAP:
199 return -errno.ENOSYS, '', "Command not found '{}'".format(cmd['prefix'])
200
201 opt = _OPTIONS_COMMAND_MAP[cmd['prefix']]
202
203 if cmd['prefix'].startswith('dashboard reset'):
204 delattr(Settings, opt['name'])
205 return 0, 'Option {} reset to default value "{}"'.format(
206 opt['name'], getattr(Settings, opt['name'])), ''
207 elif cmd['prefix'].startswith('dashboard get'):
208 return 0, str(getattr(Settings, opt['name'])), ''
209 elif cmd['prefix'].startswith('dashboard set'):
210 value = opt['type'](cmd['value'])
211 if opt['type'] == bool and cmd['value'].lower() == 'false':
212 value = False
213 setattr(Settings, opt['name'], value)
214 return 0, 'Option {} updated'.format(opt['name']), ''