github.com/verrazzano/verrazzano@v1.7.0/pkg/k8s/ready/certificates.go (about) 1 // Copyright (c) 2022, 2023, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 package ready 4 5 import ( 6 "context" 7 "github.com/verrazzano/verrazzano/pkg/vzcr" 8 "sort" 9 10 certapiv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" 11 cmmeta "github.com/cert-manager/cert-manager/pkg/apis/meta/v1" 12 "github.com/verrazzano/verrazzano/pkg/log/vzlog" 13 vzapi "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1alpha1" 14 "k8s.io/apimachinery/pkg/api/errors" 15 "k8s.io/apimachinery/pkg/types" 16 clipkg "sigs.k8s.io/controller-runtime/pkg/client" 17 ) 18 19 // CertificatesAreReady Checks the list of named objects to see if there are matching 20 // Cert-Manager Certificate objects, and checks if those are in a Ready state. 21 // 22 // ctx A valid ComponentContext for the operation 23 // certificates A list of NamespacedNames; this should be names of expected Certificate objects 24 // 25 // Returns true and an empty list of names if all certs are ready, false and a list of certificate names that are 26 // NOT in the ready state 27 func CertificatesAreReady(client clipkg.Client, log vzlog.VerrazzanoLogger, vz *vzapi.Verrazzano, certificates []types.NamespacedName) (ready bool, certsNotReady []types.NamespacedName) { 28 if len(certificates) == 0 { 29 return true, []types.NamespacedName{} 30 } 31 32 if !vzcr.IsClusterIssuerEnabled(vz) { 33 log.Oncef("Cert-Manager ClusterIssuer disabled, skipping certificates check") 34 return true, []types.NamespacedName{} 35 } 36 37 log.Oncef("Checking certificates status for %v", certificates) 38 for _, name := range certificates { 39 ready, err := IsCertficateIsReady(log, client, name) 40 if err != nil { 41 log.Errorf("Error getting certificate %s: %s", name, err) 42 } 43 if !ready { 44 certsNotReady = append(certsNotReady, name) 45 } 46 } 47 return len(certsNotReady) == 0, certsNotReady 48 } 49 50 // IsCertficateIsReady Checks if a Cert-Manager Certificate object with the specified NamespacedName 51 // can be found in the cluster, and if it is in a Ready state. 52 // 53 // Returns 54 // - true/nil if a matching Certificate object is found and Ready 55 // - false/nil if a matching Certifiate object is found and not Ready 56 // - false/error if an unexpected error has occurred 57 func IsCertficateIsReady(log vzlog.VerrazzanoLogger, client clipkg.Client, name types.NamespacedName) (bool, error) { 58 cert := &certapiv1.Certificate{} 59 if err := client.Get(context.TODO(), name, cert); err != nil { 60 if errors.IsNotFound(err) { 61 return false, nil 62 } 63 return false, err 64 } 65 certConditions := cert.Status.Conditions 66 if len(certConditions) > 0 { 67 if len(certConditions) > 1 { 68 // Typically, I've only seen one condition in the Certificate object, but if there's 69 // more than one sort the copy so the most recent is first 70 sort.Slice(certConditions, func(i, j int) bool { 71 return certConditions[i].LastTransitionTime.After( 72 certConditions[j].LastTransitionTime.Time) 73 }) 74 } 75 mostRecent := certConditions[0] 76 if mostRecent.Status == cmmeta.ConditionTrue && mostRecent.Type == certapiv1.CertificateConditionReady { 77 return true, nil 78 } 79 log.Progressf("Certificate %s not ready, reason: %s, message: %s", name, mostRecent.Reason, mostRecent.Message) 80 } 81 return false, nil 82 }