if spec.ssl:
san_list = spec.zonegroup_hostnames or []
custom_sans = san_list + [f"*.{h}" for h in san_list] if spec.wildcard_enabled else san_list
- tls_creds = self.get_certificates(daemon_spec, custom_sans)
+ tls_creds = self.get_certificates(daemon_spec, custom_sans=custom_sans)
pem = f'{tls_creds.key.rstrip()}\n{tls_creds.cert.lstrip()}'
rgw_cert_name = daemon_spec.name() if spec.generate_cert else spec.service_name()
ret, out, err = self.mgr.check_mon_command({
if svc_spec.ssl:
ip = self.get_mgmt_gw_ip(svc_spec, daemon_spec)
- tls_pair = self.get_certificates(daemon_spec, [ip])
+ tls_pair = self.get_certificates(daemon_spec, ips=[ip])
daemon_config["files"]["nginx.crt"] = tls_pair.cert
daemon_config["files"]["nginx.key"] = tls_pair.key
def get_grafana_certificates(self, daemon_spec: CephadmDaemonDeploySpec) -> TLSCredentials:
host_ips = [self.mgr.inventory.get_addr(daemon_spec.host)]
host_fqdns = [self.mgr.get_fqdn(daemon_spec.host), 'grafana_servers']
- return self.get_certificates(daemon_spec, host_ips, host_fqdns)
+ return self.get_certificates(daemon_spec, ips=host_ips, fqdns=host_fqdns)
def generate_config(self, daemon_spec: CephadmDaemonDeploySpec) -> Tuple[Dict[str, Any], List[str]]:
assert self.TYPE == daemon_spec.daemon_type
def get_alertmanager_certificates(self, daemon_spec: CephadmDaemonDeploySpec) -> TLSCredentials:
host_ips = [self.mgr.inventory.get_addr(daemon_spec.host)]
host_fqdns = [self.mgr.get_fqdn(daemon_spec.host), 'alertmanager_servers']
- return self.get_certificates(daemon_spec, host_ips, host_fqdns)
+ return self.get_certificates(daemon_spec, ips=host_ips, fqdns=host_fqdns)
@classmethod
def get_dependencies(cls, mgr: "CephadmOrchestrator",
def get_prometheus_certificates(self, daemon_spec: CephadmDaemonDeploySpec) -> TLSCredentials:
host_ips = [self.mgr.inventory.get_addr(daemon_spec.host)]
host_fqdns = [self.mgr.get_fqdn(daemon_spec.host), 'prometheus_servers']
- return self.get_certificates(daemon_spec, host_ips, host_fqdns)
+ return self.get_certificates(daemon_spec, ips=host_ips, fqdns=host_fqdns)
def get_service_discovery_cfg(self, security_enabled: bool, mgmt_gw_enabled: bool) -> Dict[str, List[str]]:
"""
# Inline certs must still be present — the service is still running on host2
assert cm.get_cert(rgw_svc.cert_name, service_name=svc_name) is not None
assert cm.get_key(rgw_svc.key_name, service_name=svc_name) is not None
+
+ @patch("cephadm.serve.CephadmServe._run_cephadm", _run_cephadm('{}'))
+ def test_rgw_zonegroup_hostnames_are_passed_as_custom_sans(
+ self, cephadm_module: CephadmOrchestrator):
+ """RGW zonegroup hostnames must be passed as custom DNS SANs.
+
+ Verifies that zonegroup hostnames are routed to get_certificates() as
+ the custom_sans keyword argument, so that values like s3.example.com
+ and *.s3.example.com are registered as DNS SANs on the generated
+ certificate.
+ """
+ with with_host(cephadm_module, 'host1'):
+ s = RGWSpec(
+ service_id='foo',
+ ssl=True,
+ zonegroup_hostnames=['s3.example.com'],
+ wildcard_enabled=True,
+ rgw_frontend_type='beast',
+ )
+ rgw_svc = service_registry.get_service('rgw')
+ tls_creds = TLSCredentials(
+ cert=ceph_generated_cert,
+ key=ceph_generated_key,
+ )
+ with patch.object(rgw_svc, 'get_certificates',
+ return_value=tls_creds) as get_certificates:
+ with with_service(cephadm_module, s):
+ # The serve loop may invoke get_certificates more than once;
+ # assert on the arguments of every call, not the count.
+ get_certificates.assert_called()
+ for args, kwargs in get_certificates.call_args_list:
+ # custom_sans must be a kwarg, never the positional ips arg
+ assert len(args) == 1
+ assert kwargs == {
+ 'custom_sans': ['s3.example.com', '*.s3.example.com'],
+ }