diff --git a/pkg/util/helpers.go b/pkg/util/helpers.go index 7f8bfecc..cd2051a3 100644 --- a/pkg/util/helpers.go +++ b/pkg/util/helpers.go @@ -19,14 +19,18 @@ limitations under the License. package util import ( + "crypto/x509" "fmt" + "sync/atomic" "github.com/pkg/errors" + "github.com/submariner-io/admiral/pkg/resource" resourceUtil "github.com/submariner-io/admiral/pkg/resource" "k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/discovery" "k8s.io/client-go/rest" "k8s.io/client-go/restmapper" @@ -39,6 +43,8 @@ const ( StatusField = "status" ) +var lastBadCertificate atomic.Value + func BuildRestMapper(restConfig *rest.Config) (meta.RESTMapper, error) { discoveryClient, err := discovery.NewDiscoveryClientForConfig(restConfig) if err != nil { @@ -131,3 +137,23 @@ func CopyImmutableMetadata(from, to *unstructured.Unstructured) *unstructured.Un return to } + +func AddCertificateErrorHandler(fatal bool) { + var logCertificateError = logger.Errorf + if fatal { + logCertificateError = logger.FatalfOnError + } + + //nolint:reassign // We need to reassign ErrorHandlers to register our handler + utilruntime.ErrorHandlers = append(utilruntime.ErrorHandlers, func(err error) { + var unknownAuthorityError x509.UnknownAuthorityError + if errors.As(err, &unknownAuthorityError) && lastBadCertificate.Swap(unknownAuthorityError.Cert) != unknownAuthorityError.Cert { + logCertificateError(err, "Certificate error: %s", resource.ToJSON(err)) + } + var certificateInvalidError x509.CertificateInvalidError + if errors.As(err, &certificateInvalidError) && lastBadCertificate.Swap(certificateInvalidError.Cert) != certificateInvalidError.Cert { + logCertificateError(err, "Certificate error: %s", resource.ToJSON(err)) + } + // The generic handler has already logged the error, no need to repeat if we don't want extra detail + }) +}