Skip to content

Commit e83745a

Browse files
m-messiahk8s-infra-cherrypick-robot
authored andcommitted
Reestablish watch for the certificate paths
1 parent bfd1cf9 commit e83745a

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

pkg/certwatcher/certwatcher.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
kerrors "k8s.io/apimachinery/pkg/util/errors"
2828
"k8s.io/apimachinery/pkg/util/sets"
2929
"k8s.io/apimachinery/pkg/util/wait"
30+
3031
"sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics"
3132
logf "sigs.k8s.io/controller-runtime/pkg/internal/log"
3233
)
@@ -120,8 +121,31 @@ func (cw *CertWatcher) Start(ctx context.Context) error {
120121
return cw.watcher.Close()
121122
}
122123

124+
func (cw *CertWatcher) ensureAllFilesAreWatched() {
125+
watchList := sets.New(cw.watcher.WatchList()...)
126+
difference := sets.New(cw.certPath, cw.keyPath).Difference(watchList)
127+
if difference.Len() == 0 {
128+
return
129+
}
130+
131+
for _, missingWatchPath := range difference.UnsortedList() {
132+
log.V(1).Info("re-adding missing watch", "path", missingWatchPath)
133+
if err := cw.watcher.Add(missingWatchPath); err != nil {
134+
log.Error(err, "failed to add watch", "path", missingWatchPath)
135+
return
136+
}
137+
}
138+
139+
log.V(1).Info("all files are watched again", "list", cw.watcher.WatchList())
140+
141+
if err := cw.ReadCertificate(); err != nil {
142+
log.Error(err, "error re-reading certificate")
143+
}
144+
}
145+
123146
// Watch reads events from the watcher's channel and reacts to changes.
124147
func (cw *CertWatcher) Watch() {
148+
watcherHealthTimer := time.NewTicker(time.Second)
125149
for {
126150
select {
127151
case event, ok := <-cw.watcher.Events:
@@ -139,6 +163,8 @@ func (cw *CertWatcher) Watch() {
139163
}
140164

141165
log.Error(err, "certificate watch error")
166+
case <-watcherHealthTimer.C:
167+
cw.ensureAllFilesAreWatched()
142168
}
143169
}
144170
}

pkg/certwatcher/certwatcher_test.go

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
. "github.com/onsi/ginkgo/v2"
3535
. "github.com/onsi/gomega"
3636
"github.com/prometheus/client_golang/prometheus/testutil"
37+
3738
"sigs.k8s.io/controller-runtime/pkg/certwatcher"
3839
"sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics"
3940
)
@@ -113,7 +114,7 @@ var _ = Describe("CertWatcher", func() {
113114
Eventually(func() bool {
114115
secondcert, _ := watcher.GetCertificate(nil)
115116
first := firstcert.PrivateKey.(*rsa.PrivateKey)
116-
return first.Equal(secondcert.PrivateKey)
117+
return first.Equal(secondcert.PrivateKey) || firstcert.Leaf.SerialNumber == secondcert.Leaf.SerialNumber
117118
}).ShouldNot(BeTrue())
118119

119120
ctxCancel()
@@ -143,14 +144,41 @@ var _ = Describe("CertWatcher", func() {
143144
Eventually(func() bool {
144145
secondcert, _ := watcher.GetCertificate(nil)
145146
first := firstcert.PrivateKey.(*rsa.PrivateKey)
146-
return first.Equal(secondcert.PrivateKey)
147+
return first.Equal(secondcert.PrivateKey) || firstcert.Leaf.SerialNumber == secondcert.Leaf.SerialNumber
147148
}).ShouldNot(BeTrue())
148149

149150
ctxCancel()
150151
Eventually(doneCh, "4s").Should(BeClosed())
151152
Expect(called.Load()).To(BeNumerically(">=", 1))
152153
})
153154

155+
It("should reload currentCert after move out", func() {
156+
doneCh := startWatcher()
157+
called := atomic.Int64{}
158+
watcher.RegisterCallback(func(crt tls.Certificate) {
159+
called.Add(1)
160+
Expect(crt.Certificate).ToNot(BeEmpty())
161+
})
162+
163+
firstcert, _ := watcher.GetCertificate(nil)
164+
165+
Expect(os.Rename(certPath, certPath+".old")).To(Succeed())
166+
Expect(os.Rename(keyPath, keyPath+".old")).To(Succeed())
167+
168+
err := writeCerts(certPath, keyPath, "192.168.0.3")
169+
Expect(err).ToNot(HaveOccurred())
170+
171+
Eventually(func() bool {
172+
secondcert, _ := watcher.GetCertificate(nil)
173+
first := firstcert.PrivateKey.(*rsa.PrivateKey)
174+
return first.Equal(secondcert.PrivateKey) || firstcert.Leaf.SerialNumber == secondcert.Leaf.SerialNumber
175+
}, "10s", "1s").ShouldNot(BeTrue())
176+
177+
ctxCancel()
178+
Eventually(doneCh, "4s").Should(BeClosed())
179+
Expect(called.Load()).To(BeNumerically(">=", 1))
180+
})
181+
154182
Context("prometheus metric read_certificate_total", func() {
155183
var readCertificateTotalBefore float64
156184
var readCertificateErrorsBefore float64

0 commit comments

Comments
 (0)