NET-2904 Fixes API Gateway Route Service Weight Division Error

This commit is contained in:
Melisa Griffin 2023-03-06 08:41:57 -05:00 committed by GitHub
parent 24502e4568
commit dac0cc90ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 4 deletions

3
.changelog/16531.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug
gateways: fix HTTPRoute bug where services with a weight not divisible by 10000 are never registered properly
```

View File

@ -863,6 +863,7 @@ func (s *ResourceGenerator) makeRouteActionForSplitter(
forMeshGateway bool, forMeshGateway bool,
) (*envoy_route_v3.Route_Route, error) { ) (*envoy_route_v3.Route_Route, error) {
clusters := make([]*envoy_route_v3.WeightedCluster_ClusterWeight, 0, len(splits)) clusters := make([]*envoy_route_v3.WeightedCluster_ClusterWeight, 0, len(splits))
totalWeight := 0
for _, split := range splits { for _, split := range splits {
nextNode := chain.Nodes[split.NextNode] nextNode := chain.Nodes[split.NextNode]
@ -878,8 +879,10 @@ func (s *ResourceGenerator) makeRouteActionForSplitter(
// The smallest representable weight is 1/10000 or .01% but envoy // The smallest representable weight is 1/10000 or .01% but envoy
// deals with integers so scale everything up by 100x. // deals with integers so scale everything up by 100x.
weight := int(split.Weight * 100)
totalWeight += weight
cw := &envoy_route_v3.WeightedCluster_ClusterWeight{ cw := &envoy_route_v3.WeightedCluster_ClusterWeight{
Weight: makeUint32Value(int(split.Weight * 100)), Weight: makeUint32Value(weight),
Name: clusterName, Name: clusterName,
} }
if err := injectHeaderManipToWeightedCluster(split.Definition, cw); err != nil { if err := injectHeaderManipToWeightedCluster(split.Definition, cw); err != nil {
@ -893,12 +896,19 @@ func (s *ResourceGenerator) makeRouteActionForSplitter(
return nil, fmt.Errorf("number of clusters in splitter must be > 0; got %d", len(clusters)) 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{ return &envoy_route_v3.Route_Route{
Route: &envoy_route_v3.RouteAction{ Route: &envoy_route_v3.RouteAction{
ClusterSpecifier: &envoy_route_v3.RouteAction_WeightedClusters{ ClusterSpecifier: &envoy_route_v3.RouteAction_WeightedClusters{
WeightedClusters: &envoy_route_v3.WeightedCluster{ WeightedClusters: &envoy_route_v3.WeightedCluster{
Clusters: clusters, Clusters: clusters,
TotalWeight: makeUint32Value(10000), // scaled up 100% TotalWeight: makeUint32Value(envoyWeightScale), // scaled up 100%
}, },
}, },
}, },

View File

@ -35,6 +35,10 @@ rules = [
services = [ services = [
{ {
name = "s1" name = "s1"
},
{
name = "s2"
weight = 2
} }
] ]
} }

View File

@ -22,9 +22,9 @@ load helpers
} }
@test "api gateway should be able to connect to s1 via configured port" { @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 ] [ "$status" -eq 0 ]
[[ "$output" == *"hello"* ]] [[ ! -z "$output" ]]
} }
@test "api gateway should get an intentions error connecting to s2 via configured port" { @test "api gateway should get an intentions error connecting to s2 via configured port" {