Merge pull request #9042 from lawliet89/tg-rewrite

pull/9910/head
Freddy 4 years ago committed by GitHub
commit e385e5992f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,3 @@
```release-note:improvement
connect: Automatically rewrite the Host header for Terminating Gateway HTTP services
```

@ -104,7 +104,7 @@ func (s *Server) routesFromSnapshotTerminatingGateway(_ connectionInfo, cfgSnap
if resolver.LoadBalancer != nil { if resolver.LoadBalancer != nil {
lb = resolver.LoadBalancer lb = resolver.LoadBalancer
} }
route, err := makeNamedDefaultRouteWithLB(clusterName, lb) route, err := makeNamedDefaultRouteWithLB(clusterName, lb, true)
if err != nil { if err != nil {
logger.Error("failed to make route", "cluster", clusterName, "error", err) logger.Error("failed to make route", "cluster", clusterName, "error", err)
continue continue
@ -114,7 +114,7 @@ func (s *Server) routesFromSnapshotTerminatingGateway(_ connectionInfo, cfgSnap
// If there is a service-resolver for this service then also setup routes for each subset // If there is a service-resolver for this service then also setup routes for each subset
for name := range resolver.Subsets { for name := range resolver.Subsets {
clusterName = connect.ServiceSNI(svc.Name, name, svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain) clusterName = connect.ServiceSNI(svc.Name, name, svc.NamespaceOrDefault(), cfgSnap.Datacenter, cfgSnap.Roots.TrustDomain)
route, err := makeNamedDefaultRouteWithLB(clusterName, lb) route, err := makeNamedDefaultRouteWithLB(clusterName, lb, true)
if err != nil { if err != nil {
logger.Error("failed to make route", "cluster", clusterName, "error", err) logger.Error("failed to make route", "cluster", clusterName, "error", err)
continue continue
@ -126,13 +126,20 @@ func (s *Server) routesFromSnapshotTerminatingGateway(_ connectionInfo, cfgSnap
return resources, nil return resources, nil
} }
func makeNamedDefaultRouteWithLB(clusterName string, lb *structs.LoadBalancer) (*envoy_route_v3.RouteConfiguration, error) { func makeNamedDefaultRouteWithLB(clusterName string, lb *structs.LoadBalancer, autoHostRewrite bool) (*envoy_route_v3.RouteConfiguration, error) {
action := makeRouteActionFromName(clusterName) action := makeRouteActionFromName(clusterName)
if err := injectLBToRouteAction(lb, action.Route); err != nil { if err := injectLBToRouteAction(lb, action.Route); err != nil {
return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err) return nil, fmt.Errorf("failed to apply load balancer configuration to route action: %v", err)
} }
// Configure Envoy to rewrite Host header
if autoHostRewrite {
action.Route.HostRewriteSpecifier = &envoy_route_v3.RouteAction_AutoHostRewrite{
AutoHostRewrite: makeBoolValue(true),
}
}
return &envoy_route_v3.RouteConfiguration{ return &envoy_route_v3.RouteConfiguration{
Name: clusterName, Name: clusterName,
VirtualHosts: []*envoy_route_v3.VirtualHost{ VirtualHosts: []*envoy_route_v3.VirtualHost{

@ -16,6 +16,7 @@
"prefix": "/" "prefix": "/"
}, },
"route": { "route": {
"autoHostRewrite": true,
"cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
"hashPolicy": [ "hashPolicy": [
{ {
@ -58,6 +59,7 @@
"prefix": "/" "prefix": "/"
}, },
"route": { "route": {
"autoHostRewrite": true,
"cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
"hashPolicy": [ "hashPolicy": [
{ {
@ -100,6 +102,7 @@
"prefix": "/" "prefix": "/"
}, },
"route": { "route": {
"autoHostRewrite": true,
"cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
"hashPolicy": [ "hashPolicy": [
{ {
@ -130,4 +133,4 @@
], ],
"typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration",
"nonce": "00000001" "nonce": "00000001"
} }

@ -16,6 +16,7 @@
"prefix": "/" "prefix": "/"
}, },
"route": { "route": {
"autoHostRewrite": true,
"cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "cluster": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
"hashPolicy": [ "hashPolicy": [
{ {
@ -58,6 +59,7 @@
"prefix": "/" "prefix": "/"
}, },
"route": { "route": {
"autoHostRewrite": true,
"cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "cluster": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
"hashPolicy": [ "hashPolicy": [
{ {
@ -100,6 +102,7 @@
"prefix": "/" "prefix": "/"
}, },
"route": { "route": {
"autoHostRewrite": true,
"cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", "cluster": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
"hashPolicy": [ "hashPolicy": [
{ {
@ -130,4 +133,4 @@
], ],
"typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration", "typeUrl": "type.googleapis.com/envoy.api.v2.RouteConfiguration",
"nonce": "00000001" "nonce": "00000001"
} }

@ -9,4 +9,9 @@ config_entries {
} }
] ]
} }
bootstrap {
kind = "service-defaults"
name = "s4"
protocol = "http"
}
} }

@ -31,3 +31,9 @@ load helpers
@test "terminating-gateway is used for the upstream connection" { @test "terminating-gateway is used for the upstream connection" {
assert_envoy_metric_at_least 127.0.0.1:20000 "s4.default.primary.*cx_total" 1 assert_envoy_metric_at_least 127.0.0.1:20000 "s4.default.primary.*cx_total" 1
} }
@test "terminating-gateway adds the Host header for connection to s3" {
# Envoy does not rewrite the port
# See https://github.com/envoyproxy/envoy/pull/504#discussion_r102614466
assert_expected_fortio_host_header "localhost" localhost 5000
}

@ -848,3 +848,33 @@ function assert_expected_fortio_name_pattern {
return 1 return 1
fi fi
} }
function get_upstream_fortio_host_header {
local HOST=$1
local PORT=$2
local PREFIX=$3
local DEBUG_HEADER_VALUE="${4:-""}"
local extra_args
if [[ -n "${DEBUG_HEADER_VALUE}" ]]; then
extra_args="-H x-test-debug:${DEBUG_HEADER_VALUE}"
fi
run retry_default curl -v -s -f -H"Host: ${HOST}" $extra_args \
"localhost:${PORT}${PREFIX}/debug"
[ "$status" == 0 ]
echo "$output" | grep -E "^Host: "
}
function assert_expected_fortio_host_header {
local EXPECT_HOST=$1
local HOST=${2:-"localhost"}
local PORT=${3:-5000}
local URL_PREFIX=${4:-""}
local DEBUG_HEADER_VALUE="${5:-""}"
GOT=$(get_upstream_fortio_host_header ${HOST} ${PORT} "${URL_PREFIX}" "${DEBUG_HEADER_VALUE}")
if [ "$GOT" != "Host: ${EXPECT_HOST}" ]; then
echo "expected Host header: $EXPECT_HOST, actual Host header: $GOT" 1>&2
return 1
fi
}

Loading…
Cancel
Save