Skip to content

Commit 7c103b6

Browse files
Merge pull request #1155 from bryan-cox/HOSTEDCP-1994
HOSTEDCP-1994: Add filewatcher for Azure client certificate authentication
2 parents 4c7e4ef + 2ddc416 commit 7c103b6

File tree

8 files changed

+73
-385
lines changed

8 files changed

+73
-385
lines changed

go.mod

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ require (
5050
k8s.io/apimachinery v0.30.1
5151
k8s.io/client-go v0.30.1
5252
k8s.io/klog/v2 v2.120.1
53-
k8s.io/kubernetes v1.30.2
5453
k8s.io/utils v0.0.0-20230726121419-3b25d923346b
5554
)
5655

go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,8 +1721,6 @@ k8s.io/kube-aggregator v0.30.1 h1:ymR2BsxDacTKwzKTuNhGZttuk009c+oZbSeD+IPX5q4=
17211721
k8s.io/kube-aggregator v0.30.1/go.mod h1:SFbqWsM6ea8dHd3mPLsZFzJHbjBOS5ykIgJh4znZ5iQ=
17221722
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
17231723
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
1724-
k8s.io/kubernetes v1.30.2 h1:11WhS78OYX/lnSy6TXxPO6Hk+E5K9ZNrEsk9JgMSX8I=
1725-
k8s.io/kubernetes v1.30.2/go.mod h1:yPbIk3MhmhGigX62FLJm+CphNtjxqCvAIFQXup6RKS0=
17261724
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
17271725
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
17281726
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=

pkg/filewatcher/filewatcher.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package filewatcher
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"sync"
7+
8+
"github.com/fsnotify/fsnotify"
9+
"k8s.io/klog/v2"
10+
)
11+
12+
var watchCertificateFileOnce sync.Once
13+
14+
// WatchFileForChanges watches the file, fileToWatch, for changes. If the file contents have changed, the pod this
15+
// function is running on will be restarted.
16+
func WatchFileForChanges(fileToWatch string) error {
17+
var err error
18+
19+
// This starts only one occurrence of the file watcher, which watches the file, fileToWatch.
20+
watchCertificateFileOnce.Do(func() {
21+
klog.Infof("Starting the file change watcher on file, %s", fileToWatch)
22+
23+
// Update the file path to watch in case this is a symlink
24+
fileToWatch, err = filepath.EvalSymlinks(fileToWatch)
25+
if err != nil {
26+
return
27+
}
28+
klog.Infof("Watching file, %s", fileToWatch)
29+
30+
// Start the file watcher to monitor file changes
31+
go func() {
32+
err = checkForFileChanges(fileToWatch)
33+
}()
34+
})
35+
return err
36+
}
37+
38+
// checkForFileChanges starts a new file watcher. If the file is changed, the pod running this function will exit.
39+
func checkForFileChanges(path string) error {
40+
watcher, err := fsnotify.NewWatcher()
41+
if err != nil {
42+
return err
43+
}
44+
45+
go func() {
46+
for {
47+
select {
48+
case event, ok := <-watcher.Events:
49+
if ok && (event.Has(fsnotify.Write) || event.Has(fsnotify.Chmod) || event.Has(fsnotify.Remove)) {
50+
klog.Infof("file, %s, was modified, exiting...", event.Name)
51+
os.Exit(0)
52+
}
53+
case err, ok := <-watcher.Errors:
54+
if ok {
55+
klog.Errorf("file watcher error: %v", err)
56+
}
57+
}
58+
}
59+
}()
60+
61+
err = watcher.Add(path)
62+
if err != nil {
63+
return err
64+
}
65+
66+
return nil
67+
}

pkg/storage/azure/azure.go

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import (
2929
"k8s.io/apimachinery/pkg/util/rand"
3030
kcorelisters "k8s.io/client-go/listers/core/v1"
3131
"k8s.io/klog/v2"
32-
"k8s.io/kubernetes/pkg/util/interrupt"
3332

3433
configv1 "github.com/openshift/api/config/v1"
3534
imageregistryv1 "github.com/openshift/api/imageregistry/v1"
@@ -39,6 +38,7 @@ import (
3938
regopclient "github.com/openshift/cluster-image-registry-operator/pkg/client"
4039
"github.com/openshift/cluster-image-registry-operator/pkg/defaults"
4140
"github.com/openshift/cluster-image-registry-operator/pkg/envvar"
41+
"github.com/openshift/cluster-image-registry-operator/pkg/filewatcher"
4242
"github.com/openshift/cluster-image-registry-operator/pkg/storage/azure/azureclient"
4343
"github.com/openshift/cluster-image-registry-operator/pkg/storage/util"
4444
)
@@ -395,18 +395,8 @@ func (d *driver) storageAccountsClient(cfg *Azure, environment autorestazure.Env
395395
return storage.AccountsClient{}, fmt.Errorf(`failed to parse certificate data "%s": %v`, certPath, err)
396396
}
397397

398-
// Set up a watch on our config file; if it changes, we should exit -
399-
// (we don't have the ability to dynamically reload config changes).
400-
stopCh := make(chan struct{})
401-
err = interrupt.New(func(s os.Signal) {
402-
_, _ = fmt.Fprintf(os.Stderr, "interrupt: Gracefully shutting down ...\n")
403-
close(stopCh)
404-
}).Run(func() error {
405-
if err := azureclient.WatchForChanges(certPath, stopCh); err != nil {
406-
return err
407-
}
408-
return nil
409-
})
398+
// Watch the certificate for changes; if the certificate changes, the pod will be restarted
399+
err = filewatcher.WatchFileForChanges(certPath)
410400
if err != nil {
411401
return storage.AccountsClient{}, err
412402
}

pkg/storage/azure/azureclient/azureclient.go

Lines changed: 3 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"fmt"
77
"net/http"
88
"os"
9-
"path/filepath"
109
"strings"
1110

1211
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
@@ -22,9 +21,8 @@ import (
2221
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container"
2322
autorestazure "github.com/Azure/go-autorest/autorest/azure"
2423
"github.com/Azure/go-autorest/autorest/to"
25-
"github.com/fsnotify/fsnotify"
24+
"github.com/openshift/cluster-image-registry-operator/pkg/filewatcher"
2625
"k8s.io/klog/v2"
27-
"k8s.io/kubernetes/pkg/util/interrupt"
2826
)
2927

3028
const (
@@ -130,18 +128,8 @@ func (c *Client) getCreds() (azcore.TokenCredential, error) {
130128
return nil, fmt.Errorf(`failed to parse certificate data "%s": %v`, certPath, err)
131129
}
132130

133-
// Set up a watch on our config file; if it changes, we should exit -
134-
// (we don't have the ability to dynamically reload config changes).
135-
stopCh := make(chan struct{})
136-
err = interrupt.New(func(s os.Signal) {
137-
_, _ = fmt.Fprintf(os.Stderr, "interrupt: Gracefully shutting down ...\n")
138-
close(stopCh)
139-
}).Run(func() error {
140-
if err := WatchForChanges(certPath, stopCh); err != nil {
141-
return err
142-
}
143-
return nil
144-
})
131+
// Watch the certificate for changes; if the certificate changes, the pod will be restarted
132+
err = filewatcher.WatchFileForChanges(certPath)
145133
if err != nil {
146134
return nil, err
147135
}
@@ -939,59 +927,3 @@ func (client *BlobClient) DeleteStorageContainer(ctx context.Context, containerN
939927
_, err := client.client.DeleteContainer(ctx, containerName, &azblob.DeleteContainerOptions{})
940928
return err
941929
}
942-
943-
// WatchForChanges closes stopCh if the configuration file changed.
944-
func WatchForChanges(configPath string, stopCh chan struct{}) error {
945-
configPath, err := filepath.Abs(configPath)
946-
if err != nil {
947-
return err
948-
}
949-
watcher, err := fsnotify.NewWatcher()
950-
if err != nil {
951-
return err
952-
}
953-
// Watch all symlinks for changes
954-
p := configPath
955-
maxDepth := 100
956-
for depth := 0; depth < maxDepth; depth++ {
957-
if err := watcher.Add(p); err != nil {
958-
return err
959-
}
960-
klog.V(2).Infof("Watching config file %s for changes", p)
961-
stat, err := os.Lstat(p)
962-
if err != nil {
963-
return err
964-
}
965-
// configmaps are usually symlinks
966-
if stat.Mode()&os.ModeSymlink > 0 {
967-
p, err = filepath.EvalSymlinks(p)
968-
if err != nil {
969-
return err
970-
}
971-
} else {
972-
break
973-
}
974-
}
975-
go func() {
976-
for {
977-
select {
978-
case <-stopCh:
979-
case event, ok := <-watcher.Events:
980-
if !ok {
981-
klog.Errorf("failed to watch config file %s", p)
982-
return
983-
}
984-
klog.V(2).Infof("Configuration file %s changed, exiting...", event.Name)
985-
close(stopCh)
986-
return
987-
case err, ok := <-watcher.Errors:
988-
if !ok {
989-
klog.Errorf("failed to watch config file %s", p)
990-
return
991-
}
992-
klog.Errorf("fsnotify error: %v", err)
993-
}
994-
}
995-
}()
996-
return nil
997-
}

0 commit comments

Comments
 (0)