From 69b3873bed8d0fc64655935dc96d6b2f4af6d5b9 Mon Sep 17 00:00:00 2001 From: bitliu Date: Fri, 18 Nov 2022 00:43:40 +0800 Subject: [PATCH] feat: add support for TCP Route Signed-off-by: bitliu --- go.mod | 2 +- internal/ir/xds_test.go | 20 ++- internal/xds/translator/listener.go | 22 +++- .../xds-ir/http-route-weighted-backend.yaml | 21 ++++ .../multiple-simple-tcp-route-same-port.yaml | 41 +++++++ .../testdata/in/xds-ir/tcp-route-complex.yaml | 14 +++ .../testdata/in/xds-ir/tcp-route-simple.yaml | 9 ++ .../in/xds-ir/tcp-route-weighted-backend.yaml | 22 ++++ .../http-route-weighted-backend.clusters.yaml | 37 ++++++ ...http-route-weighted-backend.listeners.yaml | 40 ++++++ .../http-route-weighted-backend.routes.yaml | 10 ++ ...e-simple-tcp-route-same-port.clusters.yaml | 115 ++++++++++++++++++ ...-simple-tcp-route-same-port.listeners.yaml | 70 +++++++++++ ...ple-simple-tcp-route-same-port.routes.yaml | 1 + .../xds-ir/tcp-route-complex.clusters.yaml | 23 ++++ .../xds-ir/tcp-route-complex.listeners.yaml | 35 ++++++ .../out/xds-ir/tcp-route-complex.routes.yaml | 1 + .../out/xds-ir/tcp-route-simple.clusters.yaml | 23 ++++ .../xds-ir/tcp-route-simple.listeners.yaml | 26 ++++ .../out/xds-ir/tcp-route-simple.routes.yaml | 1 + .../tcp-route-weighted-backend.clusters.yaml | 37 ++++++ .../tcp-route-weighted-backend.listeners.yaml | 35 ++++++ .../tcp-route-weighted-backend.routes.yaml | 1 + internal/xds/translator/translator.go | 72 +++++------ internal/xds/translator/translator_test.go | 15 +++ 25 files changed, 655 insertions(+), 38 deletions(-) create mode 100644 internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend.yaml create mode 100644 internal/xds/translator/testdata/in/xds-ir/multiple-simple-tcp-route-same-port.yaml create mode 100644 internal/xds/translator/testdata/in/xds-ir/tcp-route-complex.yaml create mode 100644 internal/xds/translator/testdata/in/xds-ir/tcp-route-simple.yaml create mode 100644 internal/xds/translator/testdata/in/xds-ir/tcp-route-weighted-backend.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.clusters.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.listeners.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.routes.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.clusters.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.listeners.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.routes.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.clusters.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.listeners.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.routes.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.clusters.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.listeners.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.routes.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.clusters.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.listeners.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.routes.yaml diff --git a/go.mod b/go.mod index 38d3b23721e4..a917ac08773d 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/envoyproxy/gateway go 1.18 require ( + github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc github.com/envoyproxy/go-control-plane v0.10.3-0.20221028143534-ed9652aebfd9 github.com/go-logr/zapr v1.2.0 github.com/google/go-cmp v0.5.8 @@ -51,7 +52,6 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc // indirect github.com/envoyproxy/protoc-gen-validate v0.6.7 // indirect github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect github.com/fsnotify/fsnotify v1.5.1 // indirect diff --git a/internal/ir/xds_test.go b/internal/ir/xds_test.go index cf06dab00dc9..b8ece352ef38 100644 --- a/internal/ir/xds_test.go +++ b/internal/ir/xds_test.go @@ -69,6 +69,12 @@ var ( TLS: &TLSInspectorConfig{SNIs: []string{"example.com"}}, Destinations: []*RouteDestination{&happyRouteDestination}, } + emptySNITCPListenerTLSPassthrough = TCPListener{ + Name: "empty-sni", + Address: "0.0.0.0", + Port: 80, + Destinations: []*RouteDestination{&happyRouteDestination}, + } invalidNameTCPListenerTLSPassthrough = TCPListener{ Address: "0.0.0.0", Port: 80, @@ -424,6 +430,11 @@ func TestValidateTCPListener(t *testing.T) { input: happyTCPListenerTLSPassthrough, want: nil, }, + { + name: "tcp empty SNIs", + input: emptySNITCPListenerTLSPassthrough, + want: nil, + }, { name: "tls passthrough invalid name", input: invalidNameTCPListenerTLSPassthrough, @@ -663,7 +674,14 @@ func TestValidateRouteDestination(t *testing.T) { want: ErrRouteDestinationHostInvalid, }, { - name: "invalid port", + name: "missing ip", + input: RouteDestination{ + Port: 8080, + }, + want: ErrRouteDestinationHostInvalid, + }, + { + name: "missing port", input: RouteDestination{ Host: "10.11.12.13", }, diff --git a/internal/xds/translator/listener.go b/internal/xds/translator/listener.go index 7d63575ddf51..699d983cc172 100644 --- a/internal/xds/translator/listener.go +++ b/internal/xds/translator/listener.go @@ -19,13 +19,14 @@ import ( tcp "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/tcp_proxy/v3" udp "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/udp/udp_proxy/v3" tls "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" + "github.com/envoyproxy/go-control-plane/pkg/resource/v3" "github.com/envoyproxy/go-control-plane/pkg/wellknown" "google.golang.org/protobuf/types/known/anypb" "github.com/envoyproxy/gateway/internal/ir" ) -func buildXdsTCPListener(name, address string, port uint32) *listener.Listener { +func buildXdsListener(name, address string, port uint32) *listener.Listener { accesslogAny, _ := anypb.New(stdoutFileAccessLog) return &listener.Listener{ Name: name, @@ -363,3 +364,22 @@ func buildXdsUDPListener(clusterName string, udpListener *ir.UDPListener) (*list return xdsListener, nil } + +// Point to xds cluster. +func makeConfigSource() *core.ConfigSource { + source := &core.ConfigSource{} + source.ResourceApiVersion = resource.DefaultAPIVersion + source.ConfigSourceSpecifier = &core.ConfigSource_ApiConfigSource{ + ApiConfigSource: &core.ApiConfigSource{ + TransportApiVersion: resource.DefaultAPIVersion, + ApiType: core.ApiConfigSource_DELTA_GRPC, + SetNodeOnFirstMessageOnly: true, + GrpcServices: []*core.GrpcService{{ + TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ + EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "xds_cluster"}, + }, + }}, + }, + } + return source +} diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend.yaml new file mode 100644 index 000000000000..e6d314d1f5e9 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend.yaml @@ -0,0 +1,21 @@ +http: +- name: "first-listener" + address: "0.0.0.0" + port: 10080 + hostnames: + - "*" + routes: + - name: "first-route" + destinations: + - host: "1.1.1.1" + port: 50001 + weight: 20 + - host: "2.2.2.2" + port: 50002 + weight: 40 + - host: "3.3.3.3" + port: 50003 + weight: 20 + - host: "4.4.4.4" + port: 50004 + weight: 20 diff --git a/internal/xds/translator/testdata/in/xds-ir/multiple-simple-tcp-route-same-port.yaml b/internal/xds/translator/testdata/in/xds-ir/multiple-simple-tcp-route-same-port.yaml new file mode 100644 index 000000000000..324de2128389 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/multiple-simple-tcp-route-same-port.yaml @@ -0,0 +1,41 @@ +tcp: +- name: "tcp-route-simple" + address: "0.0.0.0" + port: 10080 + destinations: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 +- name: "tcp-route-simple-1" + address: "0.0.0.0" + port: 10080 + destinations: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 +- name: "tcp-route-simple-2" + address: "0.0.0.0" + port: 10080 + destinations: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 +- name: "tcp-route-simple-3" + address: "0.0.0.0" + port: 10080 + destinations: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 +- name: "tcp-route-simple-4" + address: "0.0.0.0" + port: 10080 + destinations: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-route-complex.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-route-complex.yaml new file mode 100644 index 000000000000..1de28530c7d1 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/tcp-route-complex.yaml @@ -0,0 +1,14 @@ +tcp: +- name: "tcp-route-complex" + address: "0.0.0.0" + port: 10080 + tls: + snis: + - foo.com + - bar.com + - example.com + destinations: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-route-simple.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-route-simple.yaml new file mode 100644 index 000000000000..b88d57dd3994 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/tcp-route-simple.yaml @@ -0,0 +1,9 @@ +tcp: +- name: "tcp-route-simple" + address: "0.0.0.0" + port: 10080 + destinations: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-route-weighted-backend.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-route-weighted-backend.yaml new file mode 100644 index 000000000000..81a44d364cb8 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/tcp-route-weighted-backend.yaml @@ -0,0 +1,22 @@ +tcp: +- name: "tcp-route-weighted-backend" + address: "0.0.0.0" + port: 10080 + tls: + snis: + - foo.com + - bar.com + - example.com + destinations: + - host: "1.1.1.1" + port: 50001 + weight: 20 + - host: "2.2.2.2" + port: 50002 + weight: 40 + - host: "3.3.3.3" + port: 50003 + weight: 20 + - host: "4.4.4.4" + port: 50004 + weight: 20 diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.clusters.yaml new file mode 100644 index 000000000000..bb307d77082f --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.clusters.yaml @@ -0,0 +1,37 @@ +- commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 5s + dnsLookupFamily: V4_ONLY + loadAssignment: + clusterName: first-route + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.1.1.1 + portValue: 50001 + loadBalancingWeight: 20 + - endpoint: + address: + socketAddress: + address: 2.2.2.2 + portValue: 50002 + loadBalancingWeight: 40 + - endpoint: + address: + socketAddress: + address: 3.3.3.3 + portValue: 50003 + loadBalancingWeight: 20 + - endpoint: + address: + socketAddress: + address: 4.4.4.4 + portValue: 50004 + loadBalancingWeight: 20 + loadBalancingWeight: 1 + locality: {} + name: first-route + outlierDetection: {} + type: STATIC diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.listeners.yaml new file mode 100644 index 000000000000..6c5555739793 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.listeners.yaml @@ -0,0 +1,40 @@ +- accessLog: + - filter: + responseFlagFilter: + flags: + - NR + name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/stdout + address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + accessLog: + - name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/stdout + httpFilters: + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + rds: + configSource: + apiConfigSource: + apiType: DELTA_GRPC + grpcServices: + - envoyGrpc: + clusterName: xds_cluster + setNodeOnFirstMessageOnly: true + transportApiVersion: V3 + resourceApiVersion: V3 + routeConfigName: first-listener + statPrefix: http + name: first-listener diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.routes.yaml new file mode 100644 index 000000000000..ed122e552aa2 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-route-weighted-backend.routes.yaml @@ -0,0 +1,10 @@ +- name: first-listener + virtualHosts: + - domains: + - '*' + name: first-listener + routes: + - match: + prefix: / + route: + cluster: first-route diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.clusters.yaml new file mode 100644 index 000000000000..9b23924af5a5 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.clusters.yaml @@ -0,0 +1,115 @@ +- commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 5s + dnsLookupFamily: V4_ONLY + loadAssignment: + clusterName: tcp-route-simple + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + - endpoint: + address: + socketAddress: + address: 5.6.7.8 + portValue: 50001 + loadBalancingWeight: 1 + locality: {} + name: tcp-route-simple + outlierDetection: {} + type: STATIC +- commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 5s + dnsLookupFamily: V4_ONLY + loadAssignment: + clusterName: tcp-route-simple-1 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + - endpoint: + address: + socketAddress: + address: 5.6.7.8 + portValue: 50001 + loadBalancingWeight: 1 + locality: {} + name: tcp-route-simple-1 + outlierDetection: {} + type: STATIC +- commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 5s + dnsLookupFamily: V4_ONLY + loadAssignment: + clusterName: tcp-route-simple-2 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + - endpoint: + address: + socketAddress: + address: 5.6.7.8 + portValue: 50001 + loadBalancingWeight: 1 + locality: {} + name: tcp-route-simple-2 + outlierDetection: {} + type: STATIC +- commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 5s + dnsLookupFamily: V4_ONLY + loadAssignment: + clusterName: tcp-route-simple-3 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + - endpoint: + address: + socketAddress: + address: 5.6.7.8 + portValue: 50001 + loadBalancingWeight: 1 + locality: {} + name: tcp-route-simple-3 + outlierDetection: {} + type: STATIC +- commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 5s + dnsLookupFamily: V4_ONLY + loadAssignment: + clusterName: tcp-route-simple-4 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + - endpoint: + address: + socketAddress: + address: 5.6.7.8 + portValue: 50001 + loadBalancingWeight: 1 + locality: {} + name: tcp-route-simple-4 + outlierDetection: {} + type: STATIC diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.listeners.yaml new file mode 100644 index 000000000000..128fd616fca6 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.listeners.yaml @@ -0,0 +1,70 @@ +- accessLog: + - filter: + responseFlagFilter: + flags: + - NR + name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/stdout + address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + filterChains: + - filters: + - name: envoy.filters.network.tcp_proxy + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy + accessLog: + - name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/stdout + cluster: tcp-route-simple + statPrefix: tcp + - filters: + - name: envoy.filters.network.tcp_proxy + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy + accessLog: + - name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/stdout + cluster: tcp-route-simple-1 + statPrefix: tcp + - filters: + - name: envoy.filters.network.tcp_proxy + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy + accessLog: + - name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/stdout + cluster: tcp-route-simple-2 + statPrefix: tcp + - filters: + - name: envoy.filters.network.tcp_proxy + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy + accessLog: + - name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/stdout + cluster: tcp-route-simple-3 + statPrefix: tcp + - filters: + - name: envoy.filters.network.tcp_proxy + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy + accessLog: + - name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/stdout + cluster: tcp-route-simple-4 + statPrefix: tcp + name: tcp-route-simple diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.routes.yaml new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/multiple-simple-tcp-route-same-port.routes.yaml @@ -0,0 +1 @@ +[] diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.clusters.yaml new file mode 100644 index 000000000000..eb1b767d85c2 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.clusters.yaml @@ -0,0 +1,23 @@ +- commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 5s + dnsLookupFamily: V4_ONLY + loadAssignment: + clusterName: tcp-route-complex + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + - endpoint: + address: + socketAddress: + address: 5.6.7.8 + portValue: 50001 + loadBalancingWeight: 1 + locality: {} + name: tcp-route-complex + outlierDetection: {} + type: STATIC diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.listeners.yaml new file mode 100644 index 000000000000..dfb2a30acf0a --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.listeners.yaml @@ -0,0 +1,35 @@ +- accessLog: + - filter: + responseFlagFilter: + flags: + - NR + name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/stdout + address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + filterChains: + - filterChainMatch: + serverNames: + - foo.com + - bar.com + - example.com + filters: + - name: envoy.filters.network.tcp_proxy + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy + accessLog: + - name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/stdout + cluster: tcp-route-complex + statPrefix: passthrough + listenerFilters: + - name: envoy.filters.listener.tls_inspector + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector + name: tcp-route-complex diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.routes.yaml new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-complex.routes.yaml @@ -0,0 +1 @@ +[] diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.clusters.yaml new file mode 100644 index 000000000000..54c0cd9b4b35 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.clusters.yaml @@ -0,0 +1,23 @@ +- commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 5s + dnsLookupFamily: V4_ONLY + loadAssignment: + clusterName: tcp-route-simple + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + - endpoint: + address: + socketAddress: + address: 5.6.7.8 + portValue: 50001 + loadBalancingWeight: 1 + locality: {} + name: tcp-route-simple + outlierDetection: {} + type: STATIC diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.listeners.yaml new file mode 100644 index 000000000000..05e159719fbb --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.listeners.yaml @@ -0,0 +1,26 @@ +- accessLog: + - filter: + responseFlagFilter: + flags: + - NR + name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/stdout + address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + filterChains: + - filters: + - name: envoy.filters.network.tcp_proxy + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy + accessLog: + - name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/stdout + cluster: tcp-route-simple + statPrefix: tcp + name: tcp-route-simple diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.routes.yaml new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-simple.routes.yaml @@ -0,0 +1 @@ +[] diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.clusters.yaml new file mode 100644 index 000000000000..c24165c14ea8 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.clusters.yaml @@ -0,0 +1,37 @@ +- commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 5s + dnsLookupFamily: V4_ONLY + loadAssignment: + clusterName: tcp-route-weighted-backend + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.1.1.1 + portValue: 50001 + loadBalancingWeight: 20 + - endpoint: + address: + socketAddress: + address: 2.2.2.2 + portValue: 50002 + loadBalancingWeight: 40 + - endpoint: + address: + socketAddress: + address: 3.3.3.3 + portValue: 50003 + loadBalancingWeight: 20 + - endpoint: + address: + socketAddress: + address: 4.4.4.4 + portValue: 50004 + loadBalancingWeight: 20 + loadBalancingWeight: 1 + locality: {} + name: tcp-route-weighted-backend + outlierDetection: {} + type: STATIC diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.listeners.yaml new file mode 100644 index 000000000000..e16c3a238494 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.listeners.yaml @@ -0,0 +1,35 @@ +- accessLog: + - filter: + responseFlagFilter: + flags: + - NR + name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/stdout + address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + filterChains: + - filterChainMatch: + serverNames: + - foo.com + - bar.com + - example.com + filters: + - name: envoy.filters.network.tcp_proxy + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy + accessLog: + - name: envoy.access_loggers.file + typedConfig: + '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog + path: /dev/stdout + cluster: tcp-route-weighted-backend + statPrefix: passthrough + listenerFilters: + - name: envoy.filters.listener.tls_inspector + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector + name: tcp-route-weighted-backend diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.routes.yaml new file mode 100644 index 000000000000..fe51488c7066 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-weighted-backend.routes.yaml @@ -0,0 +1 @@ +[] diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index eeaf4a192e1e..612ac0bc6ebe 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -26,14 +26,30 @@ func Translate(ir *ir.Xds) (*types.ResourceVersionTable, error) { tCtx := new(types.ResourceVersionTable) - for _, httpListener := range ir.HTTP { + if err := processHTTPListenerXdsTranslation(tCtx, ir.HTTP); err != nil { + return nil, err + } + + if err := processTCPListenerXdsTranslation(tCtx, ir.TCP); err != nil { + return nil, err + } + + if err := processUDPListenerXdsTranslation(tCtx, ir.UDP); err != nil { + return nil, err + } + + return tCtx, nil +} + +func processHTTPListenerXdsTranslation(tCtx *types.ResourceVersionTable, httpListeners []*ir.HTTPListener) error { + for _, httpListener := range httpListeners { addFilterChain := true var xdsRouteCfg *route.RouteConfiguration // Search for an existing listener, if it does not exist, create one. xdsListener := findXdsListener(tCtx, httpListener.Address, httpListener.Port, core.SocketAddress_TCP) if xdsListener == nil { - xdsListener = buildXdsTCPListener(httpListener.Name, httpListener.Address, httpListener.Port) + xdsListener = buildXdsListener(httpListener.Name, httpListener.Address, httpListener.Port) tCtx.AddXdsResource(resource.ListenerType, xdsListener) } else if httpListener.TLS == nil { // Find the route config associated with this listener that @@ -46,14 +62,14 @@ func Translate(ir *ir.Xds) (*types.ResourceVersionTable, error) { addFilterChain = false xdsRouteCfg = findXdsRouteConfig(tCtx, routeName) if xdsRouteCfg == nil { - return nil, errors.New("unable to find xds route config") + return errors.New("unable to find xds route config") } } } if addFilterChain { if err := addXdsHTTPFilterChain(xdsListener, httpListener); err != nil { - return nil, err + return err } } @@ -69,7 +85,7 @@ func Translate(ir *ir.Xds) (*types.ResourceVersionTable, error) { if httpListener.TLS != nil { secret, err := buildXdsDownstreamTLSSecret(httpListener.Name, httpListener.TLS) if err != nil { - return nil, multierror.Append(err, errors.New("error building xds listener tls secret")) + return multierror.Append(err, errors.New("error building xds listener tls secret")) } tCtx.AddXdsResource(resource.SecretType, secret) } @@ -85,7 +101,7 @@ func Translate(ir *ir.Xds) (*types.ResourceVersionTable, error) { // 1:1 between IR HTTPRoute and xDS config.route.v3.Route xdsRoute, err := buildXdsRoute(httpRoute) if err != nil { - return nil, multierror.Append(err, errors.New("error building xds route")) + return multierror.Append(err, errors.New("error building xds route")) } vHost.Routes = append(vHost.Routes, xdsRoute) @@ -95,40 +111,45 @@ func Translate(ir *ir.Xds) (*types.ResourceVersionTable, error) { } xdsCluster, err := buildXdsCluster(httpRoute.Name, httpRoute.Destinations, httpListener.IsHTTP2) if err != nil { - return nil, multierror.Append(err, errors.New("error building xds cluster")) + return multierror.Append(err, errors.New("error building xds cluster")) } tCtx.AddXdsResource(resource.ClusterType, xdsCluster) - } xdsRouteCfg.VirtualHosts = append(xdsRouteCfg.VirtualHosts, vHost) } + return nil +} - for _, tcpListener := range ir.TCP { +func processTCPListenerXdsTranslation(tCtx *types.ResourceVersionTable, tcpListeners []*ir.TCPListener) error { + for _, tcpListener := range tcpListeners { // 1:1 between IR TCPListener and xDS Cluster xdsCluster, err := buildXdsCluster(tcpListener.Name, tcpListener.Destinations, false /*isHTTP2 */) if err != nil { - return nil, multierror.Append(err, errors.New("error building xds cluster")) + return multierror.Append(err, errors.New("error building xds cluster")) } tCtx.AddXdsResource(resource.ClusterType, xdsCluster) // Search for an existing listener, if it does not exist, create one. xdsListener := findXdsListener(tCtx, tcpListener.Address, tcpListener.Port, core.SocketAddress_TCP) if xdsListener == nil { - xdsListener = buildXdsTCPListener(tcpListener.Name, tcpListener.Address, tcpListener.Port) + xdsListener = buildXdsListener(tcpListener.Name, tcpListener.Address, tcpListener.Port) tCtx.AddXdsResource(resource.ListenerType, xdsListener) } if err := addXdsTCPFilterChain(xdsListener, tcpListener, xdsCluster.Name); err != nil { - return nil, err + return err } } + return nil +} - for _, udpListener := range ir.UDP { +func processUDPListenerXdsTranslation(tCtx *types.ResourceVersionTable, udpListeners []*ir.UDPListener) error { + for _, udpListener := range udpListeners { // 1:1 between IR UDPListener and xDS Cluster xdsCluster, err := buildXdsCluster(udpListener.Name, udpListener.Destinations, false /*isHTTP2 */) if err != nil { - return nil, multierror.Append(err, errors.New("error building xds cluster")) + return multierror.Append(err, errors.New("error building xds cluster")) } tCtx.AddXdsResource(resource.ClusterType, xdsCluster) @@ -136,11 +157,11 @@ func Translate(ir *ir.Xds) (*types.ResourceVersionTable, error) { // translator xdsListener, err := buildXdsUDPListener(xdsCluster.Name, udpListener) if err != nil { - return nil, multierror.Append(err, errors.New("error building xds cluster")) + return multierror.Append(err, errors.New("error building xds cluster")) } tCtx.AddXdsResource(resource.ListenerType, xdsListener) } - return tCtx, nil + return nil } // findXdsListener finds a xds listener with the same address, port and protocol, and returns nil if there is no match. @@ -177,22 +198,3 @@ func findXdsRouteConfig(tCtx *types.ResourceVersionTable, name string) *route.Ro return nil } - -// Point to xds cluster. -func makeConfigSource() *core.ConfigSource { - source := &core.ConfigSource{} - source.ResourceApiVersion = resource.DefaultAPIVersion - source.ConfigSourceSpecifier = &core.ConfigSource_ApiConfigSource{ - ApiConfigSource: &core.ApiConfigSource{ - TransportApiVersion: resource.DefaultAPIVersion, - ApiType: core.ApiConfigSource_DELTA_GRPC, - SetNodeOnFirstMessageOnly: true, - GrpcServices: []*core.GrpcService{{ - TargetSpecifier: &core.GrpcService_EnvoyGrpc_{ - EnvoyGrpc: &core.GrpcService_EnvoyGrpc{ClusterName: "xds_cluster"}, - }, - }}, - }, - } - return source -} diff --git a/internal/xds/translator/translator_test.go b/internal/xds/translator/translator_test.go index 5591363f8150..7bb305f337bc 100644 --- a/internal/xds/translator/translator_test.go +++ b/internal/xds/translator/translator_test.go @@ -58,6 +58,21 @@ func TestTranslate(t *testing.T) { { name: "tls-route-passthrough", }, + { + name: "tcp-route-simple", + }, + { + name: "tcp-route-complex", + }, + { + name: "multiple-simple-tcp-route-same-port", + }, + { + name: "http-route-weighted-backend", + }, + { + name: "tcp-route-weighted-backend", + }, { name: "multiple-listeners-same-port", requireSecrets: true,