diff --git a/cmd/cdi-apiserver/BUILD.bazel b/cmd/cdi-apiserver/BUILD.bazel index b73ab5e388..f4445b6553 100644 --- a/cmd/cdi-apiserver/BUILD.bazel +++ b/cmd/cdi-apiserver/BUILD.bazel @@ -10,7 +10,7 @@ go_library( "//pkg/client/clientset/versioned:go_default_library", "//pkg/common:go_default_library", "//pkg/controller/datavolume:go_default_library", - "//pkg/util/cert/watcher:go_default_library", + "//vendor/sigs.k8s.io/controller-runtime/pkg/certwatcher:go_default_library", "//pkg/util/tls-crypto-watch:go_default_library", "//pkg/version/verflag:go_default_library", "//staging/src/kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1:go_default_library", diff --git a/cmd/cdi-apiserver/apiserver.go b/cmd/cdi-apiserver/apiserver.go index 4a57ac1433..dcd996f306 100644 --- a/cmd/cdi-apiserver/apiserver.go +++ b/cmd/cdi-apiserver/apiserver.go @@ -39,13 +39,13 @@ import ( "sigs.k8s.io/controller-runtime/pkg/cluster" "sigs.k8s.io/controller-runtime/pkg/manager/signals" + "sigs.k8s.io/controller-runtime/pkg/certwatcher" cdiv1 "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1" "kubevirt.io/containerized-data-importer/pkg/apiserver" cdiclient "kubevirt.io/containerized-data-importer/pkg/client/clientset/versioned" "kubevirt.io/containerized-data-importer/pkg/common" dvc "kubevirt.io/containerized-data-importer/pkg/controller/datavolume" - certwatcher "kubevirt.io/containerized-data-importer/pkg/util/cert/watcher" cryptowatch "kubevirt.io/containerized-data-importer/pkg/util/tls-crypto-watch" "kubevirt.io/containerized-data-importer/pkg/version/verflag" ) @@ -189,7 +189,7 @@ func main() { }() go func() { - if err := certWatcher.Start(ctx.Done()); err != nil { + if err := certWatcher.Start(ctx); err != nil { klog.Errorf("cert watcher failed: %v\n", errors.WithStack(err)) } }() diff --git a/cmd/cdi-uploadproxy/BUILD.bazel b/cmd/cdi-uploadproxy/BUILD.bazel index 7aca678e88..576cdf9091 100644 --- a/cmd/cdi-uploadproxy/BUILD.bazel +++ b/cmd/cdi-uploadproxy/BUILD.bazel @@ -10,7 +10,7 @@ go_library( "//pkg/uploadproxy:go_default_library", "//pkg/util:go_default_library", "//pkg/util/cert/fetcher:go_default_library", - "//pkg/util/cert/watcher:go_default_library", + "//vendor/sigs.k8s.io/controller-runtime/pkg/certwatcher:go_default_library", "//pkg/util/tls-crypto-watch:go_default_library", "//vendor/github.com/kelseyhightower/envconfig:go_default_library", "//vendor/github.com/pkg/errors:go_default_library", diff --git a/cmd/cdi-uploadproxy/uploadproxy.go b/cmd/cdi-uploadproxy/uploadproxy.go index bf63d0e307..32fcd12579 100644 --- a/cmd/cdi-uploadproxy/uploadproxy.go +++ b/cmd/cdi-uploadproxy/uploadproxy.go @@ -13,12 +13,12 @@ import ( "k8s.io/klog/v2" "sigs.k8s.io/controller-runtime/pkg/manager/signals" + "sigs.k8s.io/controller-runtime/pkg/certwatcher" cdiclient "kubevirt.io/containerized-data-importer/pkg/client/clientset/versioned" "kubevirt.io/containerized-data-importer/pkg/uploadproxy" "kubevirt.io/containerized-data-importer/pkg/util" certfetcher "kubevirt.io/containerized-data-importer/pkg/util/cert/fetcher" - certwatcher "kubevirt.io/containerized-data-importer/pkg/util/cert/watcher" cryptowatch "kubevirt.io/containerized-data-importer/pkg/util/tls-crypto-watch" ) @@ -123,7 +123,7 @@ func main() { } go func() { - if err := certWatcher.Start(ctx.Done()); err != nil { + if err := certWatcher.Start(ctx); err != nil { klog.Errorf("failed to close certWatcher, %v", err) } if err := ctx.Err(); err != nil { diff --git a/pkg/util/cert/watcher/BUILD.bazel b/pkg/util/cert/watcher/BUILD.bazel deleted file mode 100644 index bac65886bf..0000000000 --- a/pkg/util/cert/watcher/BUILD.bazel +++ /dev/null @@ -1,12 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["certwatcher.go"], - importpath = "kubevirt.io/containerized-data-importer/pkg/util/cert/watcher", - visibility = ["//visibility:public"], - deps = [ - "//vendor/gopkg.in/fsnotify.v1:go_default_library", - "//vendor/k8s.io/klog/v2:go_default_library", - ], -) diff --git a/pkg/util/cert/watcher/certwatcher.go b/pkg/util/cert/watcher/certwatcher.go deleted file mode 100644 index 8fd049be0f..0000000000 --- a/pkg/util/cert/watcher/certwatcher.go +++ /dev/null @@ -1,161 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package watcher - -import ( - "crypto/tls" - "sync" - - "gopkg.in/fsnotify.v1" - - "k8s.io/klog/v2" -) - -// CertWatcher watches certificate and key files for changes. When either file -// changes, it reads and parses both and calls an optional callback with the new -// certificate. -type CertWatcher struct { - sync.Mutex - - currentCert *tls.Certificate - watcher *fsnotify.Watcher - - certPath string - keyPath string -} - -// New returns a new CertWatcher watching the given certificate and key. -func New(certPath, keyPath string) (*CertWatcher, error) { - var err error - - cw := &CertWatcher{ - certPath: certPath, - keyPath: keyPath, - } - - // Initial read of certificate and key. - if err := cw.ReadCertificate(); err != nil { - return nil, err - } - - cw.watcher, err = fsnotify.NewWatcher() - if err != nil { - return nil, err - } - - return cw, nil -} - -// GetCertificate fetches the currently loaded certificate, which may be nil. -func (cw *CertWatcher) GetCertificate(_ *tls.ClientHelloInfo) (*tls.Certificate, error) { - cw.Lock() - defer cw.Unlock() - return cw.currentCert, nil -} - -// Start starts the watch on the certificate and key files. -func (cw *CertWatcher) Start(stopCh <-chan struct{}) error { - files := []string{cw.certPath, cw.keyPath} - - for _, f := range files { - if err := cw.watcher.Add(f); err != nil { - return err - } - } - - go cw.Watch() - - klog.Info("Starting certificate watcher") - - // Block until the stop channel is closed. - <-stopCh - - return cw.watcher.Close() -} - -// Watch reads events from the watcher's channel and reacts to changes. -func (cw *CertWatcher) Watch() { - for { - select { - case event, ok := <-cw.watcher.Events: - // Channel is closed. - if !ok { - return - } - - cw.handleEvent(event) - - case err, ok := <-cw.watcher.Errors: - // Channel is closed. - if !ok { - return - } - - klog.Error(err, "certificate watch error") - } - } -} - -// ReadCertificate reads the certificate and key files from disk, parses them, -// and updates the current certificate on the watcher. If a callback is set, it -// is invoked with the new certificate. -func (cw *CertWatcher) ReadCertificate() error { - cert, err := tls.LoadX509KeyPair(cw.certPath, cw.keyPath) - if err != nil { - return err - } - - cw.Lock() - cw.currentCert = &cert - cw.Unlock() - - klog.Info("Updated current TLS certificate") - - return nil -} - -func (cw *CertWatcher) handleEvent(event fsnotify.Event) { - // Only care about events which may modify the contents of the file. - if !(isWrite(event) || isRemove(event) || isCreate(event)) { - return - } - - klog.V(1).Info("certificate event", "event", event) - - // If the file was removed, re-add the watch. - if isRemove(event) { - if err := cw.watcher.Add(event.Name); err != nil { - klog.Error(err, "error re-watching file") - } - } - - if err := cw.ReadCertificate(); err != nil { - klog.Error(err, "error re-reading certificate") - } -} - -func isWrite(event fsnotify.Event) bool { - return event.Op&fsnotify.Write == fsnotify.Write -} - -func isCreate(event fsnotify.Event) bool { - return event.Op&fsnotify.Create == fsnotify.Create -} - -func isRemove(event fsnotify.Event) bool { - return event.Op&fsnotify.Remove == fsnotify.Remove -}