Skip to content

Commit 4b40b7e

Browse files
authored
chore: refactor and add unit tests to watcher (#1253)
Signed-off-by: realanna <[email protected]>
1 parent 1dfd653 commit 4b40b7e

19 files changed

+1057
-42
lines changed

.sonarcloud.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
sonar.projectKey=keptn_lifecycle-toolkit
22
sonar.projectName=lifecycle-toolkit
3-
sonar.cpd.exclusions=**/test_*.go,\
3+
sonar.cpd.exclusions= **/*_test.go,\
44
scheduler/test/e2e/fake/**/*.go,\
55
operator/apis/lifecycle/v1alpha1/**/*.go,\
66
operator/apis/lifecycle/v1alpha2/**/*.go,\

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,13 @@ $(HELMIFY): $(LOCALBIN)
3333
.PHONY: integration-test #these tests should run on a real cluster!
3434
integration-test: # to run a single test by name use --test eg. --test=expose-keptn-metric
3535
kubectl kuttl test --start-kind=false ./test/integration/ --config=kuttl-test.yaml
36+
kubectl kuttl test --start-kind=false ./test/testcertificate/ --config=kuttl-test.yaml
37+
3638

3739
.PHONY: integration-test-local #these tests should run on a real cluster!
3840
integration-test-local: install-prometheus
3941
kubectl kuttl test --start-kind=false ./test/integration/ --config=kuttl-test-local.yaml
42+
kubectl kuttl test --start-kind=false ./test/testcertificate/ --config=kuttl-test-local.yaml
4043

4144
.PHONY: load-test
4245
load-test:
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package certificates
2+
3+
import (
4+
"crypto/x509"
5+
"encoding/pem"
6+
)
7+
8+
//go:generate moq -pkg fake -skip-ensure -out ./fake/certificatehandler_mock.go . ICertificateHandler
9+
type ICertificateHandler interface {
10+
Decode(data []byte) (p *pem.Block, rest []byte)
11+
Parse(der []byte) (*x509.Certificate, error)
12+
}
13+
14+
type defaultCertificateHandler struct {
15+
}
16+
17+
func (c defaultCertificateHandler) Decode(data []byte) (p *pem.Block, rest []byte) {
18+
return pem.Decode(data)
19+
}
20+
func (c defaultCertificateHandler) Parse(der []byte) (*x509.Certificate, error) {
21+
return x509.ParseCertificate(der)
22+
}

metrics-operator/cmd/certificates/fake/certificatehandler_mock.go

Lines changed: 116 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

metrics-operator/cmd/certificates/watcher.go

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ package certificates
33
import (
44
"bytes"
55
"context"
6-
"crypto/x509"
7-
"encoding/pem"
86
"errors"
97
"fmt"
108
"os"
@@ -16,13 +14,13 @@ import (
1614
corev1 "k8s.io/api/core/v1"
1715
k8serrors "k8s.io/apimachinery/pkg/api/errors"
1816
"sigs.k8s.io/controller-runtime/pkg/client"
19-
"sigs.k8s.io/controller-runtime/pkg/manager"
2017
)
2118

2219
const (
2320
certificateRenewalInterval = 6 * time.Hour
2421
ServerKey = "tls.key"
2522
ServerCert = "tls.crt"
23+
CertThreshold = 5 * time.Minute
2624
)
2725

2826
type CertificateWatcher struct {
@@ -31,16 +29,20 @@ type CertificateWatcher struct {
3129
certificateDirectory string
3230
namespace string
3331
certificateSecretName string
34-
Log logr.Logger
32+
certificateTreshold time.Duration
33+
ICertificateHandler
34+
Log logr.Logger
3535
}
3636

37-
func NewCertificateWatcher(mgr manager.Manager, namespace string, secretName string, log logr.Logger) *CertificateWatcher {
37+
func NewCertificateWatcher(reader client.Reader, certDir string, namespace string, secretName string, log logr.Logger) *CertificateWatcher {
3838
return &CertificateWatcher{
39-
apiReader: mgr.GetAPIReader(),
39+
apiReader: reader,
4040
fs: afero.NewOsFs(),
41-
certificateDirectory: mgr.GetWebhookServer().CertDir,
41+
certificateDirectory: certDir,
4242
namespace: namespace,
4343
certificateSecretName: secretName,
44+
ICertificateHandler: defaultCertificateHandler{},
45+
certificateTreshold: CertThreshold,
4446
Log: log,
4547
}
4648
}
@@ -75,7 +77,7 @@ func (watcher *CertificateWatcher) updateCertificatesFromSecret() error {
7577
}
7678

7779
for _, filename := range []string{ServerCert, ServerKey} {
78-
if _, err = watcher.ensureCertificateFile(secret, filename); err != nil {
80+
if err = watcher.ensureCertificateFile(secret, filename); err != nil {
7981
return err
8082
}
8183
}
@@ -88,22 +90,18 @@ func (watcher *CertificateWatcher) updateCertificatesFromSecret() error {
8890
return nil
8991
}
9092

91-
func (watcher *CertificateWatcher) ensureCertificateFile(secret corev1.Secret, filename string) (bool, error) {
93+
func (watcher *CertificateWatcher) ensureCertificateFile(secret corev1.Secret, filename string) error {
9294
f := filepath.Join(watcher.certificateDirectory, filename)
93-
9495
data, err := afero.ReadFile(watcher.fs, f)
9596
if os.IsNotExist(err) || !bytes.Equal(data, secret.Data[filename]) {
96-
if err := afero.WriteFile(watcher.fs, f, secret.Data[filename], 0666); err != nil {
97-
return false, err
98-
}
99-
} else {
100-
return false, err
97+
return afero.WriteFile(watcher.fs, f, secret.Data[filename], 0666)
10198
}
102-
return true, nil
99+
return err
100+
103101
}
104102

105103
func (watcher *CertificateWatcher) WaitForCertificates() {
106-
for threshold := time.Now().Add(5 * time.Minute); time.Now().Before(threshold); {
104+
for threshold := time.Now().Add(watcher.certificateTreshold); time.Now().Before(threshold); {
107105

108106
if err := watcher.updateCertificatesFromSecret(); err != nil {
109107
if k8serrors.IsNotFound(err) {
@@ -120,10 +118,10 @@ func (watcher *CertificateWatcher) WaitForCertificates() {
120118
}
121119

122120
func (watcher *CertificateWatcher) ValidateCertificateExpiration(certData []byte, renewalThreshold time.Duration, now time.Time) (bool, error) {
123-
if block, _ := pem.Decode(certData); block == nil {
121+
if block, _ := watcher.Decode(certData); block == nil {
124122
watcher.Log.Error(errors.New("can't decode PEM file"), "failed to parse certificate")
125123
return false, nil
126-
} else if cert, err := x509.ParseCertificate(block.Bytes); err != nil {
124+
} else if cert, err := watcher.Parse(block.Bytes); err != nil {
127125
watcher.Log.Error(err, "failed to parse certificate")
128126
return false, err
129127
} else if now.After(cert.NotAfter.Add(-renewalThreshold)) {

0 commit comments

Comments
 (0)