From: Redouane Kachach Date: Fri, 5 Sep 2025 08:42:10 +0000 (+0200) Subject: mgr/cephadm: adapting ingress svc to use the new cert mgmt approach X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=96d3e1ed95fc66fdf413553b864d1ee1d34a6dc6;p=ceph.git mgr/cephadm: adapting ingress svc to use the new cert mgmt approach Signed-off-by: Redouane Kachach --- diff --git a/src/pybind/mgr/cephadm/services/ingress.py b/src/pybind/mgr/cephadm/services/ingress.py index 7b436346986f..5042f6ea27ae 100644 --- a/src/pybind/mgr/cephadm/services/ingress.py +++ b/src/pybind/mgr/cephadm/services/ingress.py @@ -61,6 +61,7 @@ class IngressService(CephService): self, daemon_spec: CephadmDaemonDeploySpec, ) -> CephadmDaemonDeploySpec: + super().prepare_create(daemon_spec) if daemon_spec.daemon_type == 'haproxy': return self.haproxy_prepare_create(daemon_spec) if daemon_spec.daemon_type == 'keepalived': @@ -237,11 +238,10 @@ class IngressService(CephService): } } - if spec.ssl_cert: - config_files['files']['haproxy.pem'] = spec.ssl_cert - - if spec.ssl_key: - config_files['files']['haproxy.pem.key'] = spec.ssl_key + if spec.ssl: + tls_pair = self.get_certificates(daemon_spec) + combined_pem = tls_pair.cert + '\n' + tls_pair.key + config_files['files']['haproxy.pem'] = combined_pem return config_files, self.get_haproxy_dependencies(self.mgr, spec) diff --git a/src/pybind/mgr/cephadm/templates/services/ingress/haproxy.cfg.j2 b/src/pybind/mgr/cephadm/templates/services/ingress/haproxy.cfg.j2 index f2c9acd028d3..9491685c4d18 100644 --- a/src/pybind/mgr/cephadm/templates/services/ingress/haproxy.cfg.j2 +++ b/src/pybind/mgr/cephadm/templates/services/ingress/haproxy.cfg.j2 @@ -57,7 +57,7 @@ frontend stats monitor-uri /health frontend frontend -{% if spec.ssl_cert %} +{% if spec.ssl or spec.ssl_cert %} bind {{ ip }}:{{ frontend_port }} ssl crt /var/lib/haproxy/haproxy.pem {{ v4v6_flag }} {% else %} bind {{ ip }}:{{ frontend_port }} {{ v4v6_flag }} diff --git a/src/python-common/ceph/deployment/service_spec.py b/src/python-common/ceph/deployment/service_spec.py index 0f45117804ab..f24cfb982e46 100644 --- a/src/python-common/ceph/deployment/service_spec.py +++ b/src/python-common/ceph/deployment/service_spec.py @@ -37,6 +37,7 @@ from ceph.deployment.hostspec import HostSpec, SpecValidationError, assert_valid from ceph.deployment.utils import unwrap_ipv6, valid_addr, verify_non_negative_int from ceph.deployment.utils import verify_positive_int, verify_non_negative_number from ceph.deployment.utils import verify_boolean, verify_enum +from ceph.deployment.utils import parse_combined_pem_file from ceph.utils import is_hex from ceph.smb import constants as smbconst @@ -1506,6 +1507,15 @@ class RGWSpec(ServiceSpec): def validate(self) -> None: super(RGWSpec, self).validate() + if self.ssl: + if not self.ssl_cert and self.rgw_frontend_ssl_certificate: + combined_cert = self.rgw_frontend_ssl_certificate + if isinstance(combined_cert, list): + combined_cert = '\n'.join(combined_cert) + self.ssl_cert, self.ssl_key = parse_combined_pem_file(combined_cert) + if not (self.ssl_cert and self.ssl_key): + raise SpecValidationError("Failed to parse rgw_frontend_ssl_certificate field.") + if self.rgw_realm and not self.rgw_zone: raise SpecValidationError( 'Cannot add RGW: Realm specified but no zone specified') diff --git a/src/python-common/ceph/deployment/utils.py b/src/python-common/ceph/deployment/utils.py index 758eddc94124..0bc92b6df7ae 100644 --- a/src/python-common/ceph/deployment/utils.py +++ b/src/python-common/ceph/deployment/utils.py @@ -6,6 +6,25 @@ from ceph.deployment.hostspec import SpecValidationError from numbers import Number +def parse_combined_pem_file(pem_data: str) -> Tuple[Optional[str], Optional[str]]: + + # Extract the certificate + cert_start = "-----BEGIN CERTIFICATE-----" + cert_end = "-----END CERTIFICATE-----" + cert = None + if cert_start in pem_data and cert_end in pem_data: + cert = pem_data[pem_data.index(cert_start):pem_data.index(cert_end) + len(cert_end)] + + # Extract the private key + key_start = "-----BEGIN PRIVATE KEY-----" + key_end = "-----END PRIVATE KEY-----" + private_key = None + if key_start in pem_data and key_end in pem_data: + private_key = pem_data[pem_data.index(key_start):pem_data.index(key_end) + len(key_end)] + + return cert, private_key + + def unwrap_ipv6(address): # type: (str) -> str if address.startswith('[') and address.endswith(']'):