Skip to content

Commit 953951f

Browse files
authored
fix: handles weight zero backendRef gracefully (#1755)
**Description** Envoy Gateway skips the weight zero backendRef when constructing localityLbEndoints slices. This starts handling such cases gracefully rather than taking them as errors. **Related Issues/PRs (if applicable)** Close #1664 Supersedes #1694 --------- Signed-off-by: Takeshi Yoneda <t.y.mathetake@gmail.com>
1 parent 6294825 commit 953951f

File tree

3 files changed

+21
-11
lines changed

3 files changed

+21
-11
lines changed

internal/extensionserver/extensionserver_test.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ func Test_maybeModifyCluster(t *testing.T) {
122122
{
123123
BackendRefs: []aigv1a1.AIGatewayRouteRuleBackendRef{
124124
{Name: "aaa", Priority: ptr.To[uint32](0)},
125+
{Name: "to-be-ignored", Weight: ptr.To[int32](0)},
125126
{Name: "bbb", Priority: ptr.To[uint32](1)},
126127
},
127128
},
@@ -144,10 +145,6 @@ func Test_maybeModifyCluster(t *testing.T) {
144145
{c: &clusterv3.Cluster{
145146
Name: "httproute/ns/myroute/rule/0",
146147
}, errLog: `LoadAssignment is nil`},
147-
{c: &clusterv3.Cluster{
148-
Name: "httproute/ns/myroute/rule/0",
149-
LoadAssignment: &endpointv3.ClusterLoadAssignment{},
150-
}, errLog: `LoadAssignment endpoints length does not match backend refs length`},
151148
} {
152149
t.Run("error/"+tc.errLog, func(t *testing.T) {
153150
var buf bytes.Buffer

internal/extensionserver/post_translate_modify.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -207,14 +207,16 @@ func (s *Server) maybeModifyCluster(cluster *clusterv3.Cluster) error {
207207
s.log.Info("LoadAssignment is nil", "cluster_name", cluster.Name)
208208
return nil
209209
}
210-
if len(cluster.LoadAssignment.Endpoints) != len(httpRouteRule.BackendRefs) {
211-
s.log.Info("LoadAssignment endpoints length does not match backend refs length",
212-
"cluster_name", cluster.Name, "endpoints_length", len(cluster.LoadAssignment.Endpoints), "backend_refs_length", len(httpRouteRule.BackendRefs))
213-
return nil
214-
}
215210
// Populate the metadata for each endpoint in the LoadAssignment.
216-
for i, endpoints := range cluster.LoadAssignment.Endpoints {
217-
backendRef := httpRouteRule.BackendRefs[i]
211+
var lbEndpointIndex int
212+
for i, backendRef := range httpRouteRule.BackendRefs {
213+
// The weight of 0 means this backend is disabled and is not included in the LoadAssignment by EG,
214+
// so we skip it here.
215+
if backendRef.Weight != nil && *backendRef.Weight == 0 {
216+
continue
217+
}
218+
endpoints := cluster.LoadAssignment.Endpoints[lbEndpointIndex]
219+
lbEndpointIndex++
218220
name := backendRef.Name
219221
namespace := aigwRoute.Namespace
220222
if backendRef.Priority != nil {

tests/e2e/testdata/testupstream.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ spec:
5252
kind: Gateway
5353
group: gateway.networking.k8s.io
5454
rules:
55+
# The backend refs with weight zero should be ignored by the extension server.
56+
# See https://github.com/envoyproxy/ai-gateway/issues/1664
5557
- matches:
5658
- headers:
5759
- type: Exact
@@ -65,14 +67,23 @@ spec:
6567
name: x-ai-eg-model
6668
value: another-cool-model
6769
backendRefs:
70+
- name: translation-testupstream-cool-model-backend
71+
weight: 0
6872
- name: translation-testupstream-another-cool-model-backend
73+
weight: 100
74+
- name: translation-testupstream-cool-model-backend
75+
weight: 0
76+
- name: translation-testupstream-cool-model-backend
77+
weight: 0
6978
- matches:
7079
- headers:
7180
- type: Exact
7281
name: x-ai-eg-model
7382
value: whatever-model
7483
backendRefs:
7584
- name: translation-testupstream-cool-model-backend
85+
- name: translation-testupstream-another-cool-model-backend
86+
weight: 0
7687
---
7788
apiVersion: aigateway.envoyproxy.io/v1alpha1
7889
kind: AIServiceBackend

0 commit comments

Comments
 (0)