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 }