diff --git a/pkg/plugins/policies/meshloadbalancingstrategy/plugin/v1alpha1/plugin_test.go b/pkg/plugins/policies/meshloadbalancingstrategy/plugin/v1alpha1/plugin_test.go index 0693114f5c7a..43db2aa1e2dc 100644 --- a/pkg/plugins/policies/meshloadbalancingstrategy/plugin/v1alpha1/plugin_test.go +++ b/pkg/plugins/policies/meshloadbalancingstrategy/plugin/v1alpha1/plugin_test.go @@ -1,6 +1,7 @@ package v1alpha1_test import ( + "fmt" "path/filepath" "strings" @@ -15,8 +16,11 @@ import ( core_xds "github.com/kumahq/kuma/pkg/core/xds" "github.com/kumahq/kuma/pkg/plugins/policies/meshloadbalancingstrategy/api/v1alpha1" plugin "github.com/kumahq/kuma/pkg/plugins/policies/meshloadbalancingstrategy/plugin/v1alpha1" + gateway_plugin "github.com/kumahq/kuma/pkg/plugins/runtime/gateway" "github.com/kumahq/kuma/pkg/test/matchers" "github.com/kumahq/kuma/pkg/test/resources/builders" + "github.com/kumahq/kuma/pkg/test/resources/samples" + test_xds "github.com/kumahq/kuma/pkg/test/xds" "github.com/kumahq/kuma/pkg/util/pointer" util_proto "github.com/kumahq/kuma/pkg/util/proto" xds_context "github.com/kumahq/kuma/pkg/xds/context" @@ -42,7 +46,7 @@ var _ = Describe("MeshLoadBalancingStrategy", func() { resources []core_xds.Resource proxy *core_xds.Proxy } - DescribeTable("Apply", + DescribeTable("Apply to sidecar Dataplanes", func(given testCase) { resources := core_xds.NewResourceSet() for _, res := range given.resources { @@ -362,4 +366,91 @@ var _ = Describe("MeshLoadBalancingStrategy", func() { }, }), ) + type gatewayTestCase struct { + name string + toRules core_xds.ToRules + } + DescribeTable("should generate proper Envoy config for MeshGateways", + func(given gatewayTestCase) { + Expect(given.name).ToNot(BeEmpty()) + resources := xds_context.NewResources() + resources.MeshLocalResources[core_mesh.MeshGatewayType] = &core_mesh.MeshGatewayResourceList{ + Items: []*core_mesh.MeshGatewayResource{samples.GatewayResource()}, + } + resources.MeshLocalResources[core_mesh.MeshGatewayRouteType] = &core_mesh.MeshGatewayRouteResourceList{ + Items: []*core_mesh.MeshGatewayRouteResource{samples.BackendGatewayRoute()}, + } + + context := test_xds.CreateSampleMeshContextWith(resources) + proxy := core_xds.Proxy{ + APIVersion: "v3", + Dataplane: samples.GatewayDataplane(), + Policies: core_xds.MatchedPolicies{ + Dynamic: map[core_model.ResourceType]core_xds.TypedMatchingPolicies{ + v1alpha1.MeshLoadBalancingStrategyType: { + Type: v1alpha1.MeshLoadBalancingStrategyType, + ToRules: given.toRules, + }, + }, + }, + } + gatewayGenerator := gateway_plugin.NewGenerator("test-zone") + generatedResources, err := gatewayGenerator.Generate(context, &proxy) + Expect(err).NotTo(HaveOccurred()) + + // when + plugin := plugin.NewPlugin().(core_plugins.PolicyPlugin) + Expect(plugin.Apply(generatedResources, context, &proxy)).To(Succeed()) + + getResourceYaml := func(list core_xds.ResourceList) []byte { + actualResource, err := util_proto.ToYAML(list[0].Resource) + Expect(err).ToNot(HaveOccurred()) + return actualResource + } + + // then + Expect(getResourceYaml(generatedResources.ListOf(envoy_resource.ClusterType))). + To(matchers.MatchGoldenYAML(filepath.Join("testdata", fmt.Sprintf("%s.gateway_cluster.golden.yaml", given.name)))) + Expect(getResourceYaml(generatedResources.ListOf(envoy_resource.ListenerType))). + To(matchers.MatchGoldenYAML(filepath.Join("testdata", fmt.Sprintf("%s.gateway_listener.golden.yaml", given.name)))) + Expect(getResourceYaml(generatedResources.ListOf(envoy_resource.RouteType))). + To(matchers.MatchGoldenYAML(filepath.Join("testdata", fmt.Sprintf("%s.gateway_route.golden.yaml", given.name)))) + }, + Entry("basic outbound cluster", gatewayTestCase{ + name: "basic", + toRules: core_xds.ToRules{ + Rules: []*core_xds.Rule{ + { + Subset: core_xds.Subset{}, + Conf: v1alpha1.Conf{ + LoadBalancer: &v1alpha1.LoadBalancer{ + Type: v1alpha1.RingHashType, + RingHash: &v1alpha1.RingHash{ + MinRingSize: pointer.To[uint32](100), + MaxRingSize: pointer.To[uint32](1000), + HashFunction: pointer.To(v1alpha1.MurmurHash2Type), + HashPolicies: &[]v1alpha1.HashPolicy{ + { + Type: v1alpha1.QueryParameterType, + QueryParameter: &v1alpha1.QueryParameter{ + Name: "queryparam", + }, + Terminal: pointer.To(true), + }, + { + Type: v1alpha1.ConnectionType, + Connection: &v1alpha1.Connection{ + SourceIP: pointer.To(true), + }, + Terminal: pointer.To(false), + }, + }, + }, + }, + }, + }, + }, + }, + }), + ) }) diff --git a/pkg/plugins/policies/meshloadbalancingstrategy/plugin/v1alpha1/testdata/basic.gateway_cluster.golden.yaml b/pkg/plugins/policies/meshloadbalancingstrategy/plugin/v1alpha1/testdata/basic.gateway_cluster.golden.yaml new file mode 100644 index 000000000000..3644e3eacaff --- /dev/null +++ b/pkg/plugins/policies/meshloadbalancingstrategy/plugin/v1alpha1/testdata/basic.gateway_cluster.golden.yaml @@ -0,0 +1,20 @@ +connectTimeout: 10s +edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 +lbPolicy: RING_HASH +name: backend-26cb64fa4e85e7b7 +perConnectionBufferLimitBytes: 32768 +ringHashLbConfig: + hashFunction: MURMUR_HASH_2 + maximumRingSize: "1000" + minimumRingSize: "100" +type: EDS +typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + commonHttpProtocolOptions: + idleTimeout: 0s + explicitHttpConfig: + httpProtocolOptions: {} diff --git a/pkg/plugins/policies/meshloadbalancingstrategy/plugin/v1alpha1/testdata/basic.gateway_listener.golden.yaml b/pkg/plugins/policies/meshloadbalancingstrategy/plugin/v1alpha1/testdata/basic.gateway_listener.golden.yaml new file mode 100644 index 000000000000..88df4d36c4d3 --- /dev/null +++ b/pkg/plugins/policies/meshloadbalancingstrategy/plugin/v1alpha1/testdata/basic.gateway_listener.golden.yaml @@ -0,0 +1,55 @@ +address: + socketAddress: + address: 192.168.0.1 + portValue: 8080 +enableReusePort: true +filterChains: +- filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + idleTimeout: 300s + http2ProtocolOptions: + allowConnect: true + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - name: envoy.filters.http.local_ratelimit + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit + statPrefix: rate_limit + - name: gzip-compress + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.compressor.v3.Compressor + compressorLibrary: + name: gzip + typedConfig: + '@type': type.googleapis.com/envoy.extensions.compression.gzip.compressor.v3.Gzip + responseDirectionConfig: + disableOnEtagHeader: true + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: sample-gateway:HTTP:8080 + requestHeadersTimeout: 0.500s + serverName: Kuma Gateway + statPrefix: sample-gateway + streamIdleTimeout: 5s + useRemoteAddress: true +listenerFilters: +- name: envoy.filters.listener.tls_inspector + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector +name: sample-gateway:HTTP:8080 +perConnectionBufferLimitBytes: 32768 +trafficDirection: INBOUND diff --git a/pkg/plugins/policies/meshloadbalancingstrategy/plugin/v1alpha1/testdata/basic.gateway_route.golden.yaml b/pkg/plugins/policies/meshloadbalancingstrategy/plugin/v1alpha1/testdata/basic.gateway_route.golden.yaml new file mode 100644 index 000000000000..9dde10f4edeb --- /dev/null +++ b/pkg/plugins/policies/meshloadbalancingstrategy/plugin/v1alpha1/testdata/basic.gateway_route.golden.yaml @@ -0,0 +1,28 @@ +ignorePortInHostMatching: true +name: sample-gateway:HTTP:8080 +requestHeadersToRemove: +- x-kuma-tags +validateClusters: false +virtualHosts: +- domains: + - '*' + name: '*' + routes: + - match: + path: / + route: + clusterNotFoundResponseCode: INTERNAL_SERVER_ERROR + hashPolicy: + - queryParameter: + name: queryparam + terminal: true + - connectionProperties: + sourceIp: true + weightedClusters: + clusters: + - name: backend-26cb64fa4e85e7b7 + requestHeadersToAdd: + - header: + key: x-kuma-tags + value: '&kuma.io/service=sample-gateway&' + weight: 1