Utils for managing modules and setting config

The methods for checking modules are taken from the ceph-mon
charm and charmhelpers.contrib.storage.linux.ceph module. When
this lands I'll update the ch methods to emit a deprecation warning
and  update the ceph-mon charm to use these methods instead.

Change-Id: I1b7f08c3bd94828a5c6468df7aab6b38517cf3fa
This commit is contained in:
Liam Young 2021-06-21 13:36:11 +00:00
parent fed8b29000
commit e8240a764e
2 changed files with 190 additions and 0 deletions

View File

@ -24,6 +24,7 @@ import subprocess
import sys import sys
import time import time
import uuid import uuid
import functools
from contextlib import contextmanager from contextlib import contextmanager
from datetime import datetime from datetime import datetime
@ -3377,3 +3378,132 @@ def apply_osd_settings(settings):
level=ERROR) level=ERROR)
raise OSDConfigSetError raise OSDConfigSetError
return True return True
def enabled_manager_modules():
"""Return a list of enabled manager modules.
:rtype: List[str]
"""
cmd = ['ceph', 'mgr', 'module', 'ls']
try:
modules = subprocess.check_output(cmd).decode('UTF-8')
except subprocess.CalledProcessError as e:
log("Failed to list ceph modules: {}".format(e), WARNING)
return []
modules = json.loads(modules)
return modules['enabled_modules']
def is_mgr_module_enabled(module):
"""Is a given manager module enabled.
:param module:
:type module: str
:returns: Whether the named module is enabled
:rtype: bool
"""
return module in enabled_manager_modules()
is_dashboard_enabled = functools.partial(is_mgr_module_enabled, 'dashboard')
def mgr_enable_module(module):
"""Enable a Ceph Manager Module.
:param module: The module name to enable
:type module: str
:raises: subprocess.CalledProcessError
"""
if not is_mgr_module_enabled(module):
subprocess.check_call(['ceph', 'mgr', 'module', 'enable', module])
return True
return False
mgr_enable_dashboard = functools.partial(mgr_enable_module, 'dashboard')
def mgr_disable_module(module):
"""Enable a Ceph Manager Module.
:param module: The module name to enable
:type module: str
:raises: subprocess.CalledProcessError
"""
if is_mgr_module_enabled(module):
subprocess.check_call(['ceph', 'mgr', 'module', 'disable', module])
return True
return False
mgr_disable_dashboard = functools.partial(mgr_disable_module, 'dashboard')
def ceph_config_set(name, value, who):
"""Set a ceph config option
:param name: key to set
:type name: str
:param value: value corresponding to key
:type value: str
:param who: Config area the key is associated with (e.g. 'dashboard')
:type who: str
:raises: subprocess.CalledProcessError
"""
subprocess.check_call(['ceph', 'config', 'set', who, name, value])
mgr_config_set = functools.partial(ceph_config_set, who='mgr')
def ceph_config_get(name, who):
"""Retrieve the value of a ceph config option
:param name: key to lookup
:type name: str
:param who: Config area the key is associated with (e.g. 'dashboard')
:type who: str
:returns: Value associated with key
:rtype: str
:raises: subprocess.CalledProcessError
"""
return subprocess.check_output(
['ceph', 'config', 'get', who, name]).decode('UTF-8')
mgr_config_get = functools.partial(ceph_config_get, who='mgr')
def _dashboard_set_ssl_artifact(path, artifact_name, hostname=None):
"""Set SSL dashboard config option.
:param path: Path to file
:type path: str
:param artifact_name: Option name for setting the artifact
:type artifact_name: str
:param hostname: If hostname is set artifact will only be associated with
the dashboard on that host.
:type hostname: str
:raises: subprocess.CalledProcessError
"""
cmd = ['ceph', 'dashboard', artifact_name]
if hostname:
cmd.append(hostname)
cmd.extend(['-i', path])
log(cmd, level=DEBUG)
subprocess.check_call(cmd)
dashboard_set_ssl_certificate = functools.partial(
_dashboard_set_ssl_artifact,
artifact_name='set-ssl-certificate')
dashboard_set_ssl_certificate_key = functools.partial(
_dashboard_set_ssl_artifact,
artifact_name='set-ssl-certificate-key')

View File

@ -2074,3 +2074,63 @@ class CephGetLVSTestCase(unittest.TestCase):
result = utils.is_pristine_disk('/dev/vdz') result = utils.is_pristine_disk('/dev/vdz')
fake_open.assert_called_with('/dev/vdz', 'rb') fake_open.assert_called_with('/dev/vdz', 'rb')
self.assertEqual(result, False) self.assertEqual(result, False)
class CephManagerAndConfig(unittest.TestCase):
MODULE_OUT = b"""
{
"enabled_modules": [
"dashboard",
"iostat",
"restful"
]}"""
@patch.object(utils.subprocess, 'check_output')
def test_enabled_manager_modules(self, _check_output):
_check_output.return_value = self.MODULE_OUT
self.assertEqual(
utils.enabled_manager_modules(),
['dashboard', 'iostat', 'restful'])
@patch.object(utils, 'enabled_manager_modules')
def test_is_mgr_module_enabled(self, _enabled_manager_modules):
_enabled_manager_modules.return_value = ['dashboard', 'restful']
self.assertTrue(
utils.is_mgr_module_enabled('dashboard'))
self.assertFalse(
utils.is_mgr_module_enabled('ostrich'))
@patch.object(utils, 'is_mgr_module_enabled')
@patch.object(utils.subprocess, 'check_call')
def test_mgr_enable_module(self, _check_call, _is_mgr_module_enabled):
_is_mgr_module_enabled.return_value = True
utils.mgr_enable_module('dashboard')
self.assertFalse(_check_call.called)
_is_mgr_module_enabled.return_value = False
utils.mgr_enable_module('dashboard')
_check_call.assert_called_once_with(
['ceph', 'mgr', 'module', 'enable', 'dashboard'])
@patch.object(utils, 'is_mgr_module_enabled')
@patch.object(utils.subprocess, 'check_call')
def test_mgr_disable_module(self, _check_call, _is_mgr_module_enabled):
_is_mgr_module_enabled.return_value = False
utils.mgr_disable_module('dashboard')
self.assertFalse(_check_call.called)
_is_mgr_module_enabled.return_value = True
utils.mgr_disable_module('dashboard')
_check_call.assert_called_once_with(
['ceph', 'mgr', 'module', 'disable', 'dashboard'])
@patch.object(utils.subprocess, 'check_call')
def test_ceph_config_set(self, _check_call):
utils.ceph_config_set('mgr/dashboard/ssl', 'true', 'mgr')
_check_call.assert_called_once_with(
['ceph', 'config', 'set', 'mgr', 'mgr/dashboard/ssl', 'true'])
@patch.object(utils.subprocess, 'check_output')
def test_ceph_config_get(self, _check_output):
utils.ceph_config_get('mgr/dashboard/ssl', 'mgr')
_check_output.assert_called_once_with(
['ceph', 'config', 'get', 'mgr', 'mgr/dashboard/ssl'])