[OOM-K8S-CERT-EXTERNAL-PROVIDER] Add health check of CMPv2 provisioner (cert-service...
[oom/platform/cert-service.git] / certServiceK8sExternalProvider / src / cmpv2controller / certificate_request_controller.go
index 38b5cdf..136d3eb 100644 (file)
@@ -28,8 +28,6 @@ package cmpv2controller
 import (
        "context"
        "fmt"
-       "onap.org/oom-certservice/k8s-external-provider/src/cmpv2api"
-       provisioners "onap.org/oom-certservice/k8s-external-provider/src/cmpv2provisioner"
 
        "github.com/go-logr/logr"
        apiutil "github.com/jetstack/cert-manager/pkg/api/util"
@@ -41,6 +39,14 @@ import (
        "k8s.io/client-go/tools/record"
        ctrl "sigs.k8s.io/controller-runtime"
        "sigs.k8s.io/controller-runtime/pkg/client"
+
+       "onap.org/oom-certservice/k8s-external-provider/src/cmpv2api"
+       provisioners "onap.org/oom-certservice/k8s-external-provider/src/cmpv2provisioner"
+)
+
+const (
+       privateKeySecretNameAnnotation = "cert-manager.io/private-key-secret-name"
+       privateKeySecretKey = "tls.key"
 )
 
 // CertificateRequestController reconciles a CMPv2Issuer object.
@@ -59,6 +65,7 @@ func (controller *CertificateRequestController) Reconcile(k8sRequest ctrl.Reques
 
        // 1. Fetch the CertificateRequest resource being reconciled.
        certificateRequest := new(cmapi.CertificateRequest)
+       log.Info("Registered new certificate sign request: ", "cert-name", certificateRequest.Name)
        if err := controller.Client.Get(ctx, k8sRequest.NamespacedName, certificateRequest); err != nil {
                err = handleErrorResourceNotFound(log, err)
                return ctrl.Result{}, err
@@ -66,7 +73,7 @@ func (controller *CertificateRequestController) Reconcile(k8sRequest ctrl.Reques
 
        // 2. Check if CertificateRequest is meant for CMPv2Issuer (if not ignore)
        if !isCMPv2CertificateRequest(certificateRequest) {
-               log.V(4).Info("Certificate request is not meant for CMPv2Issuer (ignoring)",
+               log.Info("Certificate request is not meant for CMPv2Issuer (ignoring)",
                        "group", certificateRequest.Spec.IssuerRef.Group,
                        "kind", certificateRequest.Spec.IssuerRef.Kind)
                return ctrl.Result{}, nil
@@ -75,7 +82,7 @@ func (controller *CertificateRequestController) Reconcile(k8sRequest ctrl.Reques
        // 3. If the certificate data is already set then we skip this request as it
        // has already been completed in the past.
        if len(certificateRequest.Status.Certificate) > 0 {
-               log.V(4).Info("Existing certificate data found in status, skipping already completed CertificateRequest")
+               log.Info("Existing certificate data found in status, skipping already completed CertificateRequest")
                return ctrl.Result{}, nil
        }
 
@@ -103,14 +110,27 @@ func (controller *CertificateRequestController) Reconcile(k8sRequest ctrl.Reques
                return ctrl.Result{}, err
        }
 
-       // 7. Sign CertificateRequest
-       signedPEM, trustedCAs, err := provisioner.Sign(ctx, certificateRequest)
+       // 7. Get private key matching CertificateRequest
+       privateKeySecretName := certificateRequest.ObjectMeta.Annotations[privateKeySecretNameAnnotation]
+       privateKeySecretNamespaceName := types.NamespacedName{
+               Namespace: k8sRequest.Namespace,
+               Name:      privateKeySecretName,
+       }
+       var privateKeySecret core.Secret
+       if err := controller.Client.Get(ctx, privateKeySecretNamespaceName, &privateKeySecret); err != nil {
+               controller.handleErrorGettingPrivateKey(ctx, log, err, certificateRequest, privateKeySecretNamespaceName)
+               return ctrl.Result{}, err
+       }
+       privateKeyBytes := privateKeySecret.Data[privateKeySecretKey]
+
+       // 8. Sign CertificateRequest
+       signedPEM, trustedCAs, err := provisioner.Sign(ctx, certificateRequest, privateKeyBytes)
        if err != nil {
                controller.handleErrorFailedToSignCertificate(ctx, log, err, certificateRequest)
                return ctrl.Result{}, err
        }
 
-       // 8. Store signed certificates in CertificateRequest
+       // 9. Store signed certificates in CertificateRequest
        certificateRequest.Status.Certificate = signedPEM
        certificateRequest.Status.CA = trustedCAs
        if err := controller.updateCertificateRequestWithSignedCerficates(ctx, certificateRequest); err != nil {
@@ -144,7 +164,6 @@ func (controller *CertificateRequestController) setStatus(ctx context.Context, c
        return controller.Client.Status().Update(ctx, certificateRequest)
 }
 
-
 func isCMPv2IssuerReady(issuer cmpv2api.CMPv2Issuer) bool {
        condition := cmpv2api.CMPv2IssuerCondition{Type: cmpv2api.ConditionReady, Status: cmpv2api.ConditionTrue}
        return hasCondition(issuer, condition)
@@ -183,12 +202,17 @@ func (controller *CertificateRequestController) handleErrorCMPv2IssuerIsNotReady
        return err
 }
 
-func (controller *CertificateRequestController) handleErrorGettingCMPv2Issuer(ctx context.Context, log logr.Logger, err error,  certificateRequest *cmapi.CertificateRequest, issuerNamespaceName types.NamespacedName, req ctrl.Request) {
+func (controller *CertificateRequestController) handleErrorGettingCMPv2Issuer(ctx context.Context, log logr.Logger, err error, certificateRequest *cmapi.CertificateRequest, issuerNamespaceName types.NamespacedName, req ctrl.Request) {
        log.Error(err, "Failed to retrieve CMPv2Issuer resource", "namespace", req.Namespace, "name", certificateRequest.Spec.IssuerRef.Name)
        _ = controller.setStatus(ctx, certificateRequest, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to retrieve CMPv2Issuer resource %s: %v", issuerNamespaceName, err)
 }
 
-func (controller *CertificateRequestController) handleErrorFailedToSignCertificate(ctx context.Context, log logr.Logger, err error, certificateRequest *cmapi.CertificateRequest)  {
+func (controller *CertificateRequestController) handleErrorGettingPrivateKey(ctx context.Context, log logr.Logger, err error, certificateRequest *cmapi.CertificateRequest, pkSecretNamespacedName types.NamespacedName) {
+       log.Error(err, "Failed to retrieve private key secret for certificate request", "namespace", pkSecretNamespacedName.Namespace, "name", pkSecretNamespacedName.Name)
+       _ = controller.setStatus(ctx, certificateRequest, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonPending, "Failed to retrieve private key secret: %v", err)
+}
+
+func (controller *CertificateRequestController) handleErrorFailedToSignCertificate(ctx context.Context, log logr.Logger, err error, certificateRequest *cmapi.CertificateRequest) {
        log.Error(err, "Failed to sign certificate request")
        _ = controller.setStatus(ctx, certificateRequest, cmmeta.ConditionFalse, cmapi.CertificateRequestReasonFailed, "Failed to sign certificate request: %v", err)
 }