From e075e988fae1d8899fbe2fc09ca8671ebd67c2df Mon Sep 17 00:00:00 2001 From: "Nathan J. Mehl" Date: Tue, 4 Feb 2025 13:28:19 -0500 Subject: [PATCH] add prometheus gauge --- pkg/identity/service.go | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/pkg/identity/service.go b/pkg/identity/service.go index aa1c131c18990..7df926954aebe 100644 --- a/pkg/identity/service.go +++ b/pkg/identity/service.go @@ -17,6 +17,8 @@ import ( pb "github.com/linkerd/linkerd2-proxy-api/go/identity" "github.com/linkerd/linkerd2/pkg/tls" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" log "github.com/sirupsen/logrus" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -50,6 +52,8 @@ type ( recordEvent func(parent runtime.Object, eventType, reason, message string) expectedName, issuerPathCrt, issuerPathKey string + issuerCertExpiration time.Time + issuerCertExpireGauge prometheus.GaugeFunc } // Validator implementors accept a bearer token, validates it, and returns a @@ -92,6 +96,14 @@ func (svc *Service) updateIssuer(newIssuer tls.Issuer) { svc.issuerMutex.Unlock() } +func (svc *Service) getIssuerCertValidityRemaining() float64 { + if svc.issuer == nil { + log.Warn("Certificate issuer is not ready; cannot get expiration") + return float64(0) + } + return time.Now().Sub(svc.issuerCertExpiration).Seconds() +} + // Run reads from the issuer and error channels and reloads the issuer certs when necessary func (svc *Service) Run(issuerEvent <-chan struct{}, issuerError <-chan error) { for { @@ -131,6 +143,8 @@ func (svc *Service) loadCredentials() (tls.Issuer, error) { return nil, fmt.Errorf("failed to verify issuer certificate: it must be an intermediate-CA, but it is not") } + svc.issuerCertExpiration = creds.Certificate.NotAfter + log.Debugf("Loaded issuer cert: %s", creds.EncodeCertificatePEM()) log.WithFields(log.Fields{ "invalid_after": creds.Certificate.NotAfter.Unix(), @@ -141,7 +155,8 @@ func (svc *Service) loadCredentials() (tls.Issuer, error) { // NewService creates a new identity service. func NewService(validator Validator, trustAnchors *x509.CertPool, validity *tls.Validity, recordEvent func(parent runtime.Object, eventType, reason, message string), expectedName, issuerPathCrt, issuerPathKey string) *Service { - return &Service{ + + svc := &Service{ pb.UnimplementedIdentityServer{}, validator, trustAnchors, @@ -152,7 +167,16 @@ func NewService(validator Validator, trustAnchors *x509.CertPool, validity *tls. expectedName, issuerPathCrt, issuerPathKey, + time.Time{}, + nil, } + + issuerCertExpireGauge := promauto.NewGaugeFunc(prometheus.GaugeOpts{ + Name: "issuer_cert_remaining_seconds", + Help: "The remaining seconds until the issuer certificate expires", + }, svc.getIssuerCertValidityRemaining) + svc.issuerCertExpireGauge = issuerCertExpireGauge + return svc } // Register registers an identity service implementation in the provided gRPC