diff options
author | Adam King <47704447+adk3798@users.noreply.github.com> | 2024-08-02 15:26:17 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-02 15:26:17 +0200 |
commit | 3dbe2b63d6db98a6871f59ab10df6316d34b0e78 (patch) | |
tree | ee2e95e42685d13778ac91520e3eddbc0d49ee05 /src/cephadm | |
parent | Merge pull request #58883 from idryomov/wip-backport-create-resourceattrerror (diff) | |
parent | mgr/cephadm: fixing Grafana domain handling (diff) | |
download | ceph-3dbe2b63d6db98a6871f59ab10df6316d34b0e78.tar.xz ceph-3dbe2b63d6db98a6871f59ab10df6316d34b0e78.zip |
Merge pull request #58402 from rkachach/fix_issue_mtls_support
mgr/cephadm: adding mTLS for ceph mgmt-gateway and backend services communication
Reviewed-by: Adam King <adking@redhat.com>
Diffstat (limited to 'src/cephadm')
-rwxr-xr-x | src/cephadm/cephadm.py | 25 | ||||
-rw-r--r-- | src/cephadm/cephadmlib/daemons/ceph.py | 40 | ||||
-rw-r--r-- | src/cephadm/cephadmlib/daemons/mgmt_gateway.py | 38 | ||||
-rw-r--r-- | src/cephadm/tests/test_cephadm.py | 3 |
4 files changed, 79 insertions, 27 deletions
diff --git a/src/cephadm/cephadm.py b/src/cephadm/cephadm.py index 5deaec55949..5c0762f8bf3 100755 --- a/src/cephadm/cephadm.py +++ b/src/cephadm/cephadm.py @@ -167,6 +167,7 @@ from cephadmlib import templating from cephadmlib.daemons.ceph import get_ceph_mounts_for_type, ceph_daemons from cephadmlib.daemons import ( Ceph, + CephExporter, CephIscsi, CephNvmeof, CustomContainer, @@ -867,6 +868,10 @@ def create_daemon_dirs( node_proxy = NodeProxy.init(ctx, fsid, ident.daemon_id) node_proxy.create_daemon_dirs(data_dir, uid, gid) + elif daemon_type == CephExporter.daemon_type: + ceph_exporter = CephExporter.init(ctx, fsid, ident.daemon_id) + ceph_exporter.create_daemon_dirs(data_dir, uid, gid) + else: daemon = daemon_form_create(ctx, ident) if isinstance(daemon, ContainerDaemonForm): @@ -2421,11 +2426,23 @@ def prepare_dashboard( pathify(ctx.dashboard_crt.name): '/tmp/dashboard.crt:z', pathify(ctx.dashboard_key.name): '/tmp/dashboard.key:z' } - cli(['dashboard', 'set-ssl-certificate', '-i', '/tmp/dashboard.crt'], extra_mounts=mounts) - cli(['dashboard', 'set-ssl-certificate-key', '-i', '/tmp/dashboard.key'], extra_mounts=mounts) else: - logger.info('Generating a dashboard self-signed certificate...') - cli(['dashboard', 'create-self-signed-cert']) + logger.info('Using certmgr to generate dashboard self-signed certificate...') + cert_key = json_loads_retry(lambda: cli(['orch', 'certmgr', 'generate-certificates', 'dashboard'], + verbosity=CallVerbosity.QUIET_UNLESS_ERROR)) + mounts = {} + if cert_key: + cert_file = write_tmp(cert_key['cert'], uid, gid) + key_file = write_tmp(cert_key['key'], uid, gid) + mounts = { + cert_file.name: '/tmp/dashboard.crt:z', + key_file.name: '/tmp/dashboard.key:z' + } + else: + logger.error('Cannot generate certificates for Ceph dashboard.') + + cli(['dashboard', 'set-ssl-certificate', '-i', '/tmp/dashboard.crt'], extra_mounts=mounts) + cli(['dashboard', 'set-ssl-certificate-key', '-i', '/tmp/dashboard.key'], extra_mounts=mounts) logger.info('Creating initial admin user...') password = ctx.initial_dashboard_password or generate_password() diff --git a/src/cephadm/cephadmlib/daemons/ceph.py b/src/cephadm/cephadmlib/daemons/ceph.py index d5e87ad9484..efb013c7e09 100644 --- a/src/cephadm/cephadmlib/daemons/ceph.py +++ b/src/cephadm/cephadmlib/daemons/ceph.py @@ -16,7 +16,14 @@ from ..constants import DEFAULT_IMAGE from ..context import CephadmContext from ..deployment_utils import to_deployment_container from ..exceptions import Error -from ..file_utils import make_run_dir, pathify +from ..file_utils import ( + make_run_dir, + pathify, + populate_files, + makedirs, + recursive_chown, +) +from ..data_utils import dict_get from ..host_facts import HostFacts from ..logging import Highlight from ..net_utils import get_hostname, get_ip_addresses @@ -298,6 +305,8 @@ class CephExporter(ContainerDaemonForm): self.port = config_json.get('port', self.DEFAULT_PORT) self.prio_limit = config_json.get('prio-limit', 5) self.stats_period = config_json.get('stats-period', 5) + self.https_enabled: bool = config_json.get('https_enabled', False) + self.files = dict_get(config_json, 'files', {}) @classmethod def init( @@ -323,6 +332,15 @@ class CephExporter(ContainerDaemonForm): f'--prio-limit={self.prio_limit}', f'--stats-period={self.stats_period}', ] + if self.https_enabled: + args.extend( + [ + '--cert-file', + '/etc/certs/ceph-exporter.crt', + '--key-file', + '/etc/certs/ceph-exporter.key', + ] + ) return args def validate(self) -> None: @@ -348,6 +366,9 @@ class CephExporter(ContainerDaemonForm): ) -> None: cm = Ceph.get_ceph_mounts(ctx, self.identity) mounts.update(cm) + if self.https_enabled: + data_dir = self.identity.data_dir(ctx.data_dir) + mounts.update({os.path.join(data_dir, 'etc/certs'): '/etc/certs'}) def customize_process_args( self, ctx: CephadmContext, args: List[str] @@ -376,6 +397,23 @@ class CephExporter(ContainerDaemonForm): # it until now self.validate() + def create_daemon_dirs(self, data_dir: str, uid: int, gid: int) -> None: + """Create files under the container data dir""" + if not os.path.isdir(data_dir): + raise OSError('data_dir is not a directory: %s' % (data_dir)) + logger.info('Writing ceph-exporter config...') + config_dir = os.path.join(data_dir, 'etc/') + ssl_dir = os.path.join(data_dir, 'etc/certs') + for ddir in [config_dir, ssl_dir]: + makedirs(ddir, uid, gid, 0o755) + recursive_chown(ddir, uid, gid) + cert_files = { + fname: content + for fname, content in self.files.items() + if fname.endswith('.crt') or fname.endswith('.key') + } + populate_files(ssl_dir, cert_files, uid, gid) + def get_ceph_mounts_for_type( ctx: CephadmContext, fsid: str, daemon_type: str diff --git a/src/cephadm/cephadmlib/daemons/mgmt_gateway.py b/src/cephadm/cephadmlib/daemons/mgmt_gateway.py index 93dfc275c41..b0a6f0579d2 100644 --- a/src/cephadm/cephadmlib/daemons/mgmt_gateway.py +++ b/src/cephadm/cephadmlib/daemons/mgmt_gateway.py @@ -104,9 +104,22 @@ class MgmtGateway(ContainerDaemonForm): raise OSError('data_dir is not a directory: %s' % (data_dir)) logger.info('Writing mgmt-gateway config...') config_dir = os.path.join(data_dir, 'etc/') - makedirs(config_dir, uid, gid, 0o755) - recursive_chown(config_dir, uid, gid) - populate_files(config_dir, self.files, uid, gid) + ssl_dir = os.path.join(data_dir, 'etc/ssl') + for ddir in [config_dir, ssl_dir]: + makedirs(ddir, uid, gid, 0o755) + recursive_chown(ddir, uid, gid) + conf_files = { + fname: content + for fname, content in self.files.items() + if fname.endswith('.conf') + } + cert_files = { + fname: content + for fname, content in self.files.items() + if fname.endswith('.crt') or fname.endswith('.key') + } + populate_files(config_dir, conf_files, uid, gid) + populate_files(ssl_dir, cert_files, uid, gid) def _get_container_mounts(self, data_dir: str) -> Dict[str, str]: mounts: Dict[str, str] = {} @@ -152,23 +165,6 @@ class MgmtGateway(ContainerDaemonForm): os.path.join( data_dir, 'etc/nginx_external_server.conf' ): '/etc/nginx_external_server.conf:Z', - os.path.join( - data_dir, 'etc/nginx_internal.crt' - ): '/etc/nginx/ssl/nginx_internal.crt:Z', - os.path.join( - data_dir, 'etc/nginx_internal.key' - ): '/etc/nginx/ssl/nginx_internal.key:Z', + os.path.join(data_dir, 'etc/ssl'): '/etc/nginx/ssl/', } ) - - if 'nginx.crt' in self.files: - mounts.update( - { - os.path.join( - data_dir, 'etc/nginx.crt' - ): '/etc/nginx/ssl/nginx.crt:Z', - os.path.join( - data_dir, 'etc/nginx.key' - ): '/etc/nginx/ssl/nginx.key:Z', - } - ) diff --git a/src/cephadm/tests/test_cephadm.py b/src/cephadm/tests/test_cephadm.py index 6a5f4c9f00c..9e0345fe758 100644 --- a/src/cephadm/tests/test_cephadm.py +++ b/src/cephadm/tests/test_cephadm.py @@ -282,7 +282,8 @@ class TestCephAdm(object): @mock.patch('cephadmlib.firewalld.Firewalld', mock_bad_firewalld) @mock.patch('cephadm.Firewalld', mock_bad_firewalld) @mock.patch('cephadm.logger') - def test_skip_firewalld(self, _logger, cephadm_fs): + @mock.patch('cephadm.json_loads_retry', return_value=None) + def test_skip_firewalld(self, _logger, _jlr, cephadm_fs): """ test --skip-firewalld actually skips changing firewall """ |