Skip to content

Commit

Permalink
NET-2904 Fixes API Gateway Route Service Weight Division Error (#16540)
Browse files Browse the repository at this point in the history
Co-authored-by: Melisa Griffin <missylbytes@users.noreply.github.com>
  • Loading branch information
hc-github-team-consul-core and missylbytes committed Mar 6, 2023
1 parent a95d028 commit 88496d7
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 4 deletions.
3 changes: 3 additions & 0 deletions .changelog/16531.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
gateways: fix HTTPRoute bug where services with a weight not divisible by 10000 are never registered properly
```
14 changes: 12 additions & 2 deletions agent/xds/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,7 @@ func (s *ResourceGenerator) makeRouteActionForSplitter(
forMeshGateway bool,
) (*envoy_route_v3.Route_Route, error) {
clusters := make([]*envoy_route_v3.WeightedCluster_ClusterWeight, 0, len(splits))
totalWeight := 0
for _, split := range splits {
nextNode := chain.Nodes[split.NextNode]

Expand All @@ -878,8 +879,10 @@ func (s *ResourceGenerator) makeRouteActionForSplitter(

// The smallest representable weight is 1/10000 or .01% but envoy
// deals with integers so scale everything up by 100x.
weight := int(split.Weight * 100)
totalWeight += weight
cw := &envoy_route_v3.WeightedCluster_ClusterWeight{
Weight: makeUint32Value(int(split.Weight * 100)),
Weight: makeUint32Value(weight),
Name: targetOptions.clusterName,
}
if err := injectHeaderManipToWeightedCluster(split.Definition, cw); err != nil {
Expand All @@ -893,12 +896,19 @@ func (s *ResourceGenerator) makeRouteActionForSplitter(
return nil, fmt.Errorf("number of clusters in splitter must be > 0; got %d", len(clusters))
}

envoyWeightScale := 10000
if envoyWeightScale < totalWeight {
clusters[0].Weight.Value += uint32(totalWeight - envoyWeightScale)
} else {
clusters[0].Weight.Value += uint32(envoyWeightScale - totalWeight)
}

return &envoy_route_v3.Route_Route{
Route: &envoy_route_v3.RouteAction{
ClusterSpecifier: &envoy_route_v3.RouteAction_WeightedClusters{
WeightedClusters: &envoy_route_v3.WeightedCluster{
Clusters: clusters,
TotalWeight: makeUint32Value(10000), // scaled up 100%
TotalWeight: makeUint32Value(envoyWeightScale), // scaled up 100%
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ rules = [
services = [
{
name = "s1"
},
{
name = "s2"
weight = 2
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ load helpers
}

@test "api gateway should be able to connect to s1 via configured port" {
run retry_long curl -s -f -d hello localhost:9999
run retry_long curl -s -d hello localhost:9999
[ "$status" -eq 0 ]
[[ "$output" == *"hello"* ]]
[[ ! -z "$output" ]]
}

@test "api gateway should get an intentions error connecting to s2 via configured port" {
Expand Down

0 comments on commit 88496d7

Please sign in to comment.