Skip to content

Commit 98de9ad

Browse files
committed
certwatcher: add metrics to monitor certificate reads
1 parent b1e1a4f commit 98de9ad

File tree

3 files changed

+109
-0
lines changed

3 files changed

+109
-0
lines changed

pkg/certwatcher/certwatcher.go

+3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"sync"
2323

2424
"github.com/fsnotify/fsnotify"
25+
"sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics"
2526
logf "sigs.k8s.io/controller-runtime/pkg/internal/log"
2627
)
2728

@@ -116,8 +117,10 @@ func (cw *CertWatcher) Watch() {
116117
// and updates the current certificate on the watcher. If a callback is set, it
117118
// is invoked with the new certificate.
118119
func (cw *CertWatcher) ReadCertificate() error {
120+
metrics.ReadCertificateTotal.Inc()
119121
cert, err := tls.LoadX509KeyPair(cw.certPath, cw.keyPath)
120122
if err != nil {
123+
metrics.ReadCertificateErrors.Inc()
121124
return err
122125
}
123126

pkg/certwatcher/certwatcher_test.go

+61
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,17 @@ import (
2323
"crypto/x509"
2424
"crypto/x509/pkix"
2525
"encoding/pem"
26+
"fmt"
2627
"math/big"
2728
"net"
2829
"os"
2930
"time"
3031

3132
. "github.com/onsi/ginkgo"
3233
. "github.com/onsi/gomega"
34+
"github.com/prometheus/client_golang/prometheus/testutil"
3335
"sigs.k8s.io/controller-runtime/pkg/certwatcher"
36+
"sigs.k8s.io/controller-runtime/pkg/certwatcher/metrics"
3437
)
3538

3639
var _ = Describe("CertWatcher", func() {
@@ -109,6 +112,64 @@ var _ = Describe("CertWatcher", func() {
109112
ctxCancel()
110113
Eventually(doneCh, "4s").Should(BeClosed())
111114
})
115+
116+
Context("prometheus metric read_certificate_total", func() {
117+
var readCertificateTotalBefore float64
118+
var readCertificateErrorsBefore float64
119+
120+
BeforeEach(func() {
121+
readCertificateTotalBefore = testutil.ToFloat64(metrics.ReadCertificateTotal)
122+
readCertificateErrorsBefore = testutil.ToFloat64(metrics.ReadCertificateErrors)
123+
})
124+
125+
It("should get updated on successful certificate read", func() {
126+
doneCh := startWatcher()
127+
128+
Eventually(func() error {
129+
readCertificateTotalAfter := testutil.ToFloat64(metrics.ReadCertificateTotal)
130+
if readCertificateTotalAfter != readCertificateTotalBefore+1.0 {
131+
return fmt.Errorf("metric read certificate total expected: %v and got: %v", readCertificateTotalBefore+1.0, readCertificateTotalAfter)
132+
}
133+
return nil
134+
}, "4s").Should(Succeed())
135+
136+
ctxCancel()
137+
Eventually(doneCh, "4s").Should(BeClosed())
138+
})
139+
140+
It("should get updated on read certificate errors", func() {
141+
doneCh := startWatcher()
142+
143+
Eventually(func() error {
144+
readCertificateTotalAfter := testutil.ToFloat64(metrics.ReadCertificateTotal)
145+
if readCertificateTotalAfter != readCertificateTotalBefore+1.0 {
146+
return fmt.Errorf("metric read certificate total expected: %v and got: %v", readCertificateTotalBefore+1.0, readCertificateTotalAfter)
147+
}
148+
readCertificateTotalBefore = readCertificateTotalAfter
149+
return nil
150+
}, "4s").Should(Succeed())
151+
152+
Expect(os.Remove(keyPath)).To(BeNil())
153+
154+
Eventually(func() error {
155+
readCertificateTotalAfter := testutil.ToFloat64(metrics.ReadCertificateTotal)
156+
if readCertificateTotalAfter != readCertificateTotalBefore+1.0 {
157+
return fmt.Errorf("metric read certificate total expected: %v and got: %v", readCertificateTotalBefore+1.0, readCertificateTotalAfter)
158+
}
159+
return nil
160+
}, "4s").Should(Succeed())
161+
Eventually(func() error {
162+
readCertificateErrorsAfter := testutil.ToFloat64(metrics.ReadCertificateErrors)
163+
if readCertificateErrorsAfter != readCertificateErrorsBefore+1.0 {
164+
return fmt.Errorf("metric read certificate errors expected: %v and got: %v", readCertificateErrorsBefore+1.0, readCertificateErrorsAfter)
165+
}
166+
return nil
167+
}, "4s").Should(Succeed())
168+
169+
ctxCancel()
170+
Eventually(doneCh, "4s").Should(BeClosed())
171+
})
172+
})
112173
})
113174
})
114175

pkg/certwatcher/metrics/metrics.go

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
Copyright 2022 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package metrics
18+
19+
import (
20+
"github.com/prometheus/client_golang/prometheus"
21+
"sigs.k8s.io/controller-runtime/pkg/metrics"
22+
)
23+
24+
var (
25+
// ReadCertificateTotal is a prometheus counter metrics which holds the total
26+
// number of certificate reads.
27+
ReadCertificateTotal = prometheus.NewCounter(prometheus.CounterOpts{
28+
Name: "certwatcher_read_certificate_total",
29+
Help: "Total number of certificate reads",
30+
})
31+
32+
// ReadCertificateErrors is a prometheus counter metrics which holds the total
33+
// number of errors from certificate read.
34+
ReadCertificateErrors = prometheus.NewCounter(prometheus.CounterOpts{
35+
Name: "certwatcher_read_certificate_errors_total",
36+
Help: "Total number of certificate read errors",
37+
})
38+
)
39+
40+
func init() {
41+
metrics.Registry.MustRegister(
42+
ReadCertificateTotal,
43+
ReadCertificateErrors,
44+
)
45+
}

0 commit comments

Comments
 (0)