foundationdb/fdbkubernetesmonitor/internal/certloader/certloader.go

57 lines
1.9 KiB
Go

package certloader
import (
"crypto/tls"
"fmt"
"os"
"time"
"github.com/go-logr/logr"
)
// CertLoader is used to reload certificates if needed.
type CertLoader struct {
// CertFile specifies the path to the x509 certificate.
CertFile string
// CertFile specifies the path to the x509 private key.
KeyFile string
// cachedCert will cache the loaded certificate key pair.
cachedCert *tls.Certificate
// cachedCertModTime is used to track the last modification time of the key file.
cachedCertModTime time.Time
// logger is the logger for logging.
logger logr.Logger
}
// NewCertLoader creates a new CertLoader.
func NewCertLoader(logger logr.Logger, certFile string, keyFile string) *CertLoader {
return &CertLoader{
CertFile: certFile,
KeyFile: keyFile,
logger: logger.WithName("CertLoader"),
}
}
// GetCertificate returns the certificate for the TLS requests and will return the cached certificate if the file has not been changed.
func (certLoader *CertLoader) GetCertificate(_ *tls.ClientHelloInfo) (*tls.Certificate, error) {
stat, err := os.Stat(certLoader.KeyFile)
if err != nil {
err = fmt.Errorf("failed checking key file: %s modification time: %w", certLoader.KeyFile, err)
certLoader.logger.Error(err, "could not load information from key file", "certFile", certLoader.CertFile, "keyFile", certLoader.KeyFile)
return nil, err
}
if certLoader.cachedCert == nil || stat.ModTime().After(certLoader.cachedCertModTime) {
certLoader.logger.Info("loading new certificates", "certFile", certLoader.CertFile, "keyFile", certLoader.KeyFile, "cachedModificationTime", certLoader.cachedCertModTime.String(), "currentModificationTime", stat.ModTime().String())
pair, err := tls.LoadX509KeyPair(certLoader.CertFile, certLoader.KeyFile)
if err != nil {
return nil, fmt.Errorf("failed loading tls key pair: %w", err)
}
certLoader.cachedCert = &pair
certLoader.cachedCertModTime = stat.ModTime()
}
return certLoader.cachedCert, nil
}