Skip to content

Commit

Permalink
Feature/kyma-project#714 watcher cr tests (kyma-project#795)
Browse files Browse the repository at this point in the history
* controllers/withwatcher: Add Watcher Regression Tests

* watcher_certificate_test.go: Fix Lints

* kyma_controller_test.go: Fix Incomplete Teardown
  • Loading branch information
LeelaChacha authored Aug 14, 2023
1 parent 1d2f998 commit 1c1f391
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 1 deletion.
12 changes: 12 additions & 0 deletions controllers/withwatcher/kyma_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"reflect"
"strings"
"time"

v1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
"github.com/kyma-project/lifecycle-manager/api/v1beta2"
Expand Down Expand Up @@ -45,9 +46,18 @@ var _ = Describe("Kyma with multiple module CRs in remote sync mode", Ordered, f
kymaObjKey := client.ObjectKeyFromObject(kyma)
tlsSecret := createTLSSecret(kymaObjKey)

delete(kyma.ObjectMeta.Annotations, v1beta2.SyncStrategyAnnotation)
registerDefaultLifecycleForKymaWithWatcher(kyma, watcherCrForKyma, tlsSecret, issuer)

It("kyma reconciliation does not install webhook when sync label missing", func() {
Consistently(latestWebhookIsConfigured(suiteCtx, runtimeClient, watcherCrForKyma,
kymaObjKey), 5*time.Second, Interval).ShouldNot(Succeed())
})

It("kyma reconciliation installs watcher with correct webhook config", func() {
kyma.ObjectMeta.Annotations[v1beta2.SyncStrategyAnnotation] = v1beta2.SyncStrategyLocalClient
Expect(controlPlaneClient.Update(suiteCtx, kyma)).To(Succeed())

Eventually(latestWebhookIsConfigured(suiteCtx, runtimeClient, watcherCrForKyma,
kymaObjKey), Timeout, Interval).Should(Succeed())
})
Expand Down Expand Up @@ -120,6 +130,8 @@ func registerDefaultLifecycleForKymaWithWatcher(kyma *v1beta2.Kyma, watcher *v1b
By("Ensuring watcher CR is properly deleted")
Eventually(isWatcherCrDeletionFinished, Timeout, Interval).WithArguments(watcher).
Should(BeTrue())
By("Deleting Cert-Manager Issuer")
Expect(controlPlaneClient.Delete(suiteCtx, issuer)).To(Succeed())
})

BeforeEach(func() {
Expand Down
128 changes: 128 additions & 0 deletions controllers/withwatcher/watcher_certificate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package withwatcher_test

import (
"bytes"
"errors"

certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
"github.com/kyma-project/lifecycle-manager/controllers"
"github.com/kyma-project/lifecycle-manager/pkg/watcher"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"

. "github.com/kyma-project/lifecycle-manager/pkg/testutils"
)

var ErrPrivateKeyNotMatching = errors.New("private Key for the TLS secret doesn't match")

func getCertificate(clnt client.Client, kymaName string) (*certmanagerv1.Certificate, error) {
certificateCR := &certmanagerv1.Certificate{}
err := clnt.Get(suiteCtx,
client.ObjectKey{Name: watcher.ResolveTLSCertName(kymaName), Namespace: istioSystemNs},
certificateCR)
return certificateCR, err
}

func getSecret(clnt client.Client, objKey client.ObjectKey) (*corev1.Secret, error) {
secretCR := &corev1.Secret{}
err := clnt.Get(suiteCtx, objKey, secretCR)
return secretCR, err
}

func certificateExists(clnt client.Client, kymaName string) error {
_, err := getCertificate(clnt, kymaName)
return err
}

func secretExists(clnt client.Client, secretObjKey client.ObjectKey) error {
_, err := getSecret(clnt, secretObjKey)
return err
}

func deleteCertificate(clnt client.Client, kymaName string) error {
certificateCR, err := getCertificate(clnt, kymaName)
if err != nil {
return err
}
err = clnt.Delete(suiteCtx, certificateCR)
return err
}

func deleteSecret(clnt client.Client, secretObjKey client.ObjectKey) error {
secretCR, err := getSecret(clnt, secretObjKey)
if err != nil {
return err
}
err = runtimeClient.Delete(suiteCtx, secretCR)
return err
}

func matchTLSSecretPrivateKey(clnt client.Client, secretObjKey client.ObjectKey, privateKey []byte) error {
secretCR, err := getSecret(clnt, secretObjKey)
if err != nil {
return err
}
if !bytes.Equal(secretCR.Data[corev1.TLSPrivateKeyKey], privateKey) {
return ErrPrivateKeyNotMatching
}
return nil
}

var _ = Describe("Watcher Certificate Configuration in remote sync mode", Ordered, func() {
kyma := NewTestKyma("kyma-remote-sync")

watcherCrForKyma := createWatcherCR("skr-webhook-manager", true)
issuer := NewTestIssuer(istioSystemNs)
kymaObjKey := client.ObjectKeyFromObject(kyma)
tlsSecret := createTLSSecret(kymaObjKey)
skrTLSSecretObjKey := client.ObjectKey{Name: watcher.SkrTLSName, Namespace: controllers.DefaultRemoteSyncNamespace}

registerDefaultLifecycleForKymaWithWatcher(kyma, watcherCrForKyma, tlsSecret, issuer)

It("kyma reconciliation creates Certificate CR on KCP", func() {
Eventually(certificateExists, Timeout, Interval).
WithArguments(controlPlaneClient, kyma.Name).
Should(Succeed())

By("deleting the Certificate CR on KCP")
Expect(deleteCertificate(controlPlaneClient, kyma.Name)).To(Succeed())

By("Certificate CR recreated on KCP")
Eventually(certificateExists, Timeout, Interval).
WithArguments(controlPlaneClient, kyma.Name).
Should(Succeed())
})

It("kyma reconciliation creates Certificate Secret on SKR", func() {
Eventually(secretExists, Timeout, Interval).
WithArguments(runtimeClient, skrTLSSecretObjKey).
Should(Succeed())

By("deleting the Certificate Secret on SKR")
Expect(deleteSecret(runtimeClient, skrTLSSecretObjKey)).To(Succeed())

By("recreated Certificate Secret on SKR")
Eventually(secretExists, Timeout, Interval).
WithArguments(runtimeClient, skrTLSSecretObjKey).
Should(Succeed())
})

It("kyma reconciliation updates existing TLS Secret on SKR", func() {
newKey := "new-pk"

By("changing the TLS secret on KCP")
tlsSecret.Data[corev1.TLSPrivateKeyKey] = []byte(newKey)
Expect(controlPlaneClient.Update(suiteCtx, tlsSecret)).To(Succeed())

By("updates the TLS secret on SKR")
Eventually(matchTLSSecretPrivateKey, Timeout, Interval).
WithArguments(runtimeClient, skrTLSSecretObjKey, []byte(newKey)).
Should(Succeed())
})

AfterAll(func() {
Expect(controlPlaneClient.Delete(suiteCtx, kyma)).To(Succeed())
})
})
2 changes: 1 addition & 1 deletion controllers/withwatcher/watcher_controller_helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const (

//nolint:gochecknoglobals
var (
centralComponents = []string{componentToBeUpdated, "module-manager", componentToBeRemoved}
centralComponents = []string{componentToBeUpdated, componentToBeRemoved}
errRouteNotFound = errors.New("http route is not found")
errHTTPRoutesEmpty = errors.New("empty http routes")
errRouteConfigMismatch = errors.New("http route config mismatch")
Expand Down
23 changes: 23 additions & 0 deletions controllers/withwatcher/watcher_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,20 @@ func allCRsDeleted(_ *istio.Client) error {
return nil
}

func allVirtualServicesDeleted(customIstioClient *istio.Client) error {
for _, component := range centralComponents {
watcherCR, err := getWatcher(component)
if err != nil {
return err
}
err = customIstioClient.RemoveVirtualServiceForCR(suiteCtx, client.ObjectKeyFromObject(watcherCR))
if err != nil {
return err
}
}
return nil
}

func watcherCRIsReady(watcherName string) error {
watcher, err := getWatcher(watcherName)
if err != nil {
Expand Down Expand Up @@ -215,6 +229,15 @@ var _ = Describe("Watcher CR scenarios", Ordered, func() {
expectWatchersAreReady,
nil,
),
Entry("when all VirtualServices are deleted, "+
"expect VirtualServices recreated",
Timeout,
Interval,
allVirtualServicesDeleted,
expectVirtualServiceConfiguredCorrectly,
expectWatchersAreReady,
nil,
),
Entry("when one WatcherCR is deleted, "+
"expect related VirtualService http route removed"+
"and watcher finalizer is removed",
Expand Down

0 comments on commit 1c1f391

Please sign in to comment.