github.com/operator-framework/operator-lifecycle-manager@v0.30.0/pkg/lib/filemonitor/cert_updater.go (about)

     1  package filemonitor
     2  
     3  import (
     4  	"crypto/tls"
     5  	"crypto/x509"
     6  	"sync"
     7  
     8  	"github.com/fsnotify/fsnotify"
     9  	"github.com/sirupsen/logrus"
    10  )
    11  
    12  type certStore struct {
    13  	mutex      sync.RWMutex
    14  	cert       *tls.Certificate
    15  	tlsCrtPath string
    16  	tlsKeyPath string
    17  }
    18  
    19  // NewCertStore returns a store for storing the certificate data and the ability to retrieve it safely
    20  func NewCertStore(tlsCrt, tlsKey string) (*certStore, error) {
    21  	cert, err := tls.LoadX509KeyPair(tlsCrt, tlsKey)
    22  	if err != nil {
    23  		return nil, err
    24  	}
    25  	return &certStore{
    26  		mutex:      sync.RWMutex{},
    27  		cert:       &cert,
    28  		tlsCrtPath: tlsCrt,
    29  		tlsKeyPath: tlsKey,
    30  	}, nil
    31  }
    32  
    33  // HandleFilesystemUpdate is intended to be used as the OnUpdateFn for a watcher
    34  // and expects the certificate files to be in the same directory.
    35  func (k *certStore) HandleFilesystemUpdate(logger logrus.FieldLogger, event fsnotify.Event) {
    36  	switch op := event.Op; op {
    37  	case fsnotify.Create:
    38  		logger.Debugf("got fs event for %v", event.Name)
    39  
    40  		if err := k.storeCertificate(k.tlsCrtPath, k.tlsKeyPath); err != nil {
    41  			// this can happen if both certificates aren't updated at the same
    42  			// time, but it's okay as replacement only occurs with a valid key pair
    43  			logger.Debugf("certificates not in sync: %v", err)
    44  		} else {
    45  			info, err := x509.ParseCertificate(k.cert.Certificate[0])
    46  			if err != nil {
    47  				logger.Debugf("certificates refreshed, but parsing returned error: %v", err)
    48  			} else {
    49  				logger.Debugf("certificates refreshed: Subject=%v NotBefore=%v NotAfter=%v", info.Subject, info.NotBefore, info.NotAfter)
    50  			}
    51  		}
    52  	}
    53  }
    54  
    55  func (k *certStore) storeCertificate(tlsCrt, tlsKey string) error {
    56  	cert, err := tls.LoadX509KeyPair(tlsCrt, tlsKey)
    57  	if err == nil {
    58  		k.mutex.Lock()
    59  		defer k.mutex.Unlock()
    60  		k.cert = &cert
    61  	}
    62  	return err
    63  }
    64  
    65  func (k *certStore) GetCertificate() *tls.Certificate {
    66  	k.mutex.RLock()
    67  	defer k.mutex.RUnlock()
    68  	return k.cert
    69  }