Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 39 additions & 21 deletions certs/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ import (
//
// Manager will automatically reload certificates if the corresponding file changes.
type Manager struct {
lock sync.RWMutex
certificates map[pair]*tls.Certificate // Mapping: certificate file name => TLS certificates
defaultCert pair
duration time.Duration
lock sync.RWMutex
certificates map[pair]*tls.Certificate // Mapping: certificate file name => TLS certificates
defaultCert pair
duration time.Duration
disableAutoReload bool

loadX509KeyPair LoadX509KeyPairFunc
done <-chan struct{}
Expand All @@ -68,7 +69,7 @@ type pair struct {
// The certificate loaded from certFile is considered the default certificate.
// If a client does not send the TLS SNI extension then Manager will return
// this certificate.
func NewManager(ctx context.Context, certFile, keyFile string, loadX509KeyPair LoadX509KeyPairFunc) (manager *Manager, err error) {
func NewManager(ctx context.Context, certFile, keyFile string, loadX509KeyPair LoadX509KeyPairFunc, opts ...func(*Manager)) (manager *Manager, err error) {
Comment on lines -71 to +72
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I choose this option (instead of passing a disableAutoReload parameter) to ensure the API doesn't break. If this isn't an issue, we may want to pass a parameter instead.

certFile, err = filepath.Abs(certFile)
if err != nil {
return nil, err
Expand All @@ -88,12 +89,27 @@ func NewManager(ctx context.Context, certFile, keyFile string, loadX509KeyPair L
done: ctx.Done(),
duration: 1 * time.Minute,
}
for _, opt := range opts {
opt(manager)
}
if err := manager.AddCertificate(certFile, keyFile); err != nil {
return nil, err
}
return manager, nil
}

// WithDisableAutoReload disables automatic reloading
func WithDisableAutoReload() func(*Manager) {
return func(m *Manager) {
m.disableAutoReload = true
}
}

// DisableAutoReload returns if automatic reloading is disabled
func (m *Manager) DisableAutoReload() bool {
return m.disableAutoReload
}

// UpdateReloadDuration set custom symlink reload duration
func (m *Manager) UpdateReloadDuration(t time.Duration) {
if m == nil {
Expand Down Expand Up @@ -171,22 +187,24 @@ func (m *Manager) AddCertificate(certFile, keyFile string) (err error) {
}
m.certificates[p] = &certificate

if certFileIsLink && keyFileIsLink || isk8s {
go m.watchSymlinks(p, m.reloader())
} else {
// Windows doesn't allow for watching file changes but instead allows
// for directory changes only, while we can still watch for changes
// on files on other platforms. Watch parent directory on all platforms
// for simplicity.
events := make(chan notify.EventInfo, 1)

if err = notify.Watch(filepath.Dir(certFile), events, eventWrite...); err != nil {
return err
}
if err = notify.Watch(filepath.Dir(keyFile), events, eventWrite...); err != nil {
return err
if !m.DisableAutoReload() {
if certFileIsLink && keyFileIsLink || isk8s {
go m.watchSymlinks(p, m.reloader())
} else {
// Windows doesn't allow for watching file changes but instead allows
// for directory changes only, while we can still watch for changes
// on files on other platforms. Watch parent directory on all platforms
// for simplicity.
events := make(chan notify.EventInfo, 1)

if err = notify.Watch(filepath.Dir(certFile), events, eventWrite...); err != nil {
return err
}
if err = notify.Watch(filepath.Dir(keyFile), events, eventWrite...); err != nil {
return err
}
go m.watchFileEvents(p, events, m.reloader())
}
go m.watchFileEvents(p, events, m.reloader())
}
return nil
}
Expand All @@ -202,7 +220,7 @@ func (m *Manager) reloader() <-chan struct{} {
// ReloadOnSignal specifies one or more signals that will trigger certificates reloading.
// If called multiple times with the same signal certificates
func (m *Manager) ReloadOnSignal(sig ...os.Signal) {
if m == nil {
if m == nil || m.DisableAutoReload() {
return
}

Expand Down
Loading