Przeglądaj źródła

Fix GCP e2e webhook readiness and v2 suite scope

Moritz Johner 2 miesięcy temu
rodzic
commit
e8ccb7ba6a

+ 1 - 1
e2e/framework/addon/eso.go

@@ -214,7 +214,7 @@ func (l *ESO) Install() error {
 		return err
 	}
 
-	return waitForExternalSecretWebhookReady(l.Namespace)
+	return waitForExternalSecretWebhookReady(l.Namespace, l.ReleaseName)
 }
 
 func (l *ESO) Uninstall() error {

+ 1 - 1
e2e/framework/addon/eso_argocd_application.go

@@ -137,7 +137,7 @@ func (c *ArgoCDApplication) Install() error {
 		return fmt.Errorf("failed waiting for argo app to become ready: %w", err)
 	}
 
-	return waitForExternalSecretWebhookReady(c.DestinationNamespace)
+	return waitForExternalSecretWebhookReady(c.DestinationNamespace, c.Name)
 }
 
 // Uninstall removes the chart aswell as the repo.

+ 1 - 1
e2e/framework/addon/eso_flux_helm.go

@@ -127,7 +127,7 @@ func (c *FluxHelmRelease) Install() error {
 		return err
 	}
 
-	return waitForExternalSecretWebhookReady(c.TargetNamespace)
+	return waitForExternalSecretWebhookReady(c.TargetNamespace, c.Name)
 }
 
 // Uninstall removes the chart aswell as the repo.

+ 14 - 4
e2e/framework/addon/webhook.go

@@ -22,6 +22,7 @@ import (
 	"crypto/tls"
 	"fmt"
 	"net/http"
+	"strings"
 	"time"
 
 	. "github.com/onsi/ginkgo/v2"
@@ -31,21 +32,30 @@ import (
 const externalSecretValidationReview = `{"apiVersion":"admission.k8s.io/v1","kind":"AdmissionReview","request":{"uid":"test","kind":{"group":"external-secrets.io","version":"v1","kind":"ExternalSecret"},"resource":{"group":"external-secrets.io","version":"v1","resource":"externalsecrets"},"dryRun":true,"operation":"CREATE","userInfo":{"username":"test","uid":"test","groups":[],"extra":{}}}}`
 
 var (
-	externalSecretWebhookURL = func(namespace string) string {
-		return fmt.Sprintf("https://external-secrets-webhook.%s.svc.cluster.local/validate-external-secrets-io-v1-externalsecret", namespace)
+	externalSecretWebhookURL = func(namespace, releaseName string) string {
+		return fmt.Sprintf("https://%s.%s.svc.cluster.local/validate-external-secrets-io-v1-externalsecret", externalSecretWebhookServiceName(releaseName), namespace)
 	}
 	webhookReadyPollInterval = time.Second
 	webhookReadyTimeout      = 5 * time.Minute
 	webhookReadyContext      = func() context.Context { return GinkgoT().Context() }
 )
 
-func waitForExternalSecretWebhookReady(namespace string) error {
+func externalSecretWebhookServiceName(releaseName string) string {
+	const chartName = "external-secrets"
+	fullName := releaseName
+	if !strings.Contains(releaseName, chartName) {
+		fullName = releaseName + "-" + chartName
+	}
+	return fullName + "-webhook"
+}
+
+func waitForExternalSecretWebhookReady(namespace, releaseName string) error {
 	tr := &http.Transport{
 		// nolint:gosec
 		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
 	}
 	client := &http.Client{Transport: tr}
-	url := externalSecretWebhookURL(namespace)
+	url := externalSecretWebhookURL(namespace, releaseName)
 
 	return wait.PollUntilContextTimeout(webhookReadyContext(), webhookReadyPollInterval, webhookReadyTimeout, true, func(ctx context.Context) (bool, error) {
 		res, err := client.Post(url, "application/json", bytes.NewBufferString(externalSecretValidationReview))

+ 24 - 4
e2e/framework/addon/webhook_test.go

@@ -24,6 +24,26 @@ import (
 	"time"
 )
 
+func TestExternalSecretWebhookURLUsesReleaseName(t *testing.T) {
+	t.Helper()
+
+	got := externalSecretWebhookURL("default", "eso")
+	want := "https://eso-external-secrets-webhook.default.svc.cluster.local/validate-external-secrets-io-v1-externalsecret"
+	if got != want {
+		t.Fatalf("unexpected webhook URL: got %q want %q", got, want)
+	}
+}
+
+func TestExternalSecretWebhookURLUsesHelmFullnameWhenReleaseContainsChartName(t *testing.T) {
+	t.Helper()
+
+	got := externalSecretWebhookURL("external-secrets-system", "external-secrets")
+	want := "https://external-secrets-webhook.external-secrets-system.svc.cluster.local/validate-external-secrets-io-v1-externalsecret"
+	if got != want {
+		t.Fatalf("unexpected webhook URL: got %q want %q", got, want)
+	}
+}
+
 func TestWaitForExternalSecretWebhookReadyRetriesUntilOK(t *testing.T) {
 	t.Helper()
 
@@ -49,12 +69,12 @@ func TestWaitForExternalSecretWebhookReadyRetriesUntilOK(t *testing.T) {
 	}))
 	defer server.Close()
 
-	externalSecretWebhookURL = func(string) string { return server.URL }
+	externalSecretWebhookURL = func(string, string) string { return server.URL }
 	webhookReadyPollInterval = 10 * time.Millisecond
 	webhookReadyTimeout = time.Second
 	webhookReadyContext = context.Background
 
-	if err := waitForExternalSecretWebhookReady("external-secrets-system"); err != nil {
+	if err := waitForExternalSecretWebhookReady("external-secrets-system", "external-secrets"); err != nil {
 		t.Fatalf("waitForExternalSecretWebhookReady returned error: %v", err)
 	}
 	if attempts != 3 {
@@ -81,12 +101,12 @@ func TestWaitForExternalSecretWebhookReadyTimesOut(t *testing.T) {
 	}))
 	defer server.Close()
 
-	externalSecretWebhookURL = func(string) string { return server.URL }
+	externalSecretWebhookURL = func(string, string) string { return server.URL }
 	webhookReadyPollInterval = 10 * time.Millisecond
 	webhookReadyTimeout = 50 * time.Millisecond
 	webhookReadyContext = context.Background
 
-	if err := waitForExternalSecretWebhookReady("external-secrets-system"); err == nil {
+	if err := waitForExternalSecretWebhookReady("external-secrets-system", "external-secrets"); err == nil {
 		t.Fatal("expected waitForExternalSecretWebhookReady to time out")
 	}
 }

+ 21 - 0
e2e/suites/provider/cases/gcp/provider_support_test.go

@@ -17,7 +17,9 @@ limitations under the License.
 package gcp
 
 import (
+	"os"
 	"reflect"
+	"strings"
 	"testing"
 )
 
@@ -68,3 +70,22 @@ func TestGCPAccessConfigMissingEnvComplete(t *testing.T) {
 		t.Fatalf("missingManagedEnv() = %v, want none", got)
 	}
 }
+
+func TestProviderV2NamespacedSuiteDoesNotIncludeWorkloadIdentity(t *testing.T) {
+	t.Parallel()
+
+	content, err := os.ReadFile("provider_v2.go")
+	if err != nil {
+		t.Fatalf("read provider_v2.go: %v", err)
+	}
+
+	for _, forbidden := range []string{
+		"withWorkloadIdentity",
+		"useV2WorkloadIdentity(",
+		"gcp-v2-wi-",
+	} {
+		if strings.Contains(string(content), forbidden) {
+			t.Fatalf("non-managed v2 suite must not include workload identity coverage, found %q", forbidden)
+		}
+	}
+}

+ 0 - 12
e2e/suites/provider/cases/gcp/provider_v2.go

@@ -49,18 +49,6 @@ var _ = Describe("[gcp] v2 namespaced provider", Label("gcp", "secretsmanager",
 				ExpectedValue:      "gcp-v2-static-value",
 			})
 		}, useV2StaticAuth(prov)),
-		framework.Compose(withWorkloadIdentity, f, func(f *framework.Framework) (string, func(*framework.TestCase)) {
-			return common.NamespacedProviderSync(f, common.NamespacedProviderSyncConfig{
-				Description:        "[gcp] should sync through a namespaced Provider using workload identity",
-				ExternalSecretName: "gcp-v2-wi-es",
-				TargetSecretName:   "gcp-v2-wi-target",
-				RemoteKey:          f.MakeRemoteRefKey("gcp-v2-wi-remote"),
-				RemoteSecretValue:  `{"value":"gcp-v2-wi-value"}`,
-				RemoteProperty:     "value",
-				SecretKey:          "value",
-				ExpectedValue:      "gcp-v2-wi-value",
-			})
-		}, useV2WorkloadIdentity(prov)),
 		framework.Compose(withStaticAuth, f, func(f *framework.Framework) (string, func(*framework.TestCase)) {
 			return common.NamespacedProviderRefresh(f, common.NamespacedProviderRefreshConfig{
 				Description:         "[gcp] should refresh synced secrets after the remote secret changes",