From 5190dbdc019d373e42677177d95dab75eb805995 Mon Sep 17 00:00:00 2001 From: Arko Dasgupta Date: Thu, 26 Oct 2023 10:56:07 -0700 Subject: [PATCH] remove RateLimitFilter in favor of BackendTrafficPolicy Relates to https://github.com/envoyproxy/gateway/issues/2006 Signed-off-by: Arko Dasgupta --- api/v1alpha1/backendtrafficpolicy_types.go | 2 +- ...imitfilter_types.go => ratelimit_types.go} | 39 +--- api/v1alpha1/zz_generated.deepcopy.go | 68 +----- ...ateway.envoyproxy.io_ratelimitfilters.yaml | 180 --------------- internal/cmd/egctl/translate.go | 14 -- internal/gatewayapi/filters.go | 98 -------- internal/gatewayapi/helpers.go | 22 -- internal/gatewayapi/resource.go | 2 - internal/gatewayapi/route.go | 3 - internal/gatewayapi/zz_generated.deepcopy.go | 11 - internal/provider/kubernetes/controller.go | 71 +----- internal/provider/kubernetes/filters.go | 28 --- .../provider/kubernetes/kubernetes_test.go | 211 ------------------ internal/provider/kubernetes/predicates.go | 24 -- internal/provider/kubernetes/routes.go | 46 +--- site/content/en/latest/api/extension_types.md | 28 +-- 16 files changed, 16 insertions(+), 831 deletions(-) rename api/v1alpha1/{ratelimitfilter_types.go => ratelimit_types.go} (84%) delete mode 100644 charts/gateway-helm/crds/generated/gateway.envoyproxy.io_ratelimitfilters.yaml diff --git a/api/v1alpha1/backendtrafficpolicy_types.go b/api/v1alpha1/backendtrafficpolicy_types.go index f01bb401d02..e7bbecf71e8 100644 --- a/api/v1alpha1/backendtrafficpolicy_types.go +++ b/api/v1alpha1/backendtrafficpolicy_types.go @@ -49,7 +49,7 @@ type BackendTrafficPolicySpec struct { // RateLimit allows the user to limit the number of incoming requests // to a predefined value based on attributes within the traffic flow. // +optional - RateLimit *RateLimitFilterSpec `json:"rateLimit,omitempty"` + RateLimit *RateLimitPolicy `json:"rateLimit,omitempty"` // LoadBalancer policy to apply when routing traffic from the gateway to // the backend endpoints diff --git a/api/v1alpha1/ratelimitfilter_types.go b/api/v1alpha1/ratelimit_types.go similarity index 84% rename from api/v1alpha1/ratelimitfilter_types.go rename to api/v1alpha1/ratelimit_types.go index 5ee825d3b3c..7eabf64f31e 100644 --- a/api/v1alpha1/ratelimitfilter_types.go +++ b/api/v1alpha1/ratelimit_types.go @@ -5,31 +5,9 @@ package v1alpha1 -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -const ( - // KindRateLimitFilter is the name of the RateLimitFilter kind. - KindRateLimitFilter = "RateLimitFilter" -) - -// +kubebuilder:object:root=true -// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` - -// RateLimitFilter allows the user to limit the number of incoming requests -// to a predefined value based on attributes within the traffic flow. -type RateLimitFilter struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - // Spec defines the desired state of RateLimitFilter. - Spec RateLimitFilterSpec `json:"spec"` -} - -// RateLimitFilterSpec defines the desired state of RateLimitFilter. +// RateLimitPolicy defines the desired state of RateLimitFilter. // +union -type RateLimitFilterSpec struct { +type RateLimitPolicy struct { // Type decides the scope for the RateLimits. // Valid RateLimitType values are "Global". // @@ -184,16 +162,3 @@ type RateLimitValue struct { // // +kubebuilder:validation:Enum=Second;Minute;Hour;Day type RateLimitUnit string - -//+kubebuilder:object:root=true - -// RateLimitFilterList contains a list of RateLimitFilter resources. -type RateLimitFilterList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []RateLimitFilter `json:"items"` -} - -func init() { - SchemeBuilder.Register(&RateLimitFilter{}, &RateLimitFilterList{}) -} diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 0854f1f8fe5..26f7aba81a0 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -162,7 +162,7 @@ func (in *BackendTrafficPolicySpec) DeepCopyInto(out *BackendTrafficPolicySpec) in.TargetRef.DeepCopyInto(&out.TargetRef) if in.RateLimit != nil { in, out := &in.RateLimit, &out.RateLimit - *out = new(RateLimitFilterSpec) + *out = new(RateLimitPolicy) (*in).DeepCopyInto(*out) } if in.LoadBalancer != nil { @@ -1938,65 +1938,7 @@ func (in *RateLimitDatabaseBackend) DeepCopy() *RateLimitDatabaseBackend { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RateLimitFilter) DeepCopyInto(out *RateLimitFilter) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RateLimitFilter. -func (in *RateLimitFilter) DeepCopy() *RateLimitFilter { - if in == nil { - return nil - } - out := new(RateLimitFilter) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *RateLimitFilter) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RateLimitFilterList) DeepCopyInto(out *RateLimitFilterList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]RateLimitFilter, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RateLimitFilterList. -func (in *RateLimitFilterList) DeepCopy() *RateLimitFilterList { - if in == nil { - return nil - } - out := new(RateLimitFilterList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *RateLimitFilterList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RateLimitFilterSpec) DeepCopyInto(out *RateLimitFilterSpec) { +func (in *RateLimitPolicy) DeepCopyInto(out *RateLimitPolicy) { *out = *in if in.Global != nil { in, out := &in.Global, &out.Global @@ -2005,12 +1947,12 @@ func (in *RateLimitFilterSpec) DeepCopyInto(out *RateLimitFilterSpec) { } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RateLimitFilterSpec. -func (in *RateLimitFilterSpec) DeepCopy() *RateLimitFilterSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RateLimitPolicy. +func (in *RateLimitPolicy) DeepCopy() *RateLimitPolicy { if in == nil { return nil } - out := new(RateLimitFilterSpec) + out := new(RateLimitPolicy) in.DeepCopyInto(out) return out } diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_ratelimitfilters.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_ratelimitfilters.yaml deleted file mode 100644 index 1c403566111..00000000000 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_ratelimitfilters.yaml +++ /dev/null @@ -1,180 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.13.0 - name: ratelimitfilters.gateway.envoyproxy.io -spec: - group: gateway.envoyproxy.io - names: - kind: RateLimitFilter - listKind: RateLimitFilterList - plural: ratelimitfilters - singular: ratelimitfilter - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1alpha1 - schema: - openAPIV3Schema: - description: RateLimitFilter allows the user to limit the number of incoming - requests to a predefined value based on attributes within the traffic flow. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines the desired state of RateLimitFilter. - properties: - global: - description: Global defines global rate limit configuration. - properties: - rules: - description: Rules are a list of RateLimit selectors and limits. - Each rule and its associated limit is applied in a mutually - exclusive way i.e. if multiple rules get selected, each of their - associated limits get applied, so a single traffic request might - increase the rate limit counters for multiple rules if selected. - items: - description: RateLimitRule defines the semantics for matching - attributes from the incoming requests, and setting limits - for them. - properties: - clientSelectors: - description: ClientSelectors holds the list of select conditions - to select specific clients using attributes from the traffic - flow. All individual select conditions must hold True - for this rule and its limit to be applied. If this field - is empty, it is equivalent to True, and the limit is applied. - items: - description: RateLimitSelectCondition specifies the attributes - within the traffic flow that can be used to select a - subset of clients to be ratelimited. All the individual - conditions must hold True for the overall condition - to hold True. - properties: - headers: - description: Headers is a list of request headers - to match. Multiple header values are ANDed together, - meaning, a request MUST match all the specified - headers. - items: - description: HeaderMatch defines the match attributes - within the HTTP Headers of the request. - properties: - name: - description: Name of the HTTP header. - maxLength: 256 - minLength: 1 - type: string - type: - default: Exact - description: Type specifies how to match against - the value of the header. - enum: - - Exact - - RegularExpression - - Distinct - type: string - value: - description: Value within the HTTP header. Due - to the case-insensitivity of header names, - "foo" and "Foo" are considered equivalent. - Do not set this field when Type="Distinct", - implying matching on any/all unique values - within the header. - maxLength: 1024 - type: string - required: - - name - type: object - maxItems: 16 - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - sourceCIDR: - description: SourceCIDR is the client IP Address range - to match on. - properties: - type: - default: Exact - type: string - value: - description: Value is the IP CIDR that represents - the range of Source IP Addresses of the client. - These could also be the intermediate addresses - through which the request has flown through - and is part of the `X-Forwarded-For` header. - For example, `192.168.0.1/32`, `192.168.0.0/24`, - `001:db8::/64`. - maxLength: 256 - minLength: 1 - type: string - required: - - value - type: object - type: object - maxItems: 8 - type: array - limit: - description: Limit holds the rate limit values. This limit - is applied for traffic flows when the selectors compute - to True, causing the request to be counted towards the - limit. The limit is enforced and the request is ratelimited, - i.e. a response with 429 HTTP status code is sent back - to the client when the selected requests have reached - the limit. - properties: - requests: - type: integer - unit: - description: RateLimitUnit specifies the intervals for - setting rate limits. Valid RateLimitUnit values are - "Second", "Minute", "Hour", and "Day". - enum: - - Second - - Minute - - Hour - - Day - type: string - required: - - requests - - unit - type: object - required: - - limit - type: object - maxItems: 16 - type: array - required: - - rules - type: object - type: - description: Type decides the scope for the RateLimits. Valid RateLimitType - values are "Global". - enum: - - Global - type: string - required: - - type - type: object - required: - - spec - type: object - served: true - storage: true - subresources: {} diff --git a/internal/cmd/egctl/translate.go b/internal/cmd/egctl/translate.go index c46be9a8495..5850f96a1fa 100644 --- a/internal/cmd/egctl/translate.go +++ b/internal/cmd/egctl/translate.go @@ -766,20 +766,6 @@ func kubernetesYAMLToResources(str string, addMissingResources bool) (*gatewayap Spec: typedSpec.(egv1a1.EnvoyPatchPolicySpec), } resources.EnvoyPatchPolicies = append(resources.EnvoyPatchPolicies, envoyPatchPolicy) - case egv1a1.KindRateLimitFilter: - typedSpec := spec.Interface() - rateLimitFilter := &egv1a1.RateLimitFilter{ - TypeMeta: metav1.TypeMeta{ - Kind: egv1a1.KindRateLimitFilter, - APIVersion: egv1a1.GroupVersion.String(), - }, - ObjectMeta: metav1.ObjectMeta{ - Namespace: namespace, - Name: name, - }, - Spec: typedSpec.(egv1a1.RateLimitFilterSpec), - } - resources.RateLimitFilters = append(resources.RateLimitFilters, rateLimitFilter) } } diff --git a/internal/gatewayapi/filters.go b/internal/gatewayapi/filters.go index a701b801080..961b2fd6ec4 100644 --- a/internal/gatewayapi/filters.go +++ b/internal/gatewayapi/filters.go @@ -7,7 +7,6 @@ package gatewayapi import ( "fmt" - "net" "strings" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -59,7 +58,6 @@ type HTTPFilterIR struct { Mirrors []*ir.RouteDestination RequestAuthentication *ir.RequestAuthentication - RateLimit *ir.RateLimit ExtensionRefs []*ir.UnstructuredRef } @@ -679,102 +677,6 @@ func (t *Translator) processExtensionRefHTTPFilter(extFilter *gwapiv1.LocalObjec } } - // Set the filter context and return early if a matching RateLimitFilter is found. - if string(extFilter.Kind) == egv1a1.KindRateLimitFilter { - for _, rateLimitFilter := range resources.RateLimitFilters { - if rateLimitFilter.Namespace == filterNs && - rateLimitFilter.Name == string(extFilter.Name) { - if rateLimitFilter.Spec.Global == nil { - errMsg := fmt.Sprintf("Global configuration empty for RateLimitFilter: %s/%s", filterNs, - extFilter.Name) - t.processUnresolvedHTTPFilter(errMsg, filterContext) - return - } - if !t.GlobalRateLimitEnabled { - errMsg := fmt.Sprintf("Enable Ratelimit in the EnvoyGateway config to configure RateLimitFilter: %s/%s", - filterNs, extFilter.Name) - t.processUnresolvedHTTPFilter(errMsg, filterContext) - return - } - rateLimit := &ir.RateLimit{ - Global: &ir.GlobalRateLimit{ - Rules: make([]*ir.RateLimitRule, len(rateLimitFilter.Spec.Global.Rules)), - }, - } - rules := rateLimit.Global.Rules - for i, rule := range rateLimitFilter.Spec.Global.Rules { - rules[i] = &ir.RateLimitRule{ - Limit: &ir.RateLimitValue{ - Requests: rule.Limit.Requests, - Unit: ir.RateLimitUnit(rule.Limit.Unit), - }, - HeaderMatches: make([]*ir.StringMatch, 0), - } - for _, match := range rule.ClientSelectors { - for _, header := range match.Headers { - switch { - case header.Type == nil && header.Value != nil: - fallthrough - case *header.Type == egv1a1.HeaderMatchExact && header.Value != nil: - m := &ir.StringMatch{ - Name: header.Name, - Exact: header.Value, - } - rules[i].HeaderMatches = append(rules[i].HeaderMatches, m) - case *header.Type == egv1a1.HeaderMatchRegularExpression && header.Value != nil: - m := &ir.StringMatch{ - Name: header.Name, - SafeRegex: header.Value, - } - rules[i].HeaderMatches = append(rules[i].HeaderMatches, m) - case *header.Type == egv1a1.HeaderMatchDistinct && header.Value == nil: - m := &ir.StringMatch{ - Name: header.Name, - Distinct: true, - } - rules[i].HeaderMatches = append(rules[i].HeaderMatches, m) - default: - // set negative status condition. - errMsg := fmt.Sprintf("Unable to translate RateLimitFilter. Either the header.Type is not valid or the header is missing a value: %s/%s", filterNs, - extFilter.Name) - t.processUnresolvedHTTPFilter(errMsg, filterContext) - return - } - } - - if match.SourceCIDR != nil { - // distinct means that each IP Address within the specified Source IP CIDR is treated as a - // distinct client selector and uses a separate rate limit bucket/counter. - distinct := false - sourceCIDR := match.SourceCIDR.Value - if match.SourceCIDR.Type != nil && *match.SourceCIDR.Type == egv1a1.SourceMatchDistinct { - distinct = true - } - - ip, ipn, err := net.ParseCIDR(sourceCIDR) - if err != nil { - errMsg := fmt.Sprintf("Unable to translate RateLimitFilter: %s/%s", filterNs, - extFilter.Name) - t.processUnresolvedHTTPFilter(errMsg, filterContext) - return - } - - mask, _ := ipn.Mask.Size() - rules[i].CIDRMatch = &ir.CIDRMatch{ - CIDR: ipn.String(), - IPv6: ip.To4() == nil, - MaskLen: mask, - Distinct: distinct, - } - } - } - } - filterContext.HTTPFilterIR.RateLimit = rateLimit - return - } - } - } - // This list of resources will be empty unless an extension is loaded (and introduces resources) for _, res := range resources.ExtensionRefFilters { if res.GetKind() == string(extFilter.Kind) && res.GetName() == string(extFilter.Name) && res.GetNamespace() == filterNs { diff --git a/internal/gatewayapi/helpers.go b/internal/gatewayapi/helpers.go index f9a6732dbae..fc221085af3 100644 --- a/internal/gatewayapi/helpers.go +++ b/internal/gatewayapi/helpers.go @@ -192,9 +192,6 @@ func ValidateHTTPRouteFilter(filter *gwapiv1.HTTPRouteFilter, extGKs ...schema.G case string(filter.ExtensionRef.Group) == egv1a1.GroupVersion.Group && string(filter.ExtensionRef.Kind) == egv1a1.KindAuthenticationFilter: return nil - case string(filter.ExtensionRef.Group) == egv1a1.GroupVersion.Group && - string(filter.ExtensionRef.Kind) == egv1a1.KindRateLimitFilter: - return nil default: for _, gk := range extGKs { if filter.ExtensionRef.Group == gwapiv1.Group(gk.Group) && @@ -217,14 +214,6 @@ func IsAuthnHTTPFilter(filter *gwapiv1.HTTPRouteFilter) bool { string(filter.ExtensionRef.Kind) == egv1a1.KindAuthenticationFilter } -// IsRateLimitHTTPFilter returns true if the provided filter is a RateLimitFilter. -func IsRateLimitHTTPFilter(filter *gwapiv1.HTTPRouteFilter) bool { - return filter.Type == gwapiv1.HTTPRouteFilterExtensionRef && - filter.ExtensionRef != nil && - string(filter.ExtensionRef.Group) == egv1a1.GroupVersion.Group && - string(filter.ExtensionRef.Kind) == egv1a1.KindRateLimitFilter -} - // ValidateGRPCRouteFilter validates the provided filter within GRPCRoute. func ValidateGRPCRouteFilter(filter *v1alpha2.GRPCRouteFilter, extGKs ...schema.GroupKind) error { switch { @@ -241,9 +230,6 @@ func ValidateGRPCRouteFilter(filter *v1alpha2.GRPCRouteFilter, extGKs ...schema. case string(filter.ExtensionRef.Group) == egv1a1.GroupVersion.Group && string(filter.ExtensionRef.Kind) == egv1a1.KindAuthenticationFilter: return nil - case string(filter.ExtensionRef.Group) == egv1a1.GroupVersion.Group && - string(filter.ExtensionRef.Kind) == egv1a1.KindRateLimitFilter: - return nil default: for _, gk := range extGKs { if filter.ExtensionRef.Group == gwapiv1.Group(gk.Group) && @@ -266,14 +252,6 @@ func IsAuthnGRPCFilter(filter *v1alpha2.GRPCRouteFilter) bool { string(filter.ExtensionRef.Kind) == egv1a1.KindAuthenticationFilter } -// IsRateLimitGRPCFilter returns true if the provided filter is an RateLimitFilter. -func IsRateLimitGRPCFilter(filter *v1alpha2.GRPCRouteFilter) bool { - return filter.Type == v1alpha2.GRPCRouteFilterExtensionRef && - filter.ExtensionRef != nil && - string(filter.ExtensionRef.Group) == egv1a1.GroupVersion.Group && - string(filter.ExtensionRef.Kind) == egv1a1.KindRateLimitFilter -} - // GatewayOwnerLabels returns the Gateway Owner labels using // the provided namespace and name as the values. func GatewayOwnerLabels(namespace, name string) map[string]string { diff --git a/internal/gatewayapi/resource.go b/internal/gatewayapi/resource.go index 318728afce7..6bd0fc4f696 100644 --- a/internal/gatewayapi/resource.go +++ b/internal/gatewayapi/resource.go @@ -41,7 +41,6 @@ type Resources struct { EndpointSlices []*discoveryv1.EndpointSlice `json:"endpointSlices,omitempty" yaml:"endpointSlices,omitempty"` Secrets []*v1.Secret `json:"secrets,omitempty" yaml:"secrets,omitempty"` AuthenticationFilters []*egv1a1.AuthenticationFilter `json:"authenticationFilters,omitempty" yaml:"authenticationFilters,omitempty"` - RateLimitFilters []*egv1a1.RateLimitFilter `json:"rateLimitFilters,omitempty" yaml:"rateLimitFilters,omitempty"` EnvoyProxy *egv1a1.EnvoyProxy `json:"envoyProxy,omitempty" yaml:"envoyProxy,omitempty"` ExtensionRefFilters []unstructured.Unstructured `json:"extensionRefFilters,omitempty" yaml:"extensionRefFilters,omitempty"` EnvoyPatchPolicies []*egv1a1.EnvoyPatchPolicy `json:"envoyPatchPolicies,omitempty" yaml:"envoyPatchPolicies,omitempty"` @@ -61,7 +60,6 @@ func NewResources() *Resources { Secrets: []*v1.Secret{}, ReferenceGrants: []*gwapiv1b1.ReferenceGrant{}, Namespaces: []*v1.Namespace{}, - RateLimitFilters: []*egv1a1.RateLimitFilter{}, AuthenticationFilters: []*egv1a1.AuthenticationFilter{}, ExtensionRefFilters: []unstructured.Unstructured{}, EnvoyPatchPolicies: []*egv1a1.EnvoyPatchPolicy{}, diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go index fe0ec085def..fed00642f59 100644 --- a/internal/gatewayapi/route.go +++ b/internal/gatewayapi/route.go @@ -317,9 +317,6 @@ func applyHTTPFiltersContextToIRRoute(httpFiltersContext *HTTPFiltersContext, ir if httpFiltersContext.RequestAuthentication != nil { irRoute.RequestAuthentication = httpFiltersContext.RequestAuthentication } - if httpFiltersContext.RateLimit != nil { - irRoute.RateLimit = httpFiltersContext.RateLimit - } if len(httpFiltersContext.ExtensionRefs) > 0 { irRoute.ExtensionRefs = httpFiltersContext.ExtensionRefs diff --git a/internal/gatewayapi/zz_generated.deepcopy.go b/internal/gatewayapi/zz_generated.deepcopy.go index fb847507b0a..56969b4480a 100644 --- a/internal/gatewayapi/zz_generated.deepcopy.go +++ b/internal/gatewayapi/zz_generated.deepcopy.go @@ -171,17 +171,6 @@ func (in *Resources) DeepCopyInto(out *Resources) { } } } - if in.RateLimitFilters != nil { - in, out := &in.RateLimitFilters, &out.RateLimitFilters - *out = make([]*apiv1alpha1.RateLimitFilter, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(apiv1alpha1.RateLimitFilter) - (*in).DeepCopyInto(*out) - } - } - } if in.EnvoyProxy != nil { in, out := &in.EnvoyProxy, &out.EnvoyProxy *out = new(apiv1alpha1.EnvoyProxy) diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go index 663eb80a299..be6df0d1356 100644 --- a/internal/provider/kubernetes/controller.go +++ b/internal/provider/kubernetes/controller.go @@ -139,9 +139,6 @@ type resourceMappings struct { // authenFilters is a map of AuthenticationFilters, where the key is the // namespaced name of the AuthenticationFilter. authenFilters map[types.NamespacedName]*egv1a1.AuthenticationFilter - // rateLimitFilters is a map of RateLimitFilters, where the key is the - // namespaced name of the RateLimitFilter. - rateLimitFilters map[types.NamespacedName]*egv1a1.RateLimitFilter // extensionRefFilters is a map of filters managed by an extension. // The key is the namespaced name of the filter and the value is the // unstructured form of the resource. @@ -154,7 +151,6 @@ func newResourceMapping() *resourceMappings { allAssociatedBackendRefs: map[gwapiv1.BackendObjectReference]struct{}{}, allAssociatedRefGrants: map[types.NamespacedName]*gwapiv1b1.ReferenceGrant{}, authenFilters: map[types.NamespacedName]*egv1a1.AuthenticationFilter{}, - rateLimitFilters: map[types.NamespacedName]*egv1a1.RateLimitFilter{}, extensionRefFilters: map[types.NamespacedName]unstructured.Unstructured{}, } } @@ -657,7 +653,7 @@ func addReferenceGrantIndexers(ctx context.Context, mgr manager.Manager) error { // addHTTPRouteIndexers adds indexing on HTTPRoute. // - For Service, ServiceImports objects that are referenced in HTTPRoute objects via `.spec.rules.backendRefs`. // This helps in querying for HTTPRoutes that are affected by a particular Service CRUD. -// - For AuthenticationFilter and RateLimitFilter objects that are referenced in HTTPRoute objects via +// - For AuthenticationFilter objects that are referenced in HTTPRoute objects via // `.spec.rules[].filters`. This helps in querying for HTTPRoutes that are affected by a // particular AuthenticationFilter CRUD. func addHTTPRouteIndexers(ctx context.Context, mgr manager.Manager) error { @@ -673,9 +669,6 @@ func addHTTPRouteIndexers(ctx context.Context, mgr manager.Manager) error { return err } - if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1.HTTPRoute{}, rateLimitFilterHTTPRouteIndex, rateLimitFilterHTTPRouteIndexFunc); err != nil { - return err - } return nil } @@ -700,27 +693,6 @@ func authenFilterHTTPRouteIndexFunc(rawObj client.Object) []string { return filters } -func rateLimitFilterHTTPRouteIndexFunc(rawObj client.Object) []string { - httproute := rawObj.(*gwapiv1.HTTPRoute) - var filters []string - for _, rule := range httproute.Spec.Rules { - for i := range rule.Filters { - filter := rule.Filters[i] - if gatewayapi.IsRateLimitHTTPFilter(&filter) { - if err := gatewayapi.ValidateHTTPRouteFilter(&filter); err == nil { - filters = append(filters, - types.NamespacedName{ - Namespace: httproute.Namespace, - Name: string(filter.ExtensionRef.Name), - }.String(), - ) - } - } - } - } - return filters -} - func gatewayHTTPRouteIndexFunc(rawObj client.Object) []string { httproute := rawObj.(*gwapiv1.HTTPRoute) var gateways []string @@ -775,10 +747,6 @@ func addGRPCRouteIndexers(ctx context.Context, mgr manager.Manager) error { return err } - if err := mgr.GetFieldIndexer().IndexField(ctx, &gwapiv1a2.GRPCRoute{}, rateLimitFilterGRPCRouteIndex, rateLimitFilterGRPCRouteIndexFunc); err != nil { - return err - } - return nil } @@ -841,27 +809,6 @@ func authenFilterGRPCRouteIndexFunc(rawObj client.Object) []string { return filters } -func rateLimitFilterGRPCRouteIndexFunc(rawObj client.Object) []string { - grpcroute := rawObj.(*gwapiv1a2.GRPCRoute) - var filters []string - for _, rule := range grpcroute.Spec.Rules { - for i := range rule.Filters { - filter := rule.Filters[i] - if gatewayapi.IsRateLimitGRPCFilter(&filter) { - if err := gatewayapi.ValidateGRPCRouteFilter(&filter); err == nil { - filters = append(filters, - types.NamespacedName{ - Namespace: grpcroute.Namespace, - Name: string(filter.ExtensionRef.Name), - }.String(), - ) - } - } - } - } - return filters -} - // addTLSRouteIndexers adds indexing on TLSRoute, for Service objects that are // referenced in TLSRoute objects via `.spec.rules.backendRefs`. This helps in // querying for TLSRoutes that are affected by a particular Service CRUD. @@ -1578,22 +1525,6 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M return err } - rfPredicates := []predicate.Predicate{ - predicate.GenerationChangedPredicate{}, - predicate.NewPredicateFuncs(r.httpRoutesForRateLimitFilter), - } - if len(r.namespaceLabels) != 0 { - rfPredicates = append(rfPredicates, predicate.NewPredicateFuncs(r.hasMatchingNamespaceLabels)) - } - // Watch RateLimitFilter CRUDs and enqueue associated HTTPRoute objects. - if err := c.Watch( - source.Kind(mgr.GetCache(), &egv1a1.RateLimitFilter{}), - handler.EnqueueRequestsFromMapFunc(r.enqueueClass), - rfPredicates..., - ); err != nil { - return err - } - // Watch EnvoyPatchPolicy if enabled in config eppPredicates := []predicate.Predicate{predicate.GenerationChangedPredicate{}} if len(r.namespaceLabels) != 0 { diff --git a/internal/provider/kubernetes/filters.go b/internal/provider/kubernetes/filters.go index c7d402a8593..bd3266a7040 100644 --- a/internal/provider/kubernetes/filters.go +++ b/internal/provider/kubernetes/filters.go @@ -42,34 +42,6 @@ func (r *gatewayAPIReconciler) getAuthenticationFilters(ctx context.Context) ([] return authens, nil } -func (r *gatewayAPIReconciler) getRateLimitFilters(ctx context.Context) ([]egv1a1.RateLimitFilter, error) { - rateLimitList := new(egv1a1.RateLimitFilterList) - if err := r.client.List(ctx, rateLimitList); err != nil { - return nil, fmt.Errorf("failed to list RateLimitFilters: %v", err) - } - - rateLimits := rateLimitList.Items - if len(r.namespaceLabels) != 0 { - var rls []egv1a1.RateLimitFilter - for _, rl := range rateLimits { - ns := rl.GetNamespace() - ok, err := r.checkObjectNamespaceLabels(ns) - if err != nil { - // TODO: should return? or just proceed? - return nil, fmt.Errorf("failed to check namespace labels for RateLimitFilter %s in namespace %s: %s", rl.GetName(), ns, err) - } - - if ok { - rls = append(rls, rl) - } - } - - rateLimits = rls - } - - return rateLimits, nil -} - func (r *gatewayAPIReconciler) getExtensionRefFilters(ctx context.Context) ([]unstructured.Unstructured, error) { var resourceItems []unstructured.Unstructured for _, gvk := range r.extGVKs { diff --git a/internal/provider/kubernetes/kubernetes_test.go b/internal/provider/kubernetes/kubernetes_test.go index f76d915b931..871874b5a90 100644 --- a/internal/provider/kubernetes/kubernetes_test.go +++ b/internal/provider/kubernetes/kubernetes_test.go @@ -73,7 +73,6 @@ func TestProvider(t *testing.T) { "gateway scheduled status": testGatewayScheduledStatus, "httproute": testHTTPRoute, "tlsroute": testTLSRoute, - "ratelimit filter": testRateLimitFilter, "authentication filter": testAuthenFilter, "stale service cleanup route deletion": testServiceCleanupForMultipleRoutes, } @@ -458,182 +457,6 @@ func testLongNameHashedResources(ctx context.Context, t *testing.T, provider *Pr assert.Equal(t, gw.Spec, res.Gateways[0].Spec) } -func testRateLimitFilter(ctx context.Context, t *testing.T, provider *Provider, resources *message.ProviderResources) { - cli := provider.manager.GetClient() - - gc := test.GetGatewayClass("ratelimit-test", egv1a1.GatewayControllerName) - require.NoError(t, cli.Create(ctx, gc)) - - // Ensure the GatewayClass reports ready. - require.Eventually(t, func() bool { - if err := cli.Get(ctx, types.NamespacedName{Name: gc.Name}, gc); err != nil { - return false - } - - for _, cond := range gc.Status.Conditions { - if cond.Type == string(gwapiv1.GatewayClassConditionStatusAccepted) && cond.Status == metav1.ConditionTrue { - return true - } - } - - return false - }, defaultWait, defaultTick) - - defer func() { - require.NoError(t, cli.Delete(ctx, gc)) - }() - - // Create the namespace for the Gateway under test. - ns := &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "ratelimit-test"}} - require.NoError(t, cli.Create(ctx, ns)) - - gw := &gwapiv1.Gateway{ - ObjectMeta: metav1.ObjectMeta{ - Name: "ratelimit-test", - Namespace: ns.Name, - }, - Spec: gwapiv1.GatewaySpec{ - GatewayClassName: gwapiv1.ObjectName(gc.Name), - Listeners: []gwapiv1.Listener{ - { - Name: "test", - Port: gwapiv1.PortNumber(int32(8080)), - Protocol: gwapiv1.HTTPProtocolType, - }, - }, - }, - } - require.NoError(t, cli.Create(ctx, gw)) - - defer func() { - require.NoError(t, cli.Delete(ctx, gw)) - }() - - svc := test.GetService(types.NamespacedName{Namespace: ns.Name, Name: "test"}, nil, map[string]int32{ - "http": 80, - "https": 443, - }) - - require.NoError(t, cli.Create(ctx, svc)) - - defer func() { - require.NoError(t, cli.Delete(ctx, svc)) - }() - - rateLimitFilter := test.GetRateLimitFilter("ratelimit-test", ns.Name) - - require.NoError(t, cli.Create(ctx, rateLimitFilter)) - - defer func() { - require.NoError(t, cli.Delete(ctx, rateLimitFilter)) - }() - - var testCases = []struct { - name string - route gwapiv1.HTTPRoute - }{ - { - name: "ratelimit-test-httproute", - route: gwapiv1.HTTPRoute{ - ObjectMeta: metav1.ObjectMeta{ - Name: "ratelimit-test", - Namespace: ns.Name, - }, - Spec: gwapiv1.HTTPRouteSpec{ - CommonRouteSpec: gwapiv1.CommonRouteSpec{ - ParentRefs: []gwapiv1.ParentReference{ - { - Name: gwapiv1.ObjectName(gw.Name), - }, - }, - }, - Hostnames: []gwapiv1.Hostname{"test.hostname.local"}, - Rules: []gwapiv1.HTTPRouteRule{ - { - Matches: []gwapiv1.HTTPRouteMatch{ - { - Path: &gwapiv1.HTTPPathMatch{ - Type: ptr.To(gwapiv1.PathMatchPathPrefix), - Value: ptr.To("/ratelimitfilter/"), - }, - }, - }, - BackendRefs: []gwapiv1.HTTPBackendRef{ - { - BackendRef: gwapiv1.BackendRef{ - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "test", - }, - }, - }, - }, - Filters: []gwapiv1.HTTPRouteFilter{ - { - Type: gwapiv1.HTTPRouteFilterExtensionRef, - ExtensionRef: &gwapiv1.LocalObjectReference{ - Group: gwapiv1.Group(egv1a1.GroupVersion.Group), - Kind: gwapiv1.Kind(egv1a1.KindRateLimitFilter), - Name: gwapiv1.ObjectName("ratelimit-test"), - }, - }, - }, - }, - }, - }, - }, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.name, func(t *testing.T) { - require.NoError(t, cli.Create(ctx, &testCase.route)) - defer func() { - require.NoError(t, cli.Delete(ctx, &testCase.route)) - }() - - require.Eventually(t, func() bool { - return resources.GatewayAPIResources.Len() != 0 - }, defaultWait, defaultTick) - - // Ensure the test HTTPRoute in the HTTPRoute resources is as expected. - key := types.NamespacedName{ - Namespace: testCase.route.Namespace, - Name: testCase.route.Name, - } - require.Eventually(t, func() bool { - return cli.Get(ctx, key, &testCase.route) == nil - }, defaultWait, defaultTick) - - require.Eventually(t, func() bool { - res, ok := resources.GatewayAPIResources.Load("ratelimit-test") - return ok && - len(res.HTTPRoutes) != 0 && - assert.Equal(t, testCase.route.Spec, res.HTTPRoutes[0].Spec) - }, defaultWait, defaultTick) - - // Ensure the RateLimitFilter is in the resource map. - require.Eventually(t, func() bool { - res, ok := resources.GatewayAPIResources.Load("ratelimit-test") - return ok && - len(res.RateLimitFilters) != 0 && - assert.Equal(t, rateLimitFilter.Spec, res.RateLimitFilters[0].Spec) - }, defaultWait, defaultTick) - - // Update the rate limit filter. - rateLimitFilter.Spec.Global.Rules = append(rateLimitFilter.Spec.Global.Rules, test.GetRateLimitGlobalRule("two")) - require.NoError(t, cli.Update(ctx, rateLimitFilter)) - - // Ensure the RateLimitFilter in the resource map has been updated. - require.Eventually(t, func() bool { - res, ok := resources.GatewayAPIResources.Load("ratelimit-test") - return ok && - len(res.RateLimitFilters) != 0 && - assert.Equal(t, 2, len(res.RateLimitFilters[0].Spec.Global.Rules)) - }, defaultWait, defaultTick) - }) - } -} - func testAuthenFilter(ctx context.Context, t *testing.T, provider *Provider, resources *message.ProviderResources) { cli := provider.manager.GetClient() @@ -1820,20 +1643,6 @@ func TestNamespaceSelectorsProvider(t *testing.T) { require.NoError(t, cli.Delete(ctx, nonWatchedAuthenFilter)) }() - watchedRateLimitFilter := test.GetRateLimitFilter("watched-rate-limit-filter", watchedNS.Name) - require.NoError(t, cli.Create(ctx, watchedRateLimitFilter)) - - defer func() { - require.NoError(t, cli.Delete(ctx, watchedRateLimitFilter)) - }() - - nonWatchedRateLimitFilter := test.GetRateLimitFilter("non-watched-rate-limit-filter", nonWatchedNS.Name) - require.NoError(t, cli.Create(ctx, nonWatchedRateLimitFilter)) - - defer func() { - require.NoError(t, cli.Delete(ctx, nonWatchedRateLimitFilter)) - }() - watchedSvc := test.GetService(types.NamespacedName{Namespace: watchedNS.Name, Name: "watched-service"}, nil, map[string]int32{ "http": 80, "https": 443, @@ -1870,14 +1679,6 @@ func TestNamespaceSelectorsProvider(t *testing.T) { Name: gwapiv1.ObjectName(watchedAuthenFilter.Name), }, }, - { - Type: gwapiv1.HTTPRouteFilterExtensionRef, - ExtensionRef: &gwapiv1.LocalObjectReference{ - Group: gwapiv1.Group(egv1a1.GroupVersion.Group), - Kind: gwapiv1.Kind(egv1a1.KindRateLimitFilter), - Name: gwapiv1.ObjectName(watchedRateLimitFilter.Name), - }, - }, } require.NoError(t, cli.Create(ctx, watchedHTTPRoute)) defer func() { @@ -1900,14 +1701,6 @@ func TestNamespaceSelectorsProvider(t *testing.T) { Name: gwapiv1.ObjectName(nonWatchedAuthenFilter.Name), }, }, - { - Type: gwapiv1.HTTPRouteFilterExtensionRef, - ExtensionRef: &gwapiv1.LocalObjectReference{ - Group: gwapiv1.Group(egv1a1.GroupVersion.Group), - Kind: gwapiv1.Kind(egv1a1.KindRateLimitFilter), - Name: gwapiv1.ObjectName(nonWatchedRateLimitFilter.Name), - }, - }, } require.NoError(t, cli.Create(ctx, nonWatchedHTTPRoute)) defer func() { @@ -2046,8 +1839,4 @@ func TestNamespaceSelectorsProvider(t *testing.T) { return res != nil && len(res.AuthenticationFilters) == 1 }, defaultWait, defaultTick) - require.Eventually(t, func() bool { - res, _ := resources.GatewayAPIResources.Load(gc.Name) - return res != nil && len(res.RateLimitFilters) == 1 - }, defaultWait, defaultTick) } diff --git a/internal/provider/kubernetes/predicates.go b/internal/provider/kubernetes/predicates.go index b24872447d4..343ef469d1b 100644 --- a/internal/provider/kubernetes/predicates.go +++ b/internal/provider/kubernetes/predicates.go @@ -349,30 +349,6 @@ func (r *gatewayAPIReconciler) httpRoutesForAuthenticationFilter(obj client.Obje return len(httpRoutes) != 0 } -// httpRoutesForRateLimitFilter tries finding HTTPRoute referents of the provided -// RateLimitFilter and returns true if any exist. -func (r *gatewayAPIReconciler) httpRoutesForRateLimitFilter(obj client.Object) bool { - ctx := context.Background() - filter, ok := obj.(*egv1a1.RateLimitFilter) - if !ok { - r.log.Info("unexpected object type, bypassing reconciliation", "object", obj) - return false - } - - // Check if the RateLimitFilter belongs to a managed HTTPRoute. - httpRouteList := &gwapiv1.HTTPRouteList{} - if err := r.client.List(ctx, httpRouteList, &client.ListOptions{ - FieldSelector: fields.OneTermEqualSelector(rateLimitFilterHTTPRouteIndex, utils.NamespacedName(filter).String()), - }); err != nil { - r.log.Error(err, "unable to find associated HTTPRoutes") - return false - } - - httpRoutes := r.filterHTTPRoutesByNamespaceLabels(httpRouteList.Items) - - return len(httpRoutes) != 0 -} - func (r *gatewayAPIReconciler) filterHTTPRoutesByNamespaceLabels(httpRoutes []gwapiv1.HTTPRoute) []gwapiv1.HTTPRoute { if len(r.namespaceLabels) == 0 { return httpRoutes diff --git a/internal/provider/kubernetes/routes.go b/internal/provider/kubernetes/routes.go index d8447b9917b..c8876e28166 100644 --- a/internal/provider/kubernetes/routes.go +++ b/internal/provider/kubernetes/routes.go @@ -108,7 +108,7 @@ func (r *gatewayAPIReconciler) processGRPCRoutes(ctx context.Context, gatewayNam resourceMap *resourceMappings, resourceTree *gatewayapi.Resources) error { grpcRouteList := &gwapiv1a2.GRPCRouteList{} - // An GRPCRoute may reference an AuthenticationFilter and RateLimitFilter, + // An GRPCRoute may reference an AuthenticationFilter, // so add them to the resource map first (if they exist). authenFilters, err := r.getAuthenticationFilters(ctx) if err != nil { @@ -119,15 +119,6 @@ func (r *gatewayAPIReconciler) processGRPCRoutes(ctx context.Context, gatewayNam resourceMap.authenFilters[utils.NamespacedName(&filter)] = &filter } - rateLimitFilters, err := r.getRateLimitFilters(ctx) - if err != nil { - return err - } - for i := range rateLimitFilters { - filter := rateLimitFilters[i] - resourceMap.rateLimitFilters[utils.NamespacedName(&filter)] = &filter - } - if err := r.client.List(ctx, grpcRouteList, &client.ListOptions{ FieldSelector: fields.OneTermEqualSelector(gatewayGRPCRouteIndex, gatewayNamespaceName), }); err != nil { @@ -224,18 +215,6 @@ func (r *gatewayAPIReconciler) processGRPCRoutes(ctx context.Context, gatewayNam } resourceTree.AuthenticationFilters = append(resourceTree.AuthenticationFilters, authFilter) - case egv1a1.KindRateLimitFilter: - key := types.NamespacedName{ - Namespace: grpcRoute.Namespace, - Name: string(filter.ExtensionRef.Name), - } - rateLimitFilter, ok := resourceMap.rateLimitFilters[key] - if !ok { - r.log.Error(err, "RateLimitFilter not found; bypassing rule", "index", i) - continue - } - - resourceTree.RateLimitFilters = append(resourceTree.RateLimitFilters, rateLimitFilter) default: // If the Kind does not match any Envoy Gateway resources, check if it's a Kind // managed by an extension and add to resourceTree @@ -271,7 +250,7 @@ func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNam resourceMap *resourceMappings, resourceTree *gatewayapi.Resources) error { httpRouteList := &gwapiv1.HTTPRouteList{} - // An HTTPRoute may reference an AuthenticationFilter, RateLimitFilter, or a filter managed + // An HTTPRoute may reference an AuthenticationFilter, or a filter managed // by an extension so add them to the resource map first (if they exist). authenFilters, err := r.getAuthenticationFilters(ctx) if err != nil { @@ -282,15 +261,6 @@ func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNam resourceMap.authenFilters[utils.NamespacedName(&filter)] = &filter } - rateLimitFilters, err := r.getRateLimitFilters(ctx) - if err != nil { - return err - } - for i := range rateLimitFilters { - filter := rateLimitFilters[i] - resourceMap.rateLimitFilters[utils.NamespacedName(&filter)] = &filter - } - extensionRefFilters, err := r.getExtensionRefFilters(ctx) if err != nil { return err @@ -451,18 +421,6 @@ func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNam } resourceTree.AuthenticationFilters = append(resourceTree.AuthenticationFilters, authFilter) - case egv1a1.KindRateLimitFilter: - key := types.NamespacedName{ - Namespace: httpRoute.Namespace, - Name: string(filter.ExtensionRef.Name), - } - rateLimitFilter, ok := resourceMap.rateLimitFilters[key] - if !ok { - r.log.Error(err, "RateLimitFilter not found; bypassing rule", "index", i) - continue - } - - resourceTree.RateLimitFilters = append(resourceTree.RateLimitFilters, rateLimitFilter) default: // If the Kind does not match any Envoy Gateway resources, check if it's a Kind // managed by an extension and add to resourceTree diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 5e680fc52ba..a94bcc00439 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -23,7 +23,6 @@ API group. - [EnvoyPatchPolicy](#envoypatchpolicy) - [EnvoyPatchPolicyList](#envoypatchpolicylist) - [EnvoyProxy](#envoyproxy) -- [RateLimitFilter](#ratelimitfilter) - [SecurityPolicy](#securitypolicy) - [SecurityPolicyList](#securitypolicylist) @@ -116,7 +115,7 @@ _Appears in:_ | Field | Description | | --- | --- | | `targetRef` _[PolicyTargetReferenceWithSectionName](#policytargetreferencewithsectionname)_ | targetRef is the name of the resource this policy is being attached to. This Policy and the TargetRef MUST be in the same namespace for this Policy to have effect and be applied to the Gateway. | -| `rateLimit` _[RateLimitFilterSpec](#ratelimitfilterspec)_ | RateLimit allows the user to limit the number of incoming requests to a predefined value based on attributes within the traffic flow. | +| `rateLimit` _[RateLimitPolicy](#ratelimitpolicy)_ | RateLimit allows the user to limit the number of incoming requests to a predefined value based on attributes within the traffic flow. | | `loadBalancer` _[LoadBalancer](#loadbalancer)_ | LoadBalancer policy to apply when routing traffic from the gateway to the backend endpoints | @@ -834,7 +833,7 @@ _Appears in:_ GlobalRateLimit defines global rate limit configuration. _Appears in:_ -- [RateLimitFilterSpec](#ratelimitfilterspec) +- [RateLimitPolicy](#ratelimitpolicy) | Field | Description | | --- | --- | @@ -1425,31 +1424,14 @@ _Appears in:_ -#### RateLimitFilter +#### RateLimitPolicy -RateLimitFilter allows the user to limit the number of incoming requests to a predefined value based on attributes within the traffic flow. - - - -| Field | Description | -| --- | --- | -| `apiVersion` _string_ | `gateway.envoyproxy.io/v1alpha1` -| `kind` _string_ | `RateLimitFilter` -| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.26/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. | -| `spec` _[RateLimitFilterSpec](#ratelimitfilterspec)_ | Spec defines the desired state of RateLimitFilter. | - - -#### RateLimitFilterSpec - - - -RateLimitFilterSpec defines the desired state of RateLimitFilter. +RateLimitPolicy defines the desired state of RateLimitFilter. _Appears in:_ - [BackendTrafficPolicySpec](#backendtrafficpolicyspec) -- [RateLimitFilter](#ratelimitfilter) | Field | Description | | --- | --- | @@ -1509,7 +1491,7 @@ _Underlying type:_ `string` RateLimitType specifies the types of RateLimiting. _Appears in:_ -- [RateLimitFilterSpec](#ratelimitfilterspec) +- [RateLimitPolicy](#ratelimitpolicy)