From bbf7494a416b118ed1a4569899814cded2bff190 Mon Sep 17 00:00:00 2001 From: Mike Morris Date: Thu, 5 Jan 2023 16:58:54 -0500 Subject: [PATCH] e2e: add test for Consul desintation namespace without k8s namespace mirroring --- internal/commands/server/k8s_e2e_test.go | 49 +++++++++++++++++++++++ internal/testing/e2e/consul.go | 50 +++++++++++++----------- internal/testing/e2e/environment.go | 13 ++++++ internal/testing/e2e/stack.go | 3 +- 4 files changed, 92 insertions(+), 23 deletions(-) diff --git a/internal/commands/server/k8s_e2e_test.go b/internal/commands/server/k8s_e2e_test.go index a7d73d7a5..f3cf46e96 100644 --- a/internal/commands/server/k8s_e2e_test.go +++ b/internal/commands/server/k8s_e2e_test.go @@ -116,6 +116,55 @@ func TestGatewayWithClassConfigChange(t *testing.T) { testenv.Test(t, feature.Feature()) } +func TestGatewayWithoutNamespaceMirroring(t *testing.T) { + feature := features.New("gateway admission"). + Assess("gateway sync without namespace mirroring", func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { + namespace := e2e.Namespace(ctx) + resources := cfg.Client().Resources(namespace) + + // Disable namespace mirroring + ctx, err = e2e.SetNamespaceMirroring(false)(ctx) + + useHostPorts := false + gcc, gc := createGatewayClassWithParams(ctx, t, resources, GatewayClassConfigParams{ + UseHostPorts: &useHostPorts, + }) + require.Eventually(t, gatewayClassStatusCheck(ctx, resources, gc.Name, namespace, conditionAccepted), checkTimeout, checkInterval, "gatewayclass not accepted in the allotted time") + + // Create a Gateway and wait for it to be ready + // This will attempt to sync to a randomly generated Consul desintation namespace + firstGatewayName := envconf.RandomName("gw", 16) + firstGateway := createGateway(ctx, t, resources, firstGatewayName, namespace, gc, []gwv1beta1.Listener{httpsListener}) + require.Eventually(t, gatewayStatusCheck(ctx, resources, firstGatewayName, namespace, conditionReady), checkTimeout, checkInterval, "no gateway found in the allotted time") + checkGatewayConfigAnnotation(ctx, t, resources, firstGatewayName, namespace, firstConfig) + + // Set a different Consul destination namespace + ctx, err := e2e.SetConsulNamespace("")(ctx) + + // Create a second Gateway and wait for it to be ready + secondGatewayName := envconf.RandomName("gw", 16) + secondGateway := createGateway(ctx, t, resources, secondGatewayName, namespace, gc, []gwv1beta1.Listener{httpsListener}) + require.Eventually(t, gatewayStatusCheck(ctx, resources, secondGatewayName, namespace, conditionReady), checkTimeout, checkInterval, "no gateway found in the allotted time") + + // Set a different Consul destination namespace + ctx, err := e2e.SetConsulNamespace("default")(ctx) + + // Create a third Gateway and wait for it to be ready + thirdGatewayName := envconf.RandomName("gw", 16) + thirdGateway := createGateway(ctx, t, resources, thirdGatewayName, namespace, gc, []gwv1beta1.Listener{httpsListener}) + require.Eventually(t, gatewayStatusCheck(ctx, resources, thirdGatewayName, namespace, conditionReady), checkTimeout, checkInterval, "no gateway found in the allotted time") + + // Cleanup + assert.NoError(t, resources.Delete(ctx, firstGateway)) + assert.NoError(t, resources.Delete(ctx, secondGateway)) + assert.NoError(t, resources.Delete(ctx, thirdGateway)) + + return ctx + }) + + testenv.Test(t, feature.Feature()) +} + func TestGatewayWithReplicas(t *testing.T) { feature := features.New("gateway class config configure instances"). Assess("gateway is created with appropriate number of replicas set", func(ctx context.Context, t *testing.T, cfg *envconf.Config) context.Context { diff --git a/internal/testing/e2e/consul.go b/internal/testing/e2e/consul.go index 4de4bb230..497e9feb9 100644 --- a/internal/testing/e2e/consul.go +++ b/internal/testing/e2e/consul.go @@ -510,14 +510,15 @@ func ConsulHTTPPort(ctx context.Context) int { return mustGetTestEnvironment(ctx).httpPort } -func isConsulNamespaceMirroringOn() bool { - return IsEnterprise() +func isConsulNamespaceMirroringOn(ctx context.Context) bool { + return IsEnterprise() && NamespaceMirroring(ctx) } func ConsulNamespace(ctx context.Context) string { - if isConsulNamespaceMirroringOn() { - //assume mirroring is on + if isConsulNamespaceMirroringOn(ctx) { return Namespace(ctx) } + + // Return Consul namespace return mustGetTestEnvironment(ctx).namespace } @@ -588,27 +589,32 @@ func IsEnterprise() bool { return strings.HasSuffix(consulImage, "ent") } -func CreateConsulNamespace(ctx context.Context, cfg *envconf.Config) (context.Context, error) { - if IsEnterprise() { - log.Print("Creating Consul Namespace") - namespace := envconf.RandomName("test", 16) +func SetConsulNamespace(namespace *string) env.Func { + return func(ctx context.Context, _ *envconf.Config) (context.Context, error) { + if IsEnterprise() { + log.Print("Creating Consul Namespace") + if namespace == nil { + *namespace = envconf.RandomName("consul", 16) + } - consulEnvironment := ctx.Value(consulTestContextKey) - if consulEnvironment == nil { - return ctx, nil - } - env := consulEnvironment.(*consulTestEnvironment) - _, _, err := env.consulClient.Namespaces().Create(&api.Namespace{ - Name: namespace, - }, &api.WriteOptions{ - Token: env.token, - }) - if err != nil { - return nil, err + consulEnvironment := ctx.Value(consulTestContextKey) + if consulEnvironment == nil { + return ctx, nil + } + env := consulEnvironment.(*consulTestEnvironment) + _, _, err := env.consulClient.Namespaces().Create(&api.Namespace{ + Name: *namespace, + }, &api.WriteOptions{ + Token: env.token, + }) + // TODO: ignore error if namespace already exists + if err != nil { + return nil, err + } + env.namespace = *namespace } - env.namespace = namespace + return ctx, nil } - return ctx, nil } func gatewayConsulAuthMethod(name, token string, k8sConfig *rest.Config) *api.ACLAuthMethod { diff --git a/internal/testing/e2e/environment.go b/internal/testing/e2e/environment.go index 1c0c8e078..1e62fecf6 100644 --- a/internal/testing/e2e/environment.go +++ b/internal/testing/e2e/environment.go @@ -11,9 +11,11 @@ import ( ) type namespaceContext struct{} +type namespaceMirroringContext struct{} type clusterNameContext struct{} var namespaceContextKey = namespaceContext{} +var namespaceMirroringContextKey = namespaceMirroringContext{} var clusterNameContextKey = clusterNameContext{} func SetNamespace(namespace string) env.Func { @@ -22,6 +24,12 @@ func SetNamespace(namespace string) env.Func { } } +func SetNamespaceMirroring(namespaceMirroring bool) env.Func { + return func(ctx context.Context, cfg *envconf.Config) (context.Context, error) { + return context.WithValue(ctx, namespaceMirroringContextKey, namespaceMirroring), nil + } +} + func Namespace(ctx context.Context) string { namespace := ctx.Value(namespaceContextKey) if namespace == nil { @@ -30,6 +38,11 @@ func Namespace(ctx context.Context) string { return namespace.(string) } +func NamespaceMirroring(ctx context.Context) bool { + namespaceMirroring := ctx.Value(namespaceMirroringContextKey) + return namespaceMirroring.(bool) +} + func SetClusterName(name string) env.Func { return func(ctx context.Context, cfg *envconf.Config) (context.Context, error) { return context.WithValue(ctx, clusterNameContextKey, name), nil diff --git a/internal/testing/e2e/stack.go b/internal/testing/e2e/stack.go index 8daaf56f3..8eb27507e 100644 --- a/internal/testing/e2e/stack.go +++ b/internal/testing/e2e/stack.go @@ -28,6 +28,7 @@ func SetUpStack(hostRoute string) env.Func { for _, f := range []env.Func{ SetClusterName(kindClusterName), SetNamespace(namespace), + SetNamespaceMirroring(true), CrossCompileProject, BuildDockerImage, CreateKindCluster(kindClusterName), @@ -38,7 +39,7 @@ func SetUpStack(hostRoute string) env.Func { CreateTestConsulContainer(kindClusterName, namespace), CreateConsulACLPolicy, CreateConsulAuthMethod(), - CreateConsulNamespace, + SetConsulNamespace(nil), CreateTestGatewayServer(namespace), } { ctx, err = f(ctx, cfg)