From db0a8f75be6767e81ce7baf1df8714c135d6c723 Mon Sep 17 00:00:00 2001 From: Mike Beaumont Date: Tue, 20 Dec 2022 13:25:11 +0100 Subject: [PATCH] test(MeshHTTPRoute): initial plugin unit tests Signed-off-by: Mike Beaumont --- .../plugin/v1alpha1/plugin_suite_test.go | 11 + .../plugin/v1alpha1/plugin_test.go | 411 ++++++++++++++++++ .../testdata/basic.clusters.golden.yaml | 29 ++ .../testdata/basic.endpoints.golden.yaml | 55 +++ .../testdata/basic.listeners.golden.yaml | 93 ++++ .../default-route.clusters.golden.yaml | 15 + .../default-route.endpoints.golden.yaml | 21 + .../default-route.listeners.golden.yaml | 41 ++ 8 files changed, 676 insertions(+) create mode 100644 pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin_suite_test.go create mode 100644 pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin_test.go create mode 100644 pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/basic.clusters.golden.yaml create mode 100644 pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/basic.endpoints.golden.yaml create mode 100644 pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/basic.listeners.golden.yaml create mode 100644 pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/default-route.clusters.golden.yaml create mode 100644 pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/default-route.endpoints.golden.yaml create mode 100644 pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/default-route.listeners.golden.yaml diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin_suite_test.go b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin_suite_test.go new file mode 100644 index 000000000000..871c9ebefa90 --- /dev/null +++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin_suite_test.go @@ -0,0 +1,11 @@ +package v1alpha1_test + +import ( + "testing" + + "github.com/kumahq/kuma/pkg/test" +) + +func TestPlugin(t *testing.T) { + test.RunSpecs(t, "MeshHTTPRoute") +} diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin_test.go b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin_test.go new file mode 100644 index 000000000000..e42a4123addc --- /dev/null +++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin_test.go @@ -0,0 +1,411 @@ +package v1alpha1_test + +import ( + "path/filepath" + "strings" + "time" + + envoy_resource "github.com/envoyproxy/go-control-plane/pkg/resource/v3" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + common_api "github.com/kumahq/kuma/api/common/v1alpha1" + mesh_proto "github.com/kumahq/kuma/api/mesh/v1alpha1" + core_plugins "github.com/kumahq/kuma/pkg/core/plugins" + core_mesh "github.com/kumahq/kuma/pkg/core/resources/apis/mesh" + core_model "github.com/kumahq/kuma/pkg/core/resources/model" + core_xds "github.com/kumahq/kuma/pkg/core/xds" + "github.com/kumahq/kuma/pkg/metrics" + api "github.com/kumahq/kuma/pkg/plugins/policies/meshhttproute/api/v1alpha1" + plugin "github.com/kumahq/kuma/pkg/plugins/policies/meshhttproute/plugin/v1alpha1" + "github.com/kumahq/kuma/pkg/test/matchers" + "github.com/kumahq/kuma/pkg/test/resources/builders" + test_model "github.com/kumahq/kuma/pkg/test/resources/model" + "github.com/kumahq/kuma/pkg/test/xds" + util_proto "github.com/kumahq/kuma/pkg/util/proto" + "github.com/kumahq/kuma/pkg/xds/cache/cla" + xds_context "github.com/kumahq/kuma/pkg/xds/context" + xds_envoy "github.com/kumahq/kuma/pkg/xds/envoy" +) + +func getResource(resourceSet *core_xds.ResourceSet, typ envoy_resource.Type) []byte { + resources, err := resourceSet.ListOf(typ).ToDeltaDiscoveryResponse() + Expect(err).ToNot(HaveOccurred()) + actual, err := util_proto.ToYAML(resources) + Expect(err).ToNot(HaveOccurred()) + + return actual +} + +var _ = Describe("MeshHTTPRoute", func() { + type policiesTestCase struct { + dataplane *core_mesh.DataplaneResource + resources xds_context.Resources + expectedRoutes core_xds.ToRules + } + DescribeTable("MatchedPolicies", func(given policiesTestCase) { + routes, err := plugin.NewPlugin().(core_plugins.PolicyPlugin).MatchedPolicies(given.dataplane, given.resources) + Expect(err).ToNot(HaveOccurred()) + Expect(routes.ToRules).To(Equal(given.expectedRoutes)) + }, Entry("basic", policiesTestCase{ + dataplane: builders.Dataplane(). + WithName("frontend"). + WithMesh("default"). + WithAddress("127.0.0.1"). + AddOutboundsToServices("backend"). + WithInboundOfTags(mesh_proto.ServiceTag, "frontend", mesh_proto.ProtocolTag, "http"). + Build(), + resources: xds_context.Resources{ + MeshLocalResources: map[core_model.ResourceType]core_model.ResourceList{ + api.MeshHTTPRouteType: &api.MeshHTTPRouteResourceList{ + Items: []*api.MeshHTTPRouteResource{{ + Meta: &test_model.ResourceMeta{ + Mesh: core_model.DefaultMesh, + Name: "route-1", + }, + Spec: &api.MeshHTTPRoute{ + TargetRef: common_api.TargetRef{ + Kind: common_api.Mesh, + }, + To: []api.To{{ + TargetRef: common_api.TargetRef{ + Kind: common_api.MeshService, + Name: "backend", + }, + Rules: []api.Rule{{ + Matches: []api.Match{{ + Path: api.PathMatch{ + Prefix: "/v1", + }, + }}, + Default: api.RuleConf{ + BackendRefs: &[]api.BackendRef{{ + TargetRef: common_api.TargetRef{ + Kind: common_api.MeshService, + Name: "backend", + }, + Weight: 100, + }}, + }, + }}, + }}, + }, + }, { + Meta: &test_model.ResourceMeta{ + Mesh: core_model.DefaultMesh, + Name: "route-2", + }, + Spec: &api.MeshHTTPRoute{ + TargetRef: common_api.TargetRef{ + Kind: common_api.MeshService, + Name: "frontend", + }, + To: []api.To{{ + TargetRef: common_api.TargetRef{ + Kind: common_api.MeshService, + Name: "backend", + }, + Rules: []api.Rule{{ + Matches: []api.Match{{ + Path: api.PathMatch{ + Prefix: "/v1", + }, + }}, + Default: api.RuleConf{ + BackendRefs: &[]api.BackendRef{{ + TargetRef: common_api.TargetRef{ + Kind: common_api.MeshService, + Name: "backend", + }, + Weight: 100, + }}, + }, + }}, + }}, + }, + }}, + }, + }, + }, + expectedRoutes: core_xds.ToRules{ + Rules: core_xds.Rules{ + { + Subset: core_xds.MeshService("backend"), + Conf: api.PolicyDefault{ + AppendRules: []api.Rule{ + { + Matches: []api.Match{{ + Path: api.PathMatch{ + Prefix: "/v1", + }, + }}, + Default: api.RuleConf{ + BackendRefs: &[]api.BackendRef{{ + TargetRef: common_api.TargetRef{ + Kind: common_api.MeshService, + Name: "backend", + }, + Weight: 100, + }}, + }, + }, + { + Matches: []api.Match{{ + Path: api.PathMatch{ + Prefix: "/v1", + }, + }}, + Default: api.RuleConf{ + BackendRefs: &[]api.BackendRef{{ + TargetRef: common_api.TargetRef{ + Kind: common_api.MeshService, + Name: "backend", + }, + Weight: 100, + }}, + }, + }, + }, + }, + Origin: []core_model.ResourceMeta{ + &test_model.ResourceMeta{ + Mesh: "default", + Name: "route-1", + }, + &test_model.ResourceMeta{ + Mesh: "default", + Name: "route-2", + }, + }, + }, + }, + }, + }), + ) + type routesTestCase struct { + rules []plugin.ToRouteRule + serviceName string + expectedRoutes []plugin.Route + } + DescribeTable("FindRoutes", func(given routesTestCase) { + routes := plugin.FindRoutes(given.rules, given.serviceName) + Expect(routes).To(Equal(given.expectedRoutes)) + }, Entry("basic", routesTestCase{ + rules: []plugin.ToRouteRule{{ + Subset: core_xds.MeshService("backend"), + Rules: []api.Rule{{ + Matches: []api.Match{{ + Path: api.PathMatch{ + Prefix: "/v1", + }, + }}, + Default: api.RuleConf{ + BackendRefs: &[]api.BackendRef{{ + TargetRef: common_api.TargetRef{ + Kind: common_api.MeshService, + Name: "backend", + }, + Weight: 100, + }}, + }, + }}, + }, { + Subset: core_xds.MeshService("backend"), + Rules: []api.Rule{{ + Matches: []api.Match{{ + Path: api.PathMatch{ + Prefix: "/v2", + }, + }}, + Default: api.RuleConf{ + BackendRefs: &[]api.BackendRef{{ + TargetRef: common_api.TargetRef{ + Kind: common_api.MeshService, + Name: "backend", + }, + Weight: 100, + }}, + }, + }}, + }}, + serviceName: "backend", + expectedRoutes: []plugin.Route{{ + Matches: []api.Match{{ + Path: api.PathMatch{ + Prefix: "/v1", + }, + }}, + BackendRefs: []api.BackendRef{ + { + TargetRef: common_api.TargetRef{Kind: "MeshService", Name: "backend", Tags: nil, Mesh: ""}, + Weight: 100, + }, + }, + }, { + Matches: []api.Match{{ + Path: api.PathMatch{ + Prefix: "/v2", + }, + }}, + BackendRefs: []api.BackendRef{ + { + TargetRef: common_api.TargetRef{Kind: "MeshService", Name: "backend", Tags: nil, Mesh: ""}, + Weight: 100, + }, + }, + }, { + Matches: []api.Match{{ + Path: api.PathMatch{ + Prefix: "/", + }, + }}, + BackendRefs: []api.BackendRef{ + { + TargetRef: common_api.TargetRef{Kind: "MeshService", Name: "backend", Tags: nil, Mesh: ""}, + Weight: 100, + }, + }, + }}, + }), + ) + type outboundsTestCase struct { + proxy core_xds.Proxy + xdsContext xds_context.Context + } + DescribeTable("Apply", func(given outboundsTestCase) { + metrics, err := metrics.NewMetrics("") + Expect(err).ToNot(HaveOccurred()) + + claCache, err := cla.NewCache(1*time.Second, metrics) + Expect(err).ToNot(HaveOccurred()) + given.xdsContext.ControlPlane.CLACache = claCache + + resourceSet := core_xds.NewResourceSet() + plugin := plugin.NewPlugin().(core_plugins.PolicyPlugin) + Expect(plugin.Apply(resourceSet, given.xdsContext, &given.proxy)).To(Succeed()) + + nameSplit := strings.Split(GinkgoT().Name(), " ") + name := nameSplit[len(nameSplit)-1] + + Expect(getResource(resourceSet, envoy_resource.ListenerType)).To(matchers.MatchGoldenYAML(filepath.Join("testdata", name+".listeners.golden.yaml"))) + Expect(getResource(resourceSet, envoy_resource.ClusterType)).To(matchers.MatchGoldenYAML(filepath.Join("testdata", name+".clusters.golden.yaml"))) + Expect(getResource(resourceSet, envoy_resource.EndpointType)).To(matchers.MatchGoldenYAML(filepath.Join("testdata", name+".endpoints.golden.yaml"))) + }, Entry("default-route", func() outboundsTestCase { + outboundTargets := core_xds.EndpointMap{ + "backend": []core_xds.Endpoint{{ + Target: "192.168.0.4", + Port: 8084, + Tags: map[string]string{"kuma.io/service": "backend", "kuma.io/protocol": "http", "region": "us"}, + Weight: 1, + }}, + } + return outboundsTestCase{ + xdsContext: xds_context.Context{ + ControlPlane: &xds_context.ControlPlaneContext{ + Secrets: &xds.TestSecrets{}, + }, + Mesh: xds_context.MeshContext{ + Resource: builders.Mesh().WithName("default").Build(), + EndpointMap: outboundTargets, + }, + }, + proxy: core_xds.Proxy{ + APIVersion: xds_envoy.APIV3, + Dataplane: builders.Dataplane(). + WithName("frontend"). + WithMesh("default"). + WithAddress("127.0.0.1"). + AddOutboundsToServices("backend"). + WithInboundOfTags(mesh_proto.ServiceTag, "frontend", mesh_proto.ProtocolTag, "http"). + Build(), + Routing: core_xds.Routing{ + OutboundTargets: outboundTargets, + }, + }, + } + }()), Entry("basic", func() outboundsTestCase { + outboundTargets := core_xds.EndpointMap{ + "backend": []core_xds.Endpoint{{ + Target: "192.168.0.4", + Port: 8084, + Tags: map[string]string{"kuma.io/service": "backend", "kuma.io/protocol": "http", "region": "eu"}, + Weight: 1, + }, { + Target: "192.168.0.5", + Port: 8084, + Tags: map[string]string{"kuma.io/service": "backend", "kuma.io/protocol": "http", "region": "us"}, + Weight: 1, + }}, + } + return outboundsTestCase{ + xdsContext: xds_context.Context{ + ControlPlane: &xds_context.ControlPlaneContext{ + Secrets: &xds.TestSecrets{}, + }, + Mesh: xds_context.MeshContext{ + Resource: builders.Mesh().WithName("default").Build(), + EndpointMap: outboundTargets, + }, + }, + proxy: core_xds.Proxy{ + APIVersion: xds_envoy.APIV3, + Dataplane: builders.Dataplane(). + WithName("frontend"). + WithMesh("default"). + WithAddress("127.0.0.1"). + AddOutboundsToServices("backend"). + WithInboundOfTags(mesh_proto.ServiceTag, "frontend", mesh_proto.ProtocolTag, "http"). + Build(), + Routing: core_xds.Routing{ + OutboundTargets: outboundTargets, + }, + Policies: core_xds.MatchedPolicies{ + Dynamic: map[core_model.ResourceType]core_xds.TypedMatchingPolicies{ + api.MeshHTTPRouteType: { + ToRules: core_xds.ToRules{ + Rules: core_xds.Rules{{ + Subset: core_xds.MeshService("backend"), + Conf: []api.Rule{{ + Matches: []api.Match{{ + Path: api.PathMatch{ + Prefix: "/v1", + }, + }}, + Default: api.RuleConf{ + BackendRefs: &[]api.BackendRef{{ + TargetRef: common_api.TargetRef{ + Kind: common_api.MeshService, + Name: "backend", + }, + Weight: 100, + }}, + }, + }, { + Matches: []api.Match{{ + Path: api.PathMatch{ + Prefix: "/v2", + }, + }}, + Default: api.RuleConf{ + BackendRefs: &[]api.BackendRef{{ + TargetRef: common_api.TargetRef{ + Kind: common_api.MeshServiceSubset, + Name: "backend", + Tags: map[string]string{ + "region": "us", + }, + }, + Weight: 100, + }}, + }, + }}, + }}, + }, + }, + }, + }, + }, + } + }()), + ) +}) diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/basic.clusters.golden.yaml b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/basic.clusters.golden.yaml new file mode 100644 index 000000000000..5e6ab8da35fb --- /dev/null +++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/basic.clusters.golden.yaml @@ -0,0 +1,29 @@ +resources: +- name: backend + resource: + '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + name: backend + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: {} +- name: backend-_0_ + resource: + '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + name: backend-_0_ + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: {} diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/basic.endpoints.golden.yaml b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/basic.endpoints.golden.yaml new file mode 100644 index 000000000000..1c5dc494ede6 --- /dev/null +++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/basic.endpoints.golden.yaml @@ -0,0 +1,55 @@ +resources: +- name: backend + resource: + '@type': type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment + clusterName: backend + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 192.168.0.4 + portValue: 8084 + loadBalancingWeight: 1 + metadata: + filterMetadata: + envoy.lb: + kuma.io/protocol: http + region: eu + envoy.transport_socket_match: + kuma.io/protocol: http + region: eu + - endpoint: + address: + socketAddress: + address: 192.168.0.5 + portValue: 8084 + loadBalancingWeight: 1 + metadata: + filterMetadata: + envoy.lb: + kuma.io/protocol: http + region: us + envoy.transport_socket_match: + kuma.io/protocol: http + region: us +- name: backend-_0_ + resource: + '@type': type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment + clusterName: backend-_0_ + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 192.168.0.5 + portValue: 8084 + loadBalancingWeight: 1 + metadata: + filterMetadata: + envoy.lb: + kuma.io/protocol: http + region: us + envoy.transport_socket_match: + kuma.io/protocol: http + region: us diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/basic.listeners.golden.yaml b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/basic.listeners.golden.yaml new file mode 100644 index 000000000000..4e12afa9da75 --- /dev/null +++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/basic.listeners.golden.yaml @@ -0,0 +1,93 @@ +resources: +- name: outbound:127.0.0.1:10001 + resource: + '@type': type.googleapis.com/envoy.config.listener.v3.Listener + address: + socketAddress: + address: 127.0.0.1 + portValue: 10001 + filterChains: + - filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + httpFilters: + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + routeConfig: + name: outbound:backend + requestHeadersToAdd: + - header: + key: x-kuma-tags + value: '&kuma.io/protocol=http&&kuma.io/service=frontend&' + validateClusters: false + virtualHosts: + - domains: + - '*' + name: backend + routes: + - match: + prefix: /v1 + route: + cluster: backend + timeout: 0s + statPrefix: backend + - filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + httpFilters: + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + routeConfig: + name: outbound:backend + requestHeadersToAdd: + - header: + key: x-kuma-tags + value: '&kuma.io/protocol=http&&kuma.io/service=frontend&' + validateClusters: false + virtualHosts: + - domains: + - '*' + name: backend + routes: + - match: + prefix: /v2 + route: + cluster: backend-_0_ + timeout: 0s + statPrefix: backend + - filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + httpFilters: + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + routeConfig: + name: outbound:backend + requestHeadersToAdd: + - header: + key: x-kuma-tags + value: '&kuma.io/protocol=http&&kuma.io/service=frontend&' + validateClusters: false + virtualHosts: + - domains: + - '*' + name: backend + routes: + - match: + prefix: / + route: + cluster: backend + timeout: 0s + statPrefix: backend + metadata: + filterMetadata: + io.kuma.tags: + kuma.io/service: backend + name: outbound:127.0.0.1:10001 + trafficDirection: OUTBOUND diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/default-route.clusters.golden.yaml b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/default-route.clusters.golden.yaml new file mode 100644 index 000000000000..69e536007ad8 --- /dev/null +++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/default-route.clusters.golden.yaml @@ -0,0 +1,15 @@ +resources: +- name: backend + resource: + '@type': type.googleapis.com/envoy.config.cluster.v3.Cluster + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + name: backend + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: {} diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/default-route.endpoints.golden.yaml b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/default-route.endpoints.golden.yaml new file mode 100644 index 000000000000..d6600e0c3053 --- /dev/null +++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/default-route.endpoints.golden.yaml @@ -0,0 +1,21 @@ +resources: +- name: backend + resource: + '@type': type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment + clusterName: backend + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 192.168.0.4 + portValue: 8084 + loadBalancingWeight: 1 + metadata: + filterMetadata: + envoy.lb: + kuma.io/protocol: http + region: us + envoy.transport_socket_match: + kuma.io/protocol: http + region: us diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/default-route.listeners.golden.yaml b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/default-route.listeners.golden.yaml new file mode 100644 index 000000000000..15ae0b664406 --- /dev/null +++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/default-route.listeners.golden.yaml @@ -0,0 +1,41 @@ +resources: +- name: outbound:127.0.0.1:10001 + resource: + '@type': type.googleapis.com/envoy.config.listener.v3.Listener + address: + socketAddress: + address: 127.0.0.1 + portValue: 10001 + filterChains: + - filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + httpFilters: + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + routeConfig: + name: outbound:backend + requestHeadersToAdd: + - header: + key: x-kuma-tags + value: '&kuma.io/protocol=http&&kuma.io/service=frontend&' + validateClusters: false + virtualHosts: + - domains: + - '*' + name: backend + routes: + - match: + prefix: / + route: + cluster: backend + timeout: 0s + statPrefix: backend + metadata: + filterMetadata: + io.kuma.tags: + kuma.io/service: backend + name: outbound:127.0.0.1:10001 + trafficDirection: OUTBOUND