---------------------
Modules can load and store configuration options using the
-``set_config`` and ``get_config`` methods.
+``set_module_option`` and ``get_module_option`` methods.
-.. note:: Use ``set_config`` and ``get_config`` to manage user-visible
- configuration options that are not blobs (like certificates). If you want to
- persist module-internal data or binary configuration data consider using
- the `KV store`_.
+.. note:: Use ``set_module_option`` and ``get_module_option`` to
+ manage user-visible configuration options that are not blobs (like
+ certificates). If you want to persist module-internal data or
+ binary configuration data consider using the `KV store`_.
You must declare your available configuration options in the
-``OPTIONS`` class attribute, like this:
+``MODULE_OPTIONS`` class attribute, like this:
::
- OPTIONS = [
+ MODULE_OPTIONS = [
{
"name": "my_option"
}
]
-If you try to use set_config or get_config on options not declared
-in ``OPTIONS``, an exception will be raised.
+If you try to use set_module_option or get_module_option on options not declared
+in ``MODULE_OPTIONS``, an exception will be raised.
You may choose to provide setter commands in your module to perform
high level validation. Users can also modify configuration using
the normal `ceph config set` command, where the configuration options
for a mgr module are named like `mgr/<module name>/<option>`.
-If a configuration option is different depending on which node
-the mgr is running on, then use *localized* configuration (
-``get_localized_config``, ``set_localized_config``). This may be necessary
-for options such as what address to listen on. Localized options may
-also be set externally with ``ceph config set``, where they key name
-is like ``mgr/<module name>/<mgr id>/<option>``
+If a configuration option is different depending on which node the mgr
+is running on, then use *localized* configuration (
+``get_localized_module_option``, ``set_localized_module_option``).
+This may be necessary for options such as what address to listen on.
+Localized options may also be set externally with ``ceph config set``,
+where they key name is like ``mgr/<module name>/<mgr id>/<option>``
If you need to load and store data (e.g. something larger, binary, or multiline),
use the KV store instead of configuration options (see next section).
Hints for using config options:
* Reads are fast: ceph-mgr keeps a local in-memory copy, so in many cases
- you can just do a get_config every time you use a option, rather than
+ you can just do a get_module_option every time you use a option, rather than
copying it out into a variable.
* Writes block until the value is persisted (i.e. round trip to the monitor),
but reads from another thread will see the new value immediately.
* If a user has used `config set` from the command line, then the new
- value will become visible to `get_config` immediately, although the
+ value will become visible to `get_module_option` immediately, although the
mon->mgr update is asynchronous, so `config set` will return a fraction
of a second before the new value is visible on the mgr.
* To delete a config value (i.e. revert to default), just pass ``None`` to
- set_config.
+ set_module_option.
-.. automethod:: MgrModule.get_config
-.. automethod:: MgrModule.set_config
-.. automethod:: MgrModule.get_localized_config
-.. automethod:: MgrModule.set_localized_config
+.. automethod:: MgrModule.get_module_option
+.. automethod:: MgrModule.set_module_option
+.. automethod:: MgrModule.get_localized_module_option
+.. automethod:: MgrModule.set_localized_module_option
KV store
--------
-----------
It is not possible to call back into C++ code from a module's
-``__init__()`` method. For example calling ``self.get_config()`` at
+``__init__()`` method. For example calling ``self.get_module_option()`` at
this point will result in an assertion failure in ceph-mgr. For modules
that implement the ``serve()`` method, it usually makes sense to do most
initialization inside that method instead.
def optimize(self, plan):
self.log.info('Optimize plan %s' % plan.name)
plan.mode = self.get_module_option('mode', default_mode)
- max_misplaced = float(self.get_option('target_max_misplaced_ratio'))
+ max_misplaced = float(self.get_ceph_option('target_max_misplaced_ratio'))
self.log.info('Mode %s, max misplaced %f' %
(plan.mode, max_misplaced))
step = float(self.get_module_option('crush_compat_step', .5))
if step <= 0 or step >= 1.0:
return -errno.EINVAL, '"crush_compat_step" must be in (0, 1)'
- max_misplaced = float(self.get_option('target_max_misplaced_ratio'))
+ max_misplaced = float(self.get_ceph_option('target_max_misplaced_ratio'))
min_pg_per_osd = 2
ms = plan.initial
cherrypy.config.update(config)
self._url_prefix = prepare_url_prefix(self.get_module_option('url_prefix',
- default=''))
+ default=''))
uri = "{0}://{1}:{2}{3}/".format(
'https' if ssl else 'http',
class SettingsMeta(type):
def __getattr__(cls, attr):
default, stype = getattr(Options, attr)
- if stype == bool and str(mgr.get_module_option(attr,
- default)).lower() == 'false':
+ if stype == bool and str(mgr.get_module_option(
+ attr,
+ default)).lower() == 'false':
value = False
else:
value = stype(mgr.get_module_option(attr, default))
CONFIG_KEY_DICT = {}
@classmethod
- def mock_set_config(cls, attr, val):
+ def mock_set_module_option(cls, attr, val):
cls.CONFIG_KEY_DICT[attr] = val
@classmethod
- def mock_get_config(cls, attr, default=None):
+ def mock_get_module_option(cls, attr, default=None):
return cls.CONFIG_KEY_DICT.get(attr, default)
@classmethod
def setUpClass(cls):
- mgr.set_config.side_effect = cls.mock_set_config
- mgr.get_config.side_effect = cls.mock_get_config
- mgr.set_store.side_effect = cls.mock_set_config
- mgr.get_store.side_effect = cls.mock_get_config
+ mgr.set_module_option.side_effect = cls.mock_set_module_option
+ mgr.get_module_option.side_effect = cls.mock_get_module_option
+ # kludge below
+ mgr.set_store.side_effect = cls.mock_set_module_option
+ mgr.get_store.side_effect = cls.mock_get_module_option
def setUp(self):
self.CONFIG_KEY_DICT.clear()
super(ApiAuditingTest, self).__init__(*args, **kwargs)
@classmethod
- def mock_set_config(cls, key, val):
+ def mock_set_module_option(cls, key, val):
cls.settings[key] = val
@classmethod
- def mock_get_config(cls, key, default=None):
+ def mock_get_module_option(cls, key, default=None):
return cls.settings.get(key, default)
@classmethod
def setUpClass(cls):
- mgr.get_config.side_effect = cls.mock_get_config
- mgr.set_config.side_effect = cls.mock_set_config
+ mgr.get_module_option.side_effect = cls.mock_get_module_option
+ mgr.set_module_option.side_effect = cls.mock_set_module_option
@classmethod
def setup_server(cls):
def setUp(self):
mgr.cluster_log = mock.Mock()
- mgr.set_config('AUDIT_API_ENABLED', True)
- mgr.set_config('AUDIT_API_LOG_PAYLOAD', True)
+ mgr.set_module_option('AUDIT_API_ENABLED', True)
+ mgr.set_module_option('AUDIT_API_LOG_PAYLOAD', True)
def _validate_cluster_log_msg(self, path, method, user, params):
channel, _, msg = mgr.cluster_log.call_args_list[0][0]
self.assertDictEqual(json.loads(m.group(5)), params)
def test_no_audit(self):
- mgr.set_config('AUDIT_API_ENABLED', False)
+ mgr.set_module_option('AUDIT_API_ENABLED', False)
self._delete('/foo/test1')
mgr.cluster_log.assert_not_called()
def test_no_payload(self):
- mgr.set_config('AUDIT_API_LOG_PAYLOAD', False)
+ mgr.set_module_option('AUDIT_API_LOG_PAYLOAD', False)
self._delete('/foo/test1')
_, _, msg = mgr.cluster_log.call_args_list[0][0]
self.assertNotIn('params=', msg)
'GRAFANA_API_USERNAME': 'admin',
'GRAFANA_API_PASSWORD': 'admin'
}
- mgr.get_config.side_effect = settings.get
+ mgr.get_module_option.side_effect = settings.get
GrafanaProxy._cp_config['tools.authenticate.on'] = False # pylint: disable=protected-access
cls.setup_controllers([GrafanaProxy, GrafanaMockInstance])
class RestClientTest(unittest.TestCase):
def setUp(self):
settings = {'REST_REQUESTS_TIMEOUT': 45}
- mgr.get_config.side_effect = settings.get
+ mgr.get_module_option.side_effect = settings.get
def test_timeout_auto_set(self):
with patch('requests.Session.request') as mock_request:
}
@classmethod
- def mock_set_config(cls, key, val):
+ def mock_set_module_option(cls, key, val):
cls.settings[key] = val
@classmethod
- def mock_get_config(cls, key, default):
+ def mock_get_module_option(cls, key, default):
return cls.settings.get(key, default)
@classmethod
def setUpClass(cls):
- mgr.get_config.side_effect = cls.mock_get_config
- mgr.set_config.side_effect = cls.mock_set_config
+ mgr.get_module_option.side_effect = cls.mock_get_module_option
+ mgr.set_module_option.side_effect = cls.mock_set_module_option
def setUp(self):
RgwClient._user_instances.clear() # pylint: disable=protected-access
def test_ssl_verify(self):
- mgr.set_config('RGW_API_SSL_VERIFY', True)
+ mgr.set_module_option('RGW_API_SSL_VERIFY', True)
instance = RgwClient.admin_instance()
self.assertTrue(instance.session.verify)
def test_no_ssl_verify(self):
- mgr.set_config('RGW_API_SSL_VERIFY', False)
+ mgr.set_module_option('RGW_API_SSL_VERIFY', False)
instance = RgwClient.admin_instance()
self.assertFalse(instance.session.verify)
settings._OPTIONS_COMMAND_MAP = settings._options_command_map()
@classmethod
- def mock_set_config(cls, attr, val):
+ def mock_set_module_option(cls, attr, val):
cls.CONFIG_KEY_DICT[attr] = val
@classmethod
- def mock_get_config(cls, attr, default):
+ def mock_get_module_option(cls, attr, default):
return cls.CONFIG_KEY_DICT.get(attr, default)
def setUp(self):
self.CONFIG_KEY_DICT.clear()
- mgr.set_config.side_effect = self.mock_set_config
- mgr.get_config.side_effect = self.mock_get_config
+ mgr.set_module_option.side_effect = self.mock_set_module_option
+ mgr.get_module_option.side_effect = self.mock_get_module_option
if Settings.GRAFANA_API_HOST != 'localhost':
Settings.GRAFANA_API_HOST = 'localhost'
if Settings.GRAFANA_API_PORT != 3000:
cls.setup_controllers([SettingsController])
@classmethod
- def mock_set_config(cls, attr, val):
+ def mock_set_module_option(cls, attr, val):
cls.config_values[attr] = val
@classmethod
- def mock_get_config(cls, attr, default):
+ def mock_get_module_option(cls, attr, default):
return cls.config_values.get(attr, default)
def setUp(self):
self.config_values.clear()
- mgr.set_config.side_effect = self.mock_set_config
- mgr.get_config.side_effect = self.mock_get_config
+ mgr.set_module_option.side_effect = self.mock_set_module_option
+ mgr.get_module_option.side_effect = self.mock_get_module_option
def test_settings_list(self):
self._get('/api/settings')
CONFIG_KEY_DICT = {}
@classmethod
- def mock_set_config(cls, attr, val):
+ def mock_set_module_option(cls, attr, val):
cls.CONFIG_KEY_DICT[attr] = val
@classmethod
- def mock_get_config(cls, attr, default):
+ def mock_get_module_option(cls, attr, default):
return cls.CONFIG_KEY_DICT.get(attr, default)
IDP_METADATA = '''<?xml version="1.0"?>
@classmethod
def setUpClass(cls):
- mgr.set_config.side_effect = cls.mock_set_config
- mgr.get_config.side_effect = cls.mock_get_config
- mgr.set_store.side_effect = cls.mock_set_config
- mgr.get_store.side_effect = cls.mock_get_config
+ mgr.set_module_option.side_effect = cls.mock_set_module_option
+ mgr.get_module_option.side_effect = cls.mock_get_module_option
+ # kludge below
+ mgr.set_store.side_effect = cls.mock_set_module_option
+ mgr.get_store.side_effect = cls.mock_get_module_option
def setUp(self):
self.CONFIG_KEY_DICT.clear()
def predict_lift_expectancy(self, devid):
plugin_name = ''
- model = self.get_option('device_failure_prediction_mode')
+ model = self.get_ceph_option('device_failure_prediction_mode')
if model and model.lower() == 'cloud':
plugin_name = 'diskprediction_cloud'
elif model and model.lower() == 'local':
def predict_all_devices(self):
plugin_name = ''
- model = self.get_option('device_failure_prediction_mode')
+ model = self.get_ceph_option('device_failure_prediction_mode')
if model and model.lower() == 'cloud':
plugin_name = 'diskprediction_cloud'
elif model and model.lower() == 'local':
opt['name'],
self.get_module_option(opt['name']) or opt['default'])
self.log.debug(' %s = %s', opt['name'], getattr(self, opt['name']))
- if not self._activated_cloud and self.get_option('device_failure_prediction_mode') == 'cloud':
+ if not self._activated_cloud and self.get_ceph_option('device_failure_prediction_mode') == 'cloud':
self._event.set()
- if self._activated_cloud and self.get_option('device_failure_prediction_mode') != 'cloud':
+ if self._activated_cloud and self.get_ceph_option('device_failure_prediction_mode') != 'cloud':
self._event.set()
@property
while self._run:
self.refresh_config()
- mode = self.get_option('device_failure_prediction_mode')
+ mode = self.get_ceph_option('device_failure_prediction_mode')
if mode == 'cloud':
if not self._activated_cloud:
self.start_cloud_disk_prediction()
opt['name'],
self.get_module_option(opt['name']) or opt['default'])
self.log.debug(' %s = %s', opt['name'], getattr(self, opt['name']))
- if self.get_option('device_failure_prediction_mode') == 'local':
+ if self.get_ceph_option('device_failure_prediction_mode') == 'local':
self._event.set()
def refresh_config(self):
while self._run:
self.refresh_config()
- mode = self.get_option('device_failure_prediction_mode')
+ mode = self.get_ceph_option('device_failure_prediction_mode')
if mode == 'local':
now = datetime.datetime.utcnow()
if not last_predicted:
"""
return self._ceph_get_mgr_id()
- def get_option(self, key):
+ def get_ceph_option(self, key):
return self._ceph_get_option(key)
def _validate_module_option(self, key):