Просмотр исходного кода

test: harden kubernetes v2 provider recovery timing

Signed-off-by: Moritz Johner <beller.moritz@googlemail.com>
Moritz Johner 2 месяцев назад
Родитель
Сommit
a2bd67be64

+ 18 - 7
e2e/suites/provider/cases/kubernetes/clusterprovider_v2.go

@@ -88,13 +88,13 @@ var _ = Describe("[kubernetes] v2 cluster provider", Label("kubernetes", "v2", "
 
 		updateKubernetesProviderServiceAccount(f, s.providerNamespace, s.providerConfigName("manifest-recovery"), "missing-service-account")
 
-		externalSecretName := s.createExternalSecret(clusterProviderName, targetSecretName, remoteSecretName)
+		externalSecretName := s.createExternalSecretWithRefresh(clusterProviderName, targetSecretName, remoteSecretName, time.Hour)
 		s.waitForExternalSecretFailure(externalSecretName)
 		s.expectNoTargetSecret(targetSecretName)
 
 		updateKubernetesProviderServiceAccount(f, s.providerNamespace, s.providerConfigName("manifest-recovery"), s.serviceAccount)
 
-		s.waitForExternalSecretValue(externalSecretName, targetSecretName, "manifest-recovered")
+		s.waitForExternalSecretValueWithin(externalSecretName, targetSecretName, "manifest-recovered", 30*time.Second)
 	})
 
 	It("recovers after repairing cluster provider auth when authenticationScope=ProviderNamespace", func() {
@@ -110,13 +110,13 @@ var _ = Describe("[kubernetes] v2 cluster provider", Label("kubernetes", "v2", "
 
 		updateKubernetesProviderServiceAccount(f, s.providerNamespace, s.providerConfigName("provider-recovery"), "missing-service-account")
 
-		externalSecretName := s.createExternalSecret(clusterProviderName, targetSecretName, remoteSecretName)
+		externalSecretName := s.createExternalSecretWithRefresh(clusterProviderName, targetSecretName, remoteSecretName, time.Hour)
 		s.waitForExternalSecretFailure(externalSecretName)
 		s.expectNoTargetSecret(targetSecretName)
 
 		updateKubernetesProviderServiceAccount(f, s.providerNamespace, s.providerConfigName("provider-recovery"), s.serviceAccount)
 
-		s.waitForExternalSecretValue(externalSecretName, targetSecretName, "provider-recovered")
+		s.waitForExternalSecretValueWithin(externalSecretName, targetSecretName, "provider-recovered", 30*time.Second)
 	})
 
 	It("denies workload namespaces that do not match ClusterProvider conditions", func() {
@@ -230,6 +230,10 @@ func (s *clusterProviderV2Scenario) createRemoteSecret(name, value string) {
 }
 
 func (s *clusterProviderV2Scenario) createExternalSecret(clusterProviderName, targetSecretName, remoteSecretName string) string {
+	return s.createExternalSecretWithRefresh(clusterProviderName, targetSecretName, remoteSecretName, defaultV2RefreshInterval)
+}
+
+func (s *clusterProviderV2Scenario) createExternalSecretWithRefresh(clusterProviderName, targetSecretName, remoteSecretName string, refreshInterval time.Duration) string {
 	externalSecretName := fmt.Sprintf("%s-external-secret", s.namePrefix)
 	Expect(s.f.CRClient.Create(context.Background(), &esv1.ExternalSecret{
 		ObjectMeta: metav1.ObjectMeta{
@@ -237,7 +241,7 @@ func (s *clusterProviderV2Scenario) createExternalSecret(clusterProviderName, ta
 			Namespace: s.workloadNamespace,
 		},
 		Spec: esv1.ExternalSecretSpec{
-			RefreshInterval: &metav1.Duration{Duration: defaultV2RefreshInterval},
+			RefreshInterval: &metav1.Duration{Duration: refreshInterval},
 			SecretStoreRef: esv1.SecretStoreRef{
 				Name: clusterProviderName,
 				Kind: esv1.ClusterProviderKindStr,
@@ -270,6 +274,10 @@ func (s *clusterProviderV2Scenario) createExternalSecret(clusterProviderName, ta
 }
 
 func (s *clusterProviderV2Scenario) waitForExternalSecretValue(externalSecretName, targetSecretName, expectedValue string) {
+	s.waitForExternalSecretValueWithin(externalSecretName, targetSecretName, expectedValue, defaultV2WaitTimeout)
+}
+
+func (s *clusterProviderV2Scenario) waitForExternalSecretValueWithin(externalSecretName, targetSecretName, expectedValue string, timeout time.Duration) {
 	Eventually(func(g Gomega) {
 		var externalSecret esv1.ExternalSecret
 		g.Expect(s.f.CRClient.Get(context.Background(), types.NamespacedName{
@@ -285,8 +293,11 @@ func (s *clusterProviderV2Scenario) waitForExternalSecretValue(externalSecretNam
 			Name:      targetSecretName,
 			Namespace: s.workloadNamespace,
 		}, &syncedSecret)).To(Succeed())
-		g.Expect(syncedSecret.Data["value"]).To(Equal([]byte(expectedValue)))
-	}, defaultV2WaitTimeout, defaultV2PollInterval).Should(Succeed())
+		g.Expect(syncedSecret.Type).To(Equal(corev1.SecretTypeOpaque))
+		g.Expect(syncedSecret.Data).To(Equal(map[string][]byte{
+			"value": []byte(expectedValue),
+		}))
+	}, timeout, defaultV2PollInterval).Should(Succeed())
 }
 
 func (s *clusterProviderV2Scenario) waitForExternalSecretFailure(externalSecretName string) {

+ 26 - 2
e2e/suites/provider/cases/kubernetes/provider_v2.go

@@ -18,6 +18,7 @@ package kubernetes
 
 import (
 	"context"
+	"time"
 
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
@@ -25,6 +26,7 @@ import (
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/apimachinery/pkg/util/wait"
 
 	"github.com/external-secrets/external-secrets-e2e/framework"
 	frameworkv2 "github.com/external-secrets/external-secrets-e2e/framework/v2"
@@ -202,11 +204,11 @@ var _ = Describe("[kubernetes] v2 namespaced provider", Label("kubernetes", "v2"
 				Namespace: f.Namespace.Name,
 			},
 			Spec: esv1.ExternalSecretSpec{
-				RefreshInterval: &metav1.Duration{Duration: defaultV2RefreshInterval},
 				SecretStoreRef: esv1.SecretStoreRef{
 					Name: f.Namespace.Name,
 					Kind: esv1.ProviderKindStr,
 				},
+				RefreshInterval: &metav1.Duration{Duration: time.Hour},
 				Target: esv1.ExternalSecretTarget{
 					Name: "provider-v2-recovery-target",
 				},
@@ -229,7 +231,7 @@ var _ = Describe("[kubernetes] v2 namespaced provider", Label("kubernetes", "v2"
 		repairedProvider := frameworkv2.WaitForProviderConnectionReady(f, f.Namespace.Name, f.Namespace.Name, defaultV2WaitTimeout)
 		Expect(repairedProvider.Status.Capabilities).To(Equal(esv1.ProviderReadWrite))
 
-		_, err := f.WaitForSecretValue(f.Namespace.Name, "provider-v2-recovery-target", &corev1.Secret{
+		_, err := waitForSecretValueWithin(f, 30*time.Second, f.Namespace.Name, "provider-v2-recovery-target", &corev1.Secret{
 			Type: corev1.SecretTypeOpaque,
 			Data: map[string][]byte{
 				"value": []byte("provider-v2-recovered"),
@@ -280,6 +282,28 @@ func waitForExternalSecretReadyStatus(f *framework.Framework, namespace, name st
 	}, defaultV2WaitTimeout, defaultV2PollInterval).Should(Succeed())
 }
 
+func waitForSecretValueWithin(f *framework.Framework, timeout time.Duration, namespace, name string, expected *corev1.Secret) (*corev1.Secret, error) {
+	secret := &corev1.Secret{}
+	err := wait.PollUntilContextTimeout(context.Background(), time.Second, timeout, true, func(ctx context.Context) (bool, error) {
+		err := f.CRClient.Get(context.Background(), types.NamespacedName{
+			Namespace: namespace,
+			Name:      name,
+		}, secret)
+		if apierrors.IsNotFound(err) {
+			return false, nil
+		}
+		if err != nil {
+			return false, err
+		}
+		match, matchErr := Equal(expected.Data).Match(secret.Data)
+		if matchErr != nil {
+			return false, matchErr
+		}
+		return secret.Type == expected.Type && match, nil
+	})
+	return secret, err
+}
+
 func expectSecretToBeAbsent(f *framework.Framework, namespace, name string) {
 	Consistently(func() bool {
 		var secret corev1.Secret