diff --git a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/certificate.py b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/certificate.py index 34fbe452c7..fe871b27a2 100644 --- a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/certificate.py +++ b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/certificate.py @@ -308,24 +308,25 @@ class CertificateController(rest.RestController): capabilities = system.capabilities # platform-cert 'force' check for backward compatibility - if mode == constants.CERT_MODE_SSL: + if self._is_mode_supported_by_cert_manager(mode): # Call may not contain 'force' parameter # Note: cert-mon will pass a HTTP POST 'force'='true' param - force = pecan.request.POST.get('force') - if force == 'true': - force = True - else: - force = False - # if RESTAPI_CERT_SECRET_NAME secret is present in k8s, we - # assume that SSL cert is managed by cert-manager/cert-mon + force_param = pecan.request.POST.get('force') + force = force_param == "true" + + plat_cert_name = self._get_secret_name_for_mode(mode) + + # if the certificate secret is present in k8s, we + # assume that SSL cert is currently being managed by + # cert-manager/cert-mon managed_by_cm = self._kube_op.kube_get_secret( - constants.RESTAPI_CERT_SECRET_NAME, + plat_cert_name, constants.CERT_NAMESPACE_PLATFORM_CERTS) if force is False and managed_by_cm is not None: msg = "Certificate is currently being managed by cert-manager. \n" \ "To manage certificate with this command, first delete " \ - "the %s Certificate and Secret." % constants.RESTAPI_CERT_SECRET_NAME + "the %s Certificate and Secret." % plat_cert_name LOG.info(msg) return dict(success="", error=msg) @@ -572,6 +573,14 @@ class CertificateController(rest.RestController): return res + @staticmethod + def _get_secret_name_for_mode(mode): + return constants.CERT_MODE_TO_SECRET_NAME[mode] + + @staticmethod + def _is_mode_supported_by_cert_manager(mode): + return mode in constants.CERT_MODES_SUPPORTED_CERT_MANAGER + @cutils.synchronized(LOCK_NAME) @wsme_pecan.wsexpose(Certificate, types.uuid, status_code=200) def delete(self, certificate_uuid): diff --git a/sysinv/sysinv/sysinv/sysinv/cert_mon/watcher.py b/sysinv/sysinv/sysinv/sysinv/cert_mon/watcher.py index 1677b46c85..11478a7eca 100644 --- a/sysinv/sysinv/sysinv/sysinv/cert_mon/watcher.py +++ b/sysinv/sysinv/sysinv/sysinv/cert_mon/watcher.py @@ -564,4 +564,4 @@ class RegistryCertRenew(PlatformCertRenew): def update_certificate(self, event_data): LOG.info('RegistryCertRenew: Secret changes detected. Initiating certificate update') - self.update_platform_certificate(event_data, constants.CERT_MODE_DOCKER_REGISTRY) + self.update_platform_certificate(event_data, constants.CERT_MODE_DOCKER_REGISTRY, force=True) diff --git a/sysinv/sysinv/sysinv/sysinv/common/constants.py b/sysinv/sysinv/sysinv/sysinv/common/constants.py index e5c1b31533..370faf0af7 100644 --- a/sysinv/sysinv/sysinv/sysinv/common/constants.py +++ b/sysinv/sysinv/sysinv/sysinv/common/constants.py @@ -1397,6 +1397,8 @@ CERT_MODES_SUPPORTED = [CERT_MODE_SSL, CERT_MODE_OPENSTACK, CERT_MODE_OPENSTACK_CA, ] +CERT_MODES_SUPPORTED_CERT_MANAGER = [CERT_MODE_SSL, + CERT_MODE_DOCKER_REGISTRY] # CONFIG file permissions CONFIG_FILE_PERMISSION_ROOT_READ_ONLY = 0o400 @@ -1738,3 +1740,8 @@ ADMIN_EP_CERT_FORMAT = '{tls_key}' RESTAPI_CERT_SECRET_NAME = "system-restapi-gui-certificate" REGISTRY_CERT_SECRET_NAME = "system-registry-local-certificate" CERT_NAMESPACE_PLATFORM_CERTS = 'deployment' + +CERT_MODE_TO_SECRET_NAME = { + CERT_MODE_SSL: RESTAPI_CERT_SECRET_NAME, + CERT_MODE_DOCKER_REGISTRY: REGISTRY_CERT_SECRET_NAME +} diff --git a/sysinv/sysinv/sysinv/sysinv/tests/api/test_certificate.py b/sysinv/sysinv/sysinv/sysinv/tests/api/test_certificate.py index c11223d2ce..c02ce4ecf7 100644 --- a/sysinv/sysinv/sysinv/sysinv/tests/api/test_certificate.py +++ b/sysinv/sysinv/sysinv/sysinv/tests/api/test_certificate.py @@ -523,9 +523,15 @@ class ApiCertificatePostTestSuite(ApiCertificateTestCaseMixin, 'CA cert' self.assertIn(fault_string_expected, str(resp.get('error'))) - # Test install ssl certificate signed by intermediate CA + # Test failed installation of ssl certificate managed by cert-manager def test_force_failure_install_ssl_certificate(self): - mode = 'ssl' + self.force_failure_install_certificate(constants.CERT_MODE_SSL) + + # Test failed installation of docker_registry certificate managed by cert-manager + def test_force_failure_install_docker_registry_certificate(self): + self.force_failure_install_certificate(constants.CERT_MODE_DOCKER_REGISTRY) + + def force_failure_install_certificate(self, mode): certfile = os.path.join(os.path.dirname(__file__), "data", 'ssl-cert-2xcert-1xkey-with-key.pem') @@ -560,9 +566,15 @@ class ApiCertificatePostTestSuite(ApiCertificateTestCaseMixin, fault_err_msg = "Certificate is currently being managed by cert-manager" self.assertIn(fault_err_msg, str(resp.get('error'))) - # Test install ssl certificate signed by intermediate CA + # Test successful forced installation of ssl certificate managed by cert-manager def test_force_success_install_ssl_certificate(self): - mode = 'ssl' + self.force_success_install_certificate(constants.CERT_MODE_SSL) + + # Test successful forced installation of docker_registry certificate managed by cert-manager + def test_force_success_install_docker_registry_certificate(self): + self.force_success_install_certificate(constants.CERT_MODE_DOCKER_REGISTRY) + + def force_success_install_certificate(self, mode): certfile = os.path.join(os.path.dirname(__file__), "data", 'ssl-cert-2xcert-1xkey-with-key.pem')