Skip to content

Commit 3012391

Browse files
authored
xds: move env var check for HTTP CONNECT metadata parsing to endpoint and locality parsing functions (#8551)
Currently, the env var check for parsing HTTP CONNECT metadata (A86) is inside the function that parses custom metadata, `validateAndConstructMetadata`. This PR moves the check to the endpoint and locality parsing functions, `parseEndpoint` and the top-level `parseEDSRespProto` which is where localities are parsed. This allows multiple env vars to control different custom metadata keys. We already support two custom metadata keys (A76 and A86) and we plan to support more (A83). This PR also ensures that the custom metadata used for ring_hash key (A76) uses the recently added `StructMetadataValue` type. This ensures that metadata parsing happens only once. Since the location of the env var check is moved, the tests are also restructured a little. This PR groups the custom metadata parsing tests into three groups: one for success cases when the env var is turned on, one for success cases when the env var is turned off, and one for failure cases when the env var is turned on. RELEASE NOTES: none
1 parent 85c47b3 commit 3012391

File tree

2 files changed

+746
-262
lines changed

2 files changed

+746
-262
lines changed

internal/xds/xdsclient/xdsresource/unmarshal_eds.go

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -108,35 +108,42 @@ func parseEndpoints(lbEndpoints []*v3endpointpb.LbEndpoint, uniqueEndpointAddrs
108108
}
109109
uniqueEndpointAddrs[a] = true
110110
}
111-
endpointMetadata, err := validateAndConstructMetadata(lbEndpoint.GetMetadata())
112-
if err != nil {
113-
return nil, err
111+
112+
var endpointMetadata map[string]any
113+
var hashKey string
114+
if envconfig.XDSHTTPConnectEnabled || !envconfig.XDSEndpointHashKeyBackwardCompat {
115+
var err error
116+
endpointMetadata, err = validateAndConstructMetadata(lbEndpoint.GetMetadata())
117+
if err != nil {
118+
return nil, err
119+
}
120+
121+
// "The xDS resolver, described in A74, will be changed to set the hash_key
122+
// endpoint attribute to the value of LbEndpoint.Metadata envoy.lb hash_key
123+
// field, as described in Envoy's documentation for the ring hash load
124+
// balancer." - A76
125+
if !envconfig.XDSEndpointHashKeyBackwardCompat {
126+
hashKey = hashKeyFromMetadata(endpointMetadata)
127+
}
114128
}
115129
endpoints = append(endpoints, Endpoint{
116130
HealthStatus: EndpointHealthStatus(lbEndpoint.GetHealthStatus()),
117131
Addresses: addrs,
118132
Weight: weight,
119-
HashKey: hashKey(lbEndpoint),
133+
HashKey: hashKey,
120134
Metadata: endpointMetadata,
121135
})
122136
}
123137
return endpoints, nil
124138
}
125139

126-
// hashKey extracts and returns the hash key from the given LbEndpoint. If no
127-
// hash key is found, it returns an empty string.
128-
func hashKey(lbEndpoint *v3endpointpb.LbEndpoint) string {
129-
// "The xDS resolver, described in A74, will be changed to set the hash_key
130-
// endpoint attribute to the value of LbEndpoint.Metadata envoy.lb hash_key
131-
// field, as described in Envoy's documentation for the ring hash load
132-
// balancer." - A76
133-
if envconfig.XDSEndpointHashKeyBackwardCompat {
134-
return ""
135-
}
136-
envoyLB := lbEndpoint.GetMetadata().GetFilterMetadata()["envoy.lb"]
137-
if envoyLB != nil {
138-
if h := envoyLB.GetFields()["hash_key"]; h != nil {
139-
return h.GetStringValue()
140+
// hashKey extracts and returns the hash key from the given endpoint metadata.
141+
// If no hash key is found, it returns an empty string.
142+
func hashKeyFromMetadata(metadata map[string]any) string {
143+
envoyLB, ok := metadata["envoy.lb"].(StructMetadataValue)
144+
if ok {
145+
if h, ok := envoyLB.Data["hash_key"].(string); ok {
146+
return h
140147
}
141148
}
142149
return ""
@@ -195,9 +202,13 @@ func parseEDSRespProto(m *v3endpointpb.ClusterLoadAssignment) (EndpointsUpdate,
195202
if err != nil {
196203
return EndpointsUpdate{}, err
197204
}
198-
localityMetadata, err := validateAndConstructMetadata(locality.GetMetadata())
199-
if err != nil {
200-
return EndpointsUpdate{}, err
205+
var localityMetadata map[string]any
206+
if envconfig.XDSHTTPConnectEnabled {
207+
var err error
208+
localityMetadata, err = validateAndConstructMetadata(locality.GetMetadata())
209+
if err != nil {
210+
return EndpointsUpdate{}, err
211+
}
201212
}
202213

203214
ret.Localities = append(ret.Localities, Locality{
@@ -217,9 +228,7 @@ func parseEDSRespProto(m *v3endpointpb.ClusterLoadAssignment) (EndpointsUpdate,
217228
}
218229

219230
func validateAndConstructMetadata(metadataProto *v3corepb.Metadata) (map[string]any, error) {
220-
// TODO(easwars): Find a better place for the environment variable check
221-
// once A83 is implemented.
222-
if !envconfig.XDSHTTPConnectEnabled || metadataProto == nil {
231+
if metadataProto == nil {
223232
return nil, nil
224233
}
225234
metadata := make(map[string]any)

0 commit comments

Comments
 (0)