mirror of https://github.com/hashicorp/consul
Merge pull request #13699 from hashicorp/tgate-http2-upstream
Respect http2 protocol for upstreams of terminating gatewayspull/13760/head
commit
9097e2b0f0
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:bug
|
||||||
|
xds: Fix a bug where terminating gateway upstream clusters weren't configured properly when the service protocol was `http2`.
|
||||||
|
```
|
|
@ -633,6 +633,123 @@ func TestConfigSnapshotTerminatingGatewaySNI(t testing.T) *ConfigSnapshot {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConfigSnapshotTerminatingGatewayHTTP2(t testing.T) *ConfigSnapshot {
|
||||||
|
web := structs.NewServiceName("web", nil)
|
||||||
|
|
||||||
|
return TestConfigSnapshotTerminatingGateway(t, false, nil, []UpdateEvent{
|
||||||
|
{
|
||||||
|
CorrelationID: gatewayServicesWatchID,
|
||||||
|
Result: &structs.IndexedGatewayServices{
|
||||||
|
Services: []*structs.GatewayService{
|
||||||
|
{
|
||||||
|
Service: web,
|
||||||
|
CAFile: "ca.cert.pem",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CorrelationID: serviceConfigIDPrefix + web.String(),
|
||||||
|
Result: &structs.ServiceConfigResponse{
|
||||||
|
ProxyConfig: map[string]interface{}{"protocol": "http2"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CorrelationID: externalServiceIDPrefix + web.String(),
|
||||||
|
Result: &structs.IndexedCheckServiceNodes{
|
||||||
|
Nodes: []structs.CheckServiceNode{
|
||||||
|
{
|
||||||
|
Node: &structs.Node{
|
||||||
|
ID: "external",
|
||||||
|
Node: "external",
|
||||||
|
Address: "web.external.service",
|
||||||
|
Datacenter: "dc1",
|
||||||
|
},
|
||||||
|
Service: &structs.NodeService{
|
||||||
|
Service: "web",
|
||||||
|
Port: 9090,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConfigSnapshotTerminatingGatewaySubsetsHTTP2(t testing.T) *ConfigSnapshot {
|
||||||
|
web := structs.NewServiceName("web", nil)
|
||||||
|
|
||||||
|
return TestConfigSnapshotTerminatingGateway(t, false, nil, []UpdateEvent{
|
||||||
|
{
|
||||||
|
CorrelationID: serviceResolverIDPrefix + web.String(),
|
||||||
|
Result: &structs.ConfigEntryResponse{
|
||||||
|
Entry: &structs.ServiceResolverConfigEntry{
|
||||||
|
Kind: structs.ServiceResolver,
|
||||||
|
Name: "web",
|
||||||
|
Subsets: map[string]structs.ServiceResolverSubset{
|
||||||
|
"v1": {
|
||||||
|
Filter: "Service.Meta.version == 1",
|
||||||
|
},
|
||||||
|
"v2": {
|
||||||
|
Filter: "Service.Meta.version == 2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CorrelationID: gatewayServicesWatchID,
|
||||||
|
Result: &structs.IndexedGatewayServices{
|
||||||
|
Services: []*structs.GatewayService{
|
||||||
|
{
|
||||||
|
Service: web,
|
||||||
|
CAFile: "ca.cert.pem",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CorrelationID: serviceConfigIDPrefix + web.String(),
|
||||||
|
Result: &structs.ServiceConfigResponse{
|
||||||
|
ProxyConfig: map[string]interface{}{"protocol": "http2"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CorrelationID: externalServiceIDPrefix + web.String(),
|
||||||
|
Result: &structs.IndexedCheckServiceNodes{
|
||||||
|
Nodes: []structs.CheckServiceNode{
|
||||||
|
{
|
||||||
|
Node: &structs.Node{
|
||||||
|
ID: "external",
|
||||||
|
Node: "external",
|
||||||
|
Address: "web.external.service",
|
||||||
|
Datacenter: "dc1",
|
||||||
|
},
|
||||||
|
Service: &structs.NodeService{
|
||||||
|
Service: "web",
|
||||||
|
Port: 9090,
|
||||||
|
Meta: map[string]string{"version": "1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Node: &structs.Node{
|
||||||
|
ID: "external2",
|
||||||
|
Node: "external2",
|
||||||
|
Address: "web.external2.service",
|
||||||
|
Datacenter: "dc1",
|
||||||
|
},
|
||||||
|
Service: &structs.NodeService{
|
||||||
|
Service: "web",
|
||||||
|
Port: 9091,
|
||||||
|
Meta: map[string]string{"version": "2"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestConfigSnapshotTerminatingGatewayHostnameSubsets(t testing.T) *ConfigSnapshot {
|
func TestConfigSnapshotTerminatingGatewayHostnameSubsets(t testing.T) *ConfigSnapshot {
|
||||||
var (
|
var (
|
||||||
api = structs.NewServiceName("api", nil)
|
api = structs.NewServiceName("api", nil)
|
||||||
|
|
|
@ -425,6 +425,24 @@ func (s *ResourceGenerator) makeGatewayServiceClusters(
|
||||||
}
|
}
|
||||||
clusters = append(clusters, cluster)
|
clusters = append(clusters, cluster)
|
||||||
|
|
||||||
|
svcConfig, ok := cfgSnap.TerminatingGateway.ServiceConfigs[svc]
|
||||||
|
isHTTP2 := false
|
||||||
|
if ok {
|
||||||
|
upstreamCfg, err := structs.ParseUpstreamConfig(svcConfig.ProxyConfig)
|
||||||
|
if err != nil {
|
||||||
|
// Don't hard fail on a config typo, just warn. The parse func returns
|
||||||
|
// default config if there is an error so it's safe to continue.
|
||||||
|
s.Logger.Warn("failed to parse", "upstream", svc, "error", err)
|
||||||
|
}
|
||||||
|
isHTTP2 = upstreamCfg.Protocol == "http2" || upstreamCfg.Protocol == "grpc"
|
||||||
|
}
|
||||||
|
|
||||||
|
if isHTTP2 {
|
||||||
|
if err := s.setHttp2ProtocolOptions(cluster); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If there is a service-resolver for this service then also setup a cluster for each subset
|
// If there is a service-resolver for this service then also setup a cluster for each subset
|
||||||
for name, subset := range resolver.Subsets {
|
for name, subset := range resolver.Subsets {
|
||||||
subsetHostnameEndpoints, err := s.filterSubsetEndpoints(&subset, hostnameEndpoints)
|
subsetHostnameEndpoints, err := s.filterSubsetEndpoints(&subset, hostnameEndpoints)
|
||||||
|
@ -444,6 +462,11 @@ func (s *ResourceGenerator) makeGatewayServiceClusters(
|
||||||
if err := s.injectGatewayServiceAddons(cfgSnap, cluster, svc, loadBalancer); err != nil {
|
if err := s.injectGatewayServiceAddons(cfgSnap, cluster, svc, loadBalancer); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if isHTTP2 {
|
||||||
|
if err := s.setHttp2ProtocolOptions(cluster); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
clusters = append(clusters, cluster)
|
clusters = append(clusters, cluster)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -589,6 +589,14 @@ func TestClustersFromSnapshot(t *testing.T) {
|
||||||
name: "terminating-gateway-sni",
|
name: "terminating-gateway-sni",
|
||||||
create: proxycfg.TestConfigSnapshotTerminatingGatewaySNI,
|
create: proxycfg.TestConfigSnapshotTerminatingGatewaySNI,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "terminating-gateway-http2-upstream",
|
||||||
|
create: proxycfg.TestConfigSnapshotTerminatingGatewayHTTP2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "terminating-gateway-http2-upstream-subsets",
|
||||||
|
create: proxycfg.TestConfigSnapshotTerminatingGatewaySubsetsHTTP2,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "terminating-gateway-ignore-extra-resolvers",
|
name: "terminating-gateway-ignore-extra-resolvers",
|
||||||
create: proxycfg.TestConfigSnapshotTerminatingGatewayIgnoreExtraResolvers,
|
create: proxycfg.TestConfigSnapshotTerminatingGatewayIgnoreExtraResolvers,
|
||||||
|
|
181
agent/xds/testdata/clusters/terminating-gateway-http2-upstream-subsets.latest.golden
vendored
Normal file
181
agent/xds/testdata/clusters/terminating-gateway-http2-upstream-subsets.latest.golden
vendored
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||||
|
"name": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "LOGICAL_DNS",
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"loadAssignment": {
|
||||||
|
"clusterName": "v1.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "web.external.service",
|
||||||
|
"portValue": 9090
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"typedExtensionProtocolOptions": {
|
||||||
|
"envoy.extensions.upstreams.http.v3.HttpProtocolOptions": {
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions",
|
||||||
|
"explicitHttpConfig": {
|
||||||
|
"http2ProtocolOptions": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dnsRefreshRate": "10s",
|
||||||
|
"dnsLookupFamily": "V4_ONLY",
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"transportSocket": {
|
||||||
|
"name": "tls",
|
||||||
|
"typedConfig": {
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"validationContext": {
|
||||||
|
"trustedCa": {
|
||||||
|
"filename": "ca.cert.pem"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||||
|
"name": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "LOGICAL_DNS",
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"loadAssignment": {
|
||||||
|
"clusterName": "v2.web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "web.external2.service",
|
||||||
|
"portValue": 9091
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"typedExtensionProtocolOptions": {
|
||||||
|
"envoy.extensions.upstreams.http.v3.HttpProtocolOptions": {
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions",
|
||||||
|
"explicitHttpConfig": {
|
||||||
|
"http2ProtocolOptions": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dnsRefreshRate": "10s",
|
||||||
|
"dnsLookupFamily": "V4_ONLY",
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"transportSocket": {
|
||||||
|
"name": "tls",
|
||||||
|
"typedConfig": {
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"validationContext": {
|
||||||
|
"trustedCa": {
|
||||||
|
"filename": "ca.cert.pem"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||||
|
"name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "LOGICAL_DNS",
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"loadAssignment": {
|
||||||
|
"clusterName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "web.external.service",
|
||||||
|
"portValue": 9090
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"typedExtensionProtocolOptions": {
|
||||||
|
"envoy.extensions.upstreams.http.v3.HttpProtocolOptions": {
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions",
|
||||||
|
"explicitHttpConfig": {
|
||||||
|
"http2ProtocolOptions": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dnsRefreshRate": "10s",
|
||||||
|
"dnsLookupFamily": "V4_ONLY",
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"transportSocket": {
|
||||||
|
"name": "tls",
|
||||||
|
"typedConfig": {
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"validationContext": {
|
||||||
|
"trustedCa": {
|
||||||
|
"filename": "ca.cert.pem"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
65
agent/xds/testdata/clusters/terminating-gateway-http2-upstream.latest.golden
vendored
Normal file
65
agent/xds/testdata/clusters/terminating-gateway-http2-upstream.latest.golden
vendored
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
{
|
||||||
|
"versionInfo": "00000001",
|
||||||
|
"resources": [
|
||||||
|
{
|
||||||
|
"@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||||
|
"name": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"type": "LOGICAL_DNS",
|
||||||
|
"connectTimeout": "5s",
|
||||||
|
"loadAssignment": {
|
||||||
|
"clusterName": "web.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul",
|
||||||
|
"endpoints": [
|
||||||
|
{
|
||||||
|
"lbEndpoints": [
|
||||||
|
{
|
||||||
|
"endpoint": {
|
||||||
|
"address": {
|
||||||
|
"socketAddress": {
|
||||||
|
"address": "web.external.service",
|
||||||
|
"portValue": 9090
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"healthStatus": "HEALTHY",
|
||||||
|
"loadBalancingWeight": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"typedExtensionProtocolOptions": {
|
||||||
|
"envoy.extensions.upstreams.http.v3.HttpProtocolOptions": {
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions",
|
||||||
|
"explicitHttpConfig": {
|
||||||
|
"http2ProtocolOptions": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dnsRefreshRate": "10s",
|
||||||
|
"dnsLookupFamily": "V4_ONLY",
|
||||||
|
"outlierDetection": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"transportSocket": {
|
||||||
|
"name": "tls",
|
||||||
|
"typedConfig": {
|
||||||
|
"@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
|
||||||
|
"commonTlsContext": {
|
||||||
|
"tlsParams": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"validationContext": {
|
||||||
|
"trustedCa": {
|
||||||
|
"filename": "ca.cert.pem"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster",
|
||||||
|
"nonce": "00000001"
|
||||||
|
}
|
Loading…
Reference in New Issue