From cdfdf00e77e7e3bb468dc9653c041578b576bd9c Mon Sep 17 00:00:00 2001 From: Lukasz Dziedziak Date: Tue, 9 Jan 2024 15:53:32 +0100 Subject: [PATCH] feat(meshhttproute): add grpc support (#8752) Signed-off-by: Lukasz Dziedziak --- .../policies/core/xds/meshroute/listeners.go | 2 + .../plugin/v1alpha1/listeners.go | 5 ++ .../plugin/v1alpha1/plugin_test.go | 43 ++++++++++++++ .../grpc-service.clusters.golden.yaml | 15 +++++ .../grpc-service.endpoints.golden.yaml | 21 +++++++ .../grpc-service.listeners.golden.yaml | 59 +++++++++++++++++++ .../testdata/grpc-service.routes.golden.yaml | 1 + test/e2e_env/universal/grpc/grpc.go | 9 +-- 8 files changed, 151 insertions(+), 4 deletions(-) create mode 100644 pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/grpc-service.clusters.golden.yaml create mode 100644 pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/grpc-service.endpoints.golden.yaml create mode 100644 pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/grpc-service.listeners.golden.yaml create mode 100644 pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/grpc-service.routes.golden.yaml diff --git a/pkg/plugins/policies/core/xds/meshroute/listeners.go b/pkg/plugins/policies/core/xds/meshroute/listeners.go index d0a8b0e7621b..91fabd5d0fa3 100644 --- a/pkg/plugins/policies/core/xds/meshroute/listeners.go +++ b/pkg/plugins/policies/core/xds/meshroute/listeners.go @@ -26,6 +26,7 @@ func MakeTCPSplit( core_mesh.ProtocolTCP: {}, core_mesh.ProtocolHTTP: {}, core_mesh.ProtocolHTTP2: {}, + core_mesh.ProtocolGRPC: {}, }, clusterCache, servicesAcc, @@ -44,6 +45,7 @@ func MakeHTTPSplit( map[core_mesh.Protocol]struct{}{ core_mesh.ProtocolHTTP: {}, core_mesh.ProtocolHTTP2: {}, + core_mesh.ProtocolGRPC: {}, }, clusterCache, servicesAcc, diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/listeners.go b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/listeners.go index 846734a634fc..c889bb141a17 100644 --- a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/listeners.go +++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/listeners.go @@ -90,6 +90,11 @@ func generateListeners( filterChainBuilder. Configure(envoy_listeners.AddFilterChainConfigurer(outboundRouteConfigurer)) + // TODO: https://github.com/kumahq/kuma/issues/3325 + switch protocol { + case core_mesh.ProtocolGRPC: + filterChainBuilder.Configure(envoy_listeners.GrpcStats()) + } listenerBuilder.Configure(envoy_listeners.FilterChain(filterChainBuilder)) listener, err := listenerBuilder.Build() if err != nil { diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin_test.go b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin_test.go index 44596c31518f..ff7a29a8aa2c 100644 --- a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin_test.go +++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/plugin_test.go @@ -409,6 +409,49 @@ var _ = Describe("MeshHTTPRoute", func() { Build(), } }()), + Entry("grpc-service", func() outboundsTestCase { + outboundTargets := xds_builders.EndpointMap(). + AddEndpoint("backend", xds_builders.Endpoint(). + WithTarget("192.168.0.4"). + WithPort(8084). + WithWeight(1). + WithTags(mesh_proto.ServiceTag, "backend", mesh_proto.ProtocolTag, core_mesh.ProtocolGRPC, "region", "us")) + return outboundsTestCase{ + xdsContext: *xds_builders.Context().WithEndpointMap(outboundTargets). + AddServiceProtocol("backend", core_mesh.ProtocolGRPC). + Build(), + proxy: xds_builders.Proxy(). + WithDataplane(samples.DataplaneWebBuilder()). + WithRouting(xds_builders.Routing().WithOutboundTargets(outboundTargets)). + WithPolicies( + xds_builders.MatchedPolicies(). + WithToPolicy(api.MeshHTTPRouteType, core_rules.ToRules{ + Rules: core_rules.Rules{ + { + Subset: core_rules.MeshService("backend"), + Conf: api.PolicyDefault{ + Rules: []api.Rule{{ + Matches: []api.Match{{ + Path: &api.PathMatch{ + Type: api.PathPrefix, + Value: "/v1", + }, + }}, + Default: api.RuleConf{ + BackendRefs: &[]common_api.BackendRef{{ + TargetRef: builders.TargetRefService("backend"), + Weight: pointer.To(uint(100)), + }}, + }, + }}, + }, + }, + }, + }), + ). + Build(), + } + }()), Entry("request-mirror", func() outboundsTestCase { outboundTargets := xds_builders.EndpointMap(). AddEndpoint("backend", xds_builders.Endpoint(). diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/grpc-service.clusters.golden.yaml b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/grpc-service.clusters.golden.yaml new file mode 100644 index 000000000000..69e536007ad8 --- /dev/null +++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/grpc-service.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/grpc-service.endpoints.golden.yaml b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/grpc-service.endpoints.golden.yaml new file mode 100644 index 000000000000..bcfe6f62534f --- /dev/null +++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/grpc-service.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: grpc + region: us + envoy.transport_socket_match: + kuma.io/protocol: grpc + region: us diff --git a/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/grpc-service.listeners.golden.yaml b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/grpc-service.listeners.golden.yaml new file mode 100644 index 000000000000..03b3f5827b3c --- /dev/null +++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/grpc-service.listeners.golden.yaml @@ -0,0 +1,59 @@ +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.grpc_stats + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig + emitFilterState: true + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + normalizePath: true + routeConfig: + name: outbound:backend + requestHeadersToAdd: + - header: + key: x-kuma-tags + value: '&kuma.io/protocol=http&&kuma.io/service=web&' + validateClusters: false + virtualHosts: + - domains: + - '*' + name: backend + routes: + - match: + path: /v1 + name: bzv64o+joRk33jfDADgGv5ar4QyONO0NEVKnoBfJW/E= + route: + cluster: backend + timeout: 0s + - match: + prefix: /v1/ + name: bzv64o+joRk33jfDADgGv5ar4QyONO0NEVKnoBfJW/E= + route: + cluster: backend + timeout: 0s + - match: + prefix: / + name: 9Zuf5Tg79OuZcQITwBbQykxAk2u4fRKrwYn3//AL4Yo= + 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/grpc-service.routes.golden.yaml b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/grpc-service.routes.golden.yaml new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/pkg/plugins/policies/meshhttproute/plugin/v1alpha1/testdata/grpc-service.routes.golden.yaml @@ -0,0 +1 @@ +{} diff --git a/test/e2e_env/universal/grpc/grpc.go b/test/e2e_env/universal/grpc/grpc.go index 131e41ded84e..0cfd9424d9e2 100644 --- a/test/e2e_env/universal/grpc/grpc.go +++ b/test/e2e_env/universal/grpc/grpc.go @@ -62,7 +62,8 @@ func GRPC() { }, "30s", "1s").Should(Succeed()) }) - It("MeshHTTPRoute DOES NOT split the traffic between two gRPC services", func() { + // todo switch to MeshGRPCRoute when https://github.com/kumahq/kuma/issues/3325 is implemented + It("MeshHTTPRoute does split the traffic between two gRPC services", func() { yaml := ` type: MeshHTTPRoute name: http-route-1 @@ -96,9 +97,9 @@ spec: universal.Cluster, "second-test-server", "http://localhost:9901/stats?format=prometheus", ) g.Expect(err).ToNot(HaveOccurred()) - // todo switch .ToNot to .To when https://github.com/kumahq/kuma/issues/3325 is implemented - g.Expect(stdout).ToNot(ContainSubstring(`envoy_cluster_grpc_request_message_count{envoy_cluster_name="localhost_8080"}`)) - g.Expect(stdout).ToNot(ContainSubstring(`envoy_cluster_grpc_response_message_count{envoy_cluster_name="localhost_8080"}`)) + + g.Expect(stdout).To(ContainSubstring(`envoy_cluster_grpc_request_message_count{envoy_cluster_name="localhost_8080"}`)) + g.Expect(stdout).To(ContainSubstring(`envoy_cluster_grpc_response_message_count{envoy_cluster_name="localhost_8080"}`)) }, "30s", "1s").MustPassRepeatedly(5).Should(Succeed()) }) }