diff --git a/apis/v1/grpcroute_types.go b/apis/v1/grpcroute_types.go index 953ba0243b..e1d4f25af9 100644 --- a/apis/v1/grpcroute_types.go +++ b/apis/v1/grpcroute_types.go @@ -210,7 +210,7 @@ type GRPCRouteRule struct { // the above criteria. // // +optional - // +kubebuilder:validation:MaxItems=8 + // +kubebuilder:validation:MaxItems=64 Matches []GRPCRouteMatch `json:"matches,omitempty"` // Filters define the filters that are applied to requests that match diff --git a/config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml b/config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml index ad9944737e..6de3d06b5b 100644 --- a/config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml +++ b/config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml @@ -1805,7 +1805,7 @@ spec: has(self.method) ? self.method.matches(r"""^[A-Za-z_][A-Za-z_0-9]*$"""): true' type: object - maxItems: 8 + maxItems: 64 type: array name: description: |- diff --git a/config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml b/config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml index 1cd8c79bf6..763bf83ec9 100644 --- a/config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml +++ b/config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml @@ -1678,7 +1678,7 @@ spec: has(self.method) ? self.method.matches(r"""^[A-Za-z_][A-Za-z_0-9]*$"""): true' type: object - maxItems: 8 + maxItems: 64 type: array type: object maxItems: 16 diff --git a/pkg/test/cel/grpcroute_test.go b/pkg/test/cel/grpcroute_test.go index 366e91c1ed..628de66ae9 100644 --- a/pkg/test/cel/grpcroute_test.go +++ b/pkg/test/cel/grpcroute_test.go @@ -282,7 +282,67 @@ func TestGRPCRouteRule(t *testing.T) { }, }, }, - } + { + name: "too many matches and rules", + wantErrors: []string{"total number of matches across all rules in a route must be less than 128"}, + rules: func() []gatewayv1.GRPCRouteRule { + match := gatewayv1.GRPCRouteMatch{ + Headers: []gatewayv1.GRPCHeaderMatch{ + { + Type: ptrTo(gatewayv1.GRPCHeaderMatchExact), + Name: "version", + Value: "v1", + }, + }, + Method: &gatewayv1.GRPCMethodMatch{ + Type: ptrTo(gatewayv1.GRPCMethodMatchExact), + Service: ptrTo("foo"), + Method: ptrTo("bar"), + }, + } + + var rules []gatewayv1.GRPCRouteRule + for i := 0; i < 7; i++ { // Create 7 rules + rule := gatewayv1.GRPCRouteRule{} + for j := 0; j < 20; j++ { // Each rule has 20 matches + rule.Matches = append(rule.Matches, match) + } + rules = append(rules, rule) + } + return rules + }(), + }, + { + name: "many matches and few rules", + wantErrors: nil, + rules: func() []gatewayv1.GRPCRouteRule { + match := gatewayv1.GRPCRouteMatch{ + Headers: []gatewayv1.GRPCHeaderMatch{ + { + Type: ptrTo(gatewayv1.GRPCHeaderMatchExact), + Name: "version", + Value: "v1", + }, + }, + Method: &gatewayv1.GRPCMethodMatch{ + Type: ptrTo(gatewayv1.GRPCMethodMatchExact), + Service: ptrTo("foo"), + Method: ptrTo("bar"), + }, + } + + var rules []gatewayv1.GRPCRouteRule + for i := 0; i < 2; i++ { // Create 2 rules + rule := gatewayv1.GRPCRouteRule{} + for j := 0; j < 48; j++ { // Each rule has 48 matches + rule.Matches = append(rule.Matches, match) + } + rules = append(rules, rule) + } + return rules + }(), + }} + for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { route := &gatewayv1.GRPCRoute{