xds: mesh gateway CDS requests are now allowed to receive an empty CDS reply (#6787)

This is the rest of the fix for #6543 that was incompletely fixed in #6576.
This commit is contained in:
R.B. Boyer 2019-11-26 15:55:13 -06:00 committed by GitHub
parent d7a4347307
commit a9343db838
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 40 additions and 4 deletions

View File

@ -83,7 +83,7 @@ func (s *ConfigSnapshot) Valid() bool {
case structs.ServiceKindConnectProxy: case structs.ServiceKindConnectProxy:
return s.Roots != nil && s.ConnectProxy.Leaf != nil return s.Roots != nil && s.ConnectProxy.Leaf != nil
case structs.ServiceKindMeshGateway: case structs.ServiceKindMeshGateway:
return s.Roots != nil && (s.MeshGateway.WatchedServicesSet || len(s.MeshGateway.WatchedServices) > 0) return s.Roots != nil && (s.MeshGateway.WatchedServicesSet || len(s.MeshGateway.ServiceGroups) > 0)
default: default:
return false return false
} }

View File

@ -215,6 +215,10 @@ func (s *Server) process(stream ADSStream, reqCh <-chan *envoy.DiscoveryRequest)
typeURL: ClusterType, typeURL: ClusterType,
resources: s.clustersFromSnapshot, resources: s.clustersFromSnapshot,
stream: stream, stream: stream,
allowEmptyFn: func(cfgSnap *proxycfg.ConfigSnapshot) bool {
// Mesh gateways are allowed to inform CDS of no clusters.
return cfgSnap.Kind == structs.ServiceKindMeshGateway
},
}, },
RouteType: &xDSType{ RouteType: &xDSType{
typeURL: RouteType, typeURL: RouteType,
@ -370,8 +374,9 @@ type xDSType struct {
// previous request we already responded to and 2) if the proxy rejected the // previous request we already responded to and 2) if the proxy rejected the
// last version we sent with a Nack then req.VersionInfo will be the older // last version we sent with a Nack then req.VersionInfo will be the older
// version it's hanging on to. // version it's hanging on to.
lastVersion uint64 lastVersion uint64
resources func(cfgSnap *proxycfg.ConfigSnapshot, token string) ([]proto.Message, error) resources func(cfgSnap *proxycfg.ConfigSnapshot, token string) ([]proto.Message, error)
allowEmptyFn func(cfgSnap *proxycfg.ConfigSnapshot) bool
} }
func (t *xDSType) Recv(req *envoy.DiscoveryRequest) { func (t *xDSType) Recv(req *envoy.DiscoveryRequest) {
@ -392,13 +397,16 @@ func (t *xDSType) SendIfNew(cfgSnap *proxycfg.ConfigSnapshot, version uint64, no
if err != nil { if err != nil {
return err return err
} }
allowEmpty := t.allowEmptyFn != nil && t.allowEmptyFn(cfgSnap)
// Zero length resource responses should be ignored and are the result of no // Zero length resource responses should be ignored and are the result of no
// data yet. Notice that this caused a bug originally where we had zero // data yet. Notice that this caused a bug originally where we had zero
// healthy endpoints for an upstream that would cause Envoy to hang waiting // healthy endpoints for an upstream that would cause Envoy to hang waiting
// for the EDS response. This is fixed though by ensuring we send an explicit // for the EDS response. This is fixed though by ensuring we send an explicit
// empty LoadAssignment resource for the cluster rather than allowing junky // empty LoadAssignment resource for the cluster rather than allowing junky
// empty resources. // empty resources.
if len(resources) == 0 { if len(resources) == 0 && !allowEmpty {
// Nothing to send yet // Nothing to send yet
return nil return nil
} }

View File

@ -0,0 +1,2 @@
bind_addr = "0.0.0.0"
advertise_addr = "{{ GetInterfaceIP \"eth0\" }}"

View File

@ -0,0 +1,5 @@
services {
name = "mesh-gateway"
kind = "mesh-gateway"
port = 4431
}

View File

@ -0,0 +1 @@
# We don't want an s1 service

View File

@ -0,0 +1 @@
# We don't want an s2 service

View File

@ -0,0 +1,5 @@
#!/bin/bash
set -eEuo pipefail
gen_envoy_bootstrap mesh-gateway 19000 primary true

View File

@ -0,0 +1,3 @@
#!/bin/bash
export REQUIRED_SERVICES="gateway-primary"

View File

@ -0,0 +1,11 @@
#!/usr/bin/env bats
load helpers
@test "gateway-primary proxy admin is up on :19000" {
retry_default curl -f -s localhost:19000/stats -o /dev/null
}
@test "gateway-primary listener is up on :4431" {
retry_default nc -z localhost:4431
}