Browse Source

e2e: harden v2 fake provider mutator behavior

Moritz Johner 2 months ago
parent
commit
ed9b3c0161
2 changed files with 252 additions and 50 deletions
  1. 88 34
      e2e/framework/addon/eso_v2_mutators.go
  2. 164 16
      e2e/framework/addon/eso_v2_mutators_test.go

+ 88 - 34
e2e/framework/addon/eso_v2_mutators.go

@@ -16,7 +16,11 @@ limitations under the License.
 
 package addon
 
-import "os"
+import (
+	"os"
+	"strconv"
+	"strings"
+)
 
 const (
 	v2HelmNamespace   = "external-secrets-system"
@@ -35,44 +39,15 @@ func WithV2Namespace() MutationFunc {
 
 func WithV2KubernetesProvider() MutationFunc {
 	return func(eso *ESO) {
-		version := os.Getenv("VERSION")
-		vars := []StringTuple{
-			{Key: "replicaCount", Value: "1"},
-			{Key: "v2.enabled", Value: "true"},
-			{Key: "crds.createProvider", Value: "true"},
-			{Key: "crds.createClusterProvider", Value: "true"},
-			{Key: "providers.enabled", Value: "true"},
-			{Key: "providerDefaults.replicaCount", Value: "1"},
-			{Key: "providers.list[0].name", Value: "kubernetes"},
-			{Key: "providers.list[0].type", Value: "kubernetes"},
-			{Key: "providers.list[0].enabled", Value: "true"},
-			{Key: "providers.list[0].replicaCount", Value: "1"},
-			{Key: "providers.list[0].image.repository", Value: "ghcr.io/external-secrets/provider-kubernetes"},
-			{Key: "providers.list[0].image.tag", Value: version},
-			{Key: "providers.list[0].image.pullPolicy", Value: "IfNotPresent"},
-		}
-		for _, variable := range vars {
-			setOrAppendVar(eso.HelmChart, variable)
-		}
+		ensureV2ProviderConfig(eso.HelmChart)
+		setProvider(eso.HelmChart, "kubernetes", "kubernetes", "ghcr.io/external-secrets/provider-kubernetes", os.Getenv("VERSION"))
 	}
 }
 
 func WithV2FakeProvider() MutationFunc {
 	return func(eso *ESO) {
-		version := os.Getenv("VERSION")
-		vars := []StringTuple{
-			{Key: "providers.enabled", Value: "true"},
-			{Key: "providers.list[1].name", Value: "fake"},
-			{Key: "providers.list[1].type", Value: "fake"},
-			{Key: "providers.list[1].enabled", Value: "true"},
-			{Key: "providers.list[1].replicaCount", Value: "1"},
-			{Key: "providers.list[1].image.repository", Value: "ghcr.io/external-secrets/provider-fake"},
-			{Key: "providers.list[1].image.tag", Value: version},
-			{Key: "providers.list[1].image.pullPolicy", Value: "IfNotPresent"},
-		}
-		for _, variable := range vars {
-			setOrAppendVar(eso.HelmChart, variable)
-		}
+		ensureV2ProviderConfig(eso.HelmChart)
+		setProvider(eso.HelmChart, "fake", "fake", "ghcr.io/external-secrets/provider-fake", os.Getenv("VERSION"))
 	}
 }
 
@@ -86,6 +61,85 @@ func setOrAppendVar(chart *HelmChart, variable StringTuple) {
 	chart.Vars = append(chart.Vars, variable)
 }
 
+func ensureV2ProviderConfig(chart *HelmChart) {
+	vars := []StringTuple{
+		{Key: "replicaCount", Value: "1"},
+		{Key: "v2.enabled", Value: "true"},
+		{Key: "crds.createProvider", Value: "true"},
+		{Key: "crds.createClusterProvider", Value: "true"},
+		{Key: "providers.enabled", Value: "true"},
+		{Key: "providerDefaults.replicaCount", Value: "1"},
+	}
+	for _, variable := range vars {
+		setOrAppendVar(chart, variable)
+	}
+}
+
+func setProvider(chart *HelmChart, name, providerType, imageRepository, imageTag string) {
+	index := findProviderIndex(chart, name)
+	if index < 0 {
+		index = nextProviderIndex(chart)
+	}
+
+	prefix := "providers.list[" + strconv.Itoa(index) + "]"
+	vars := []StringTuple{
+		{Key: prefix + ".name", Value: name},
+		{Key: prefix + ".type", Value: providerType},
+		{Key: prefix + ".enabled", Value: "true"},
+		{Key: prefix + ".replicaCount", Value: "1"},
+		{Key: prefix + ".image.repository", Value: imageRepository},
+		{Key: prefix + ".image.tag", Value: imageTag},
+		{Key: prefix + ".image.pullPolicy", Value: "IfNotPresent"},
+	}
+	for _, variable := range vars {
+		setOrAppendVar(chart, variable)
+	}
+}
+
+func findProviderIndex(chart *HelmChart, name string) int {
+	const prefix = "providers.list["
+	const suffix = "].name"
+	for _, variable := range chart.Vars {
+		if !strings.HasPrefix(variable.Key, prefix) || !strings.HasSuffix(variable.Key, suffix) {
+			continue
+		}
+		if variable.Value != name {
+			continue
+		}
+		indexStr := strings.TrimSuffix(strings.TrimPrefix(variable.Key, prefix), suffix)
+		index, err := strconv.Atoi(indexStr)
+		if err == nil {
+			return index
+		}
+	}
+	return -1
+}
+
+func nextProviderIndex(chart *HelmChart) int {
+	const prefix = "providers.list["
+	maxIndex := -1
+	for _, variable := range chart.Vars {
+		if !strings.HasPrefix(variable.Key, prefix) {
+			continue
+		}
+
+		remainder := strings.TrimPrefix(variable.Key, prefix)
+		closingBracket := strings.Index(remainder, "]")
+		if closingBracket < 0 {
+			continue
+		}
+
+		index, err := strconv.Atoi(remainder[:closingBracket])
+		if err != nil {
+			continue
+		}
+		if index > maxIndex {
+			maxIndex = index
+		}
+	}
+	return maxIndex + 1
+}
+
 func containsArg(args []string, target string) bool {
 	for _, arg := range args {
 		if arg == target {

+ 164 - 16
e2e/framework/addon/eso_v2_mutators_test.go

@@ -16,21 +16,37 @@ limitations under the License.
 
 package addon
 
-import "testing"
+import (
+	"regexp"
+	"strconv"
+	"strings"
+	"testing"
+)
 
 func TestWithV2FakeProvider(t *testing.T) {
 	t.Setenv("VERSION", "test-version")
 
 	eso := NewESO(WithV2FakeProvider())
 
+	assertV2ProviderBaseVars(t, eso.HelmChart)
 	assertVarValue(t, eso.HelmChart, "providers.enabled", "true")
-	assertVarValue(t, eso.HelmChart, "providers.list[1].name", "fake")
-	assertVarValue(t, eso.HelmChart, "providers.list[1].type", "fake")
-	assertVarValue(t, eso.HelmChart, "providers.list[1].enabled", "true")
-	assertVarValue(t, eso.HelmChart, "providers.list[1].replicaCount", "1")
-	assertVarValue(t, eso.HelmChart, "providers.list[1].image.repository", "ghcr.io/external-secrets/provider-fake")
-	assertVarValue(t, eso.HelmChart, "providers.list[1].image.tag", "test-version")
-	assertVarValue(t, eso.HelmChart, "providers.list[1].image.pullPolicy", "IfNotPresent")
+	assertProvider(
+		t,
+		eso.HelmChart,
+		"fake",
+		"fake",
+		"ghcr.io/external-secrets/provider-fake",
+		"test-version",
+	)
+	assertSequentialProviderIndexes(t, eso.HelmChart)
+
+	providers := providerEntries(t, eso.HelmChart)
+	if len(providers) != 1 {
+		t.Fatalf("expected exactly one provider entry, got %d", len(providers))
+	}
+	if providers[0].Name != "fake" {
+		t.Fatalf("expected fake to be at index 0 when standalone, got index 0 name %q", providers[0].Name)
+	}
 }
 
 func TestWithV2ProvidersCompose(t *testing.T) {
@@ -52,15 +68,25 @@ func TestWithV2ProvidersCompose(t *testing.T) {
 		t.Fatalf("expected --create-namespace arg, got %v", eso.HelmChart.Args)
 	}
 
-	assertVarValue(t, eso.HelmChart, "v2.enabled", "true")
+	assertV2ProviderBaseVars(t, eso.HelmChart)
 	assertVarValue(t, eso.HelmChart, "providers.enabled", "true")
-	assertVarValue(t, eso.HelmChart, "providers.list[0].name", "kubernetes")
-	assertVarValue(t, eso.HelmChart, "providers.list[0].image.repository", "ghcr.io/external-secrets/provider-kubernetes")
-	assertVarValue(t, eso.HelmChart, "providers.list[0].image.tag", "test-version")
-	assertVarValue(t, eso.HelmChart, "providers.list[1].name", "fake")
-	assertVarValue(t, eso.HelmChart, "providers.list[1].type", "fake")
-	assertVarValue(t, eso.HelmChart, "providers.list[1].image.repository", "ghcr.io/external-secrets/provider-fake")
-	assertVarValue(t, eso.HelmChart, "providers.list[1].image.tag", "test-version")
+	assertProvider(
+		t,
+		eso.HelmChart,
+		"kubernetes",
+		"kubernetes",
+		"ghcr.io/external-secrets/provider-kubernetes",
+		"test-version",
+	)
+	assertProvider(
+		t,
+		eso.HelmChart,
+		"fake",
+		"fake",
+		"ghcr.io/external-secrets/provider-fake",
+		"test-version",
+	)
+	assertSequentialProviderIndexes(t, eso.HelmChart)
 }
 
 func assertVarValue(t *testing.T, chart *HelmChart, key, wantValue string) {
@@ -77,3 +103,125 @@ func assertVarValue(t *testing.T, chart *HelmChart, key, wantValue string) {
 
 	t.Fatalf("expected %s=%s to be set", key, wantValue)
 }
+
+func assertV2ProviderBaseVars(t *testing.T, chart *HelmChart) {
+	t.Helper()
+
+	assertVarValue(t, chart, "replicaCount", "1")
+	assertVarValue(t, chart, "v2.enabled", "true")
+	assertVarValue(t, chart, "crds.createProvider", "true")
+	assertVarValue(t, chart, "crds.createClusterProvider", "true")
+	assertVarValue(t, chart, "providerDefaults.replicaCount", "1")
+}
+
+func assertProvider(t *testing.T, chart *HelmChart, name, providerType, imageRepository, imageTag string) {
+	t.Helper()
+
+	for _, provider := range providerEntries(t, chart) {
+		if provider.Name != name {
+			continue
+		}
+		if provider.Type != providerType {
+			t.Fatalf("expected provider %q to have type %q, got %q", name, providerType, provider.Type)
+		}
+		if provider.Enabled != "true" {
+			t.Fatalf("expected provider %q to be enabled, got %q", name, provider.Enabled)
+		}
+		if provider.ReplicaCount != "1" {
+			t.Fatalf("expected provider %q replicaCount 1, got %q", name, provider.ReplicaCount)
+		}
+		if provider.ImageRepository != imageRepository {
+			t.Fatalf("expected provider %q image repository %q, got %q", name, imageRepository, provider.ImageRepository)
+		}
+		if provider.ImageTag != imageTag {
+			t.Fatalf("expected provider %q image tag %q, got %q", name, imageTag, provider.ImageTag)
+		}
+		if provider.ImagePullPolicy != "IfNotPresent" {
+			t.Fatalf("expected provider %q image pull policy IfNotPresent, got %q", name, provider.ImagePullPolicy)
+		}
+		return
+	}
+
+	t.Fatalf("expected provider %q to exist", name)
+}
+
+func assertSequentialProviderIndexes(t *testing.T, chart *HelmChart) {
+	t.Helper()
+
+	providers := providerEntries(t, chart)
+	for i := 0; i < len(providers); i++ {
+		if _, ok := providers[i]; !ok {
+			t.Fatalf("expected provider index %d to exist, got indexes %v", i, sortedProviderIndexes(providers))
+		}
+	}
+}
+
+type providerEntry struct {
+	Name            string
+	Type            string
+	Enabled         string
+	ReplicaCount    string
+	ImageRepository string
+	ImageTag        string
+	ImagePullPolicy string
+}
+
+var providerVarPattern = regexp.MustCompile(`^providers\.list\[(\d+)\]\.(.+)$`)
+
+func providerEntries(t *testing.T, chart *HelmChart) map[int]providerEntry {
+	t.Helper()
+
+	providers := make(map[int]providerEntry)
+	for _, variable := range chart.Vars {
+		matches := providerVarPattern.FindStringSubmatch(variable.Key)
+		if matches == nil {
+			continue
+		}
+		index, err := strconv.Atoi(matches[1])
+		if err != nil {
+			t.Fatalf("unable to parse provider index from key %q: %v", variable.Key, err)
+		}
+		field := matches[2]
+
+		entry := providers[index]
+		switch field {
+		case "name":
+			entry.Name = variable.Value
+		case "type":
+			entry.Type = variable.Value
+		case "enabled":
+			entry.Enabled = variable.Value
+		case "replicaCount":
+			entry.ReplicaCount = variable.Value
+		case "image.repository":
+			entry.ImageRepository = variable.Value
+		case "image.tag":
+			entry.ImageTag = variable.Value
+		case "image.pullPolicy":
+			entry.ImagePullPolicy = variable.Value
+		default:
+			if strings.HasPrefix(field, "image.") {
+				t.Fatalf("unexpected provider image field %q in key %q", field, variable.Key)
+			}
+		}
+		providers[index] = entry
+	}
+	return providers
+}
+
+func sortedProviderIndexes(providers map[int]providerEntry) []int {
+	indexes := make([]int, 0, len(providers))
+	for index := range providers {
+		indexes = append(indexes, index)
+	}
+
+	for i := 0; i < len(indexes); i++ {
+		for j := i + 1; j < len(indexes); j++ {
+			if indexes[j] < indexes[i] {
+				indexes[i], indexes[j] = indexes[j], indexes[i]
+			}
+		}
+	}
+
+	return indexes
+}