From 4fdbb22e78bcec6c6d17ddeee22868241c29bd3c Mon Sep 17 00:00:00 2001 From: Arko Dasgupta Date: Tue, 3 Jan 2023 15:10:25 -0800 Subject: [PATCH] Ratelimiting Design (#706) * Overview and examples for Ratelimiting Started a design doc highlighting the `WHAT` and `WHY` Relates to https://github.com/envoyproxy/gateway/issues/670 Signed-off-by: Arko Dasgupta * ratelimit api Signed-off-by: Arko Dasgupta * update design Signed-off-by: Arko Dasgupta * rename to RateLimitFilter Signed-off-by: Arko Dasgupta * crd Signed-off-by: Arko Dasgupta * address comments * Use `Distinct` instead of `Any` * Highlight different between `matches` in `RateLimitFilter` and `HTTPRoute` * Elaborate more in design doc Signed-off-by: Arko Dasgupta * lint Signed-off-by: Arko Dasgupta * address comments from @danehans Signed-off-by: Arko Dasgupta * rm tabs Signed-off-by: Arko Dasgupta * lint Signed-off-by: Arko Dasgupta * more examples Signed-off-by: Arko Dasgupta * docs lint Signed-off-by: Arko Dasgupta * update API and CRD Signed-off-by: Arko Dasgupta * fix examples and add links Signed-off-by: Arko Dasgupta * fix example Signed-off-by: Arko Dasgupta * fix indent Signed-off-by: Arko Dasgupta * api typo Signed-off-by: Arko Dasgupta * add more notes on match conditions Signed-off-by: Arko Dasgupta * typo Signed-off-by: Arko Dasgupta * :%s/matches/clientSelectors/g Signed-off-by: Arko Dasgupta * regex docs && value max length Signed-off-by: Arko Dasgupta * fix comments for global rate limit type Signed-off-by: Arko Dasgupta * merge dependabot bumps Signed-off-by: Arko Dasgupta * fix comment on headers Signed-off-by: Arko Dasgupta Signed-off-by: Arko Dasgupta --- api/v1alpha1/ratelimitfilter_types.go | 164 +++++++++++ api/v1alpha1/zz_generated.deepcopy.go | 185 ++++++++++++ docs/latest/design/ratelimit.md | 269 ++++++++++++++++++ ...ateway.envoyproxy.io_ratelimitfilters.yaml | 161 +++++++++++ 4 files changed, 779 insertions(+) create mode 100644 api/v1alpha1/ratelimitfilter_types.go create mode 100644 docs/latest/design/ratelimit.md create mode 100644 internal/provider/kubernetes/config/crd/bases/gateway.envoyproxy.io_ratelimitfilters.yaml diff --git a/api/v1alpha1/ratelimitfilter_types.go b/api/v1alpha1/ratelimitfilter_types.go new file mode 100644 index 00000000000..4a042b5eb74 --- /dev/null +++ b/api/v1alpha1/ratelimitfilter_types.go @@ -0,0 +1,164 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +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"` +} + +// +kubebuilder:object:root=true + +// RateLimitFilterList contains a list of RateLimitFilter resources. +type RateLimitList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []RateLimitFilter `json:"items"` +} + +// RateLimitFilterSpec defines the desired state of RateLimitFilter. +// +union +type RateLimitFilterSpec struct { + // Type decides the scope for the RateLimits. + // Valid RateLimitType values are: + // + // * "Global" - In this mode, the rate limits are applied across all Envoy proxy instances. + // + // +unionDiscriminator + Type RateLimitType `json:"type"` + // Global rate limit configuration. + // + // +optional + Global *GlobalRateLimit `json:"global,omitempty"` +} + +// RateLimitType specifies the types of RateLimiting. +// +kubebuilder:validation:Enum=Global +type RateLimitType string + +const ( + // GlobalRateLimitType allows the rate limits to be applied across all Envoy proxy instances. + GlobalRateLimitType RateLimitType = "Global" +) + +// GlobalRateLimit defines the global rate limit configuration. +type GlobalRateLimit struct { + // 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. + // + // +kubebuilder:validation:MaxItems=16 + Rules []RateLimitRule `json:"rules"` +} + +// RateLimitRule defines the semantics for matching attributes +// from the incoming requests, and setting limits for them. +type RateLimitRule struct { + // 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. + // + // +optional + // +kubebuilder:validation:MaxItems=8 + ClientSelectors []RateLimitSelectCondition `json:"clientSelectors,omitempty"` + // 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. + Limit RateLimitValue `json:"limit"` +} + +// 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. +type RateLimitSelectCondition struct { + // Headers is a list of request headers to match. Multiple header values are ANDed together, + // meaning, a request MUST match all the specified headers. + // + // +listType=map + // +listMapKey=name + // +optional + // +kubebuilder:validation:MaxItems=16 + Headers []HeaderMatch `json:"headers,omitempty"` +} + +// HeaderMatch defines the match attributes within the HTTP Headers of the request. +type HeaderMatch struct { + // Type specifies how to match against the value of the header. + // + // +optional + // +kubebuilder:default=Exact + Type *HeaderMatchType `json:"type,omitempty"` + + // Name of the HTTP header. + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=256 + Name string `json:"name"` + + // 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. + // +optional + // +kubebuilder:validation:MaxLength=1024 + Value *string `json:"value,omitempty"` +} + +// HeaderMatchType specifies the semantics of how HTTP header values should be +// compared. Valid HeaderMatchType values are: +// +// - "Exact": Use this type to match the exact value of the Value field against the value of the specified HTTP Header. +// - "RegularExpression": Use this type to match a regular expression against the value of the specified HTTP Header. +// The regex string must adhere to the syntax documented in https://github.com/google/re2/wiki/Syntax. +// - "Distinct": Use this type to match any and all possible unique values encountered in the specified HTTP Header. +// Note that each unique value will receive its own rate limit bucket. +// +// +kubebuilder:validation:Enum=Exact;RegularExpression;Distinct +type HeaderMatchType string + +// HeaderMatchType constants. +const ( + HeaderMatchExact HeaderMatchType = "Exact" + HeaderMatchRegularExpression HeaderMatchType = "RegularExpression" + HeaderMatchDistinct HeaderMatchType = "Distinct" +) + +// RateLimitValue defines the limits for rate limiting. +type RateLimitValue struct { + Requests uint `json:"requests"` + Unit RateLimitUnit `json:"unit"` +} + +// RateLimitUnit specifies the intervals for setting rate limits. +// Valid RateLimitUnit values are: +// +// * "Second" +// * "Minute" +// * "Hour" +// * "Day" +// +// +kubebuilder:validation:Enum=Second;Minute;Hour;Day +type RateLimitUnit string diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 52f08bc0751..a007968e62e 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -94,6 +94,53 @@ func (in *AuthenticationFilterSpec) DeepCopy() *AuthenticationFilterSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GlobalRateLimit) DeepCopyInto(out *GlobalRateLimit) { + *out = *in + if in.Rules != nil { + in, out := &in.Rules, &out.Rules + *out = make([]RateLimitRule, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalRateLimit. +func (in *GlobalRateLimit) DeepCopy() *GlobalRateLimit { + if in == nil { + return nil + } + out := new(GlobalRateLimit) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HeaderMatch) DeepCopyInto(out *HeaderMatch) { + *out = *in + if in.Type != nil { + in, out := &in.Type, &out.Type + *out = new(HeaderMatchType) + **out = **in + } + if in.Value != nil { + in, out := &in.Value, &out.Value + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeaderMatch. +func (in *HeaderMatch) DeepCopy() *HeaderMatch { + if in == nil { + return nil + } + out := new(HeaderMatch) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *JwtAuthenticationFilterProvider) DeepCopyInto(out *JwtAuthenticationFilterProvider) { *out = *in @@ -115,6 +162,144 @@ func (in *JwtAuthenticationFilterProvider) DeepCopy() *JwtAuthenticationFilterPr return out } +// 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 *RateLimitFilterSpec) DeepCopyInto(out *RateLimitFilterSpec) { + *out = *in + if in.Global != nil { + in, out := &in.Global, &out.Global + *out = new(GlobalRateLimit) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RateLimitFilterSpec. +func (in *RateLimitFilterSpec) DeepCopy() *RateLimitFilterSpec { + if in == nil { + return nil + } + out := new(RateLimitFilterSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RateLimitList) DeepCopyInto(out *RateLimitList) { + *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 RateLimitList. +func (in *RateLimitList) DeepCopy() *RateLimitList { + if in == nil { + return nil + } + out := new(RateLimitList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RateLimitList) 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 *RateLimitRule) DeepCopyInto(out *RateLimitRule) { + *out = *in + if in.ClientSelectors != nil { + in, out := &in.ClientSelectors, &out.ClientSelectors + *out = make([]RateLimitSelectCondition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + out.Limit = in.Limit +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RateLimitRule. +func (in *RateLimitRule) DeepCopy() *RateLimitRule { + if in == nil { + return nil + } + out := new(RateLimitRule) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RateLimitSelectCondition) DeepCopyInto(out *RateLimitSelectCondition) { + *out = *in + if in.Headers != nil { + in, out := &in.Headers, &out.Headers + *out = make([]HeaderMatch, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RateLimitSelectCondition. +func (in *RateLimitSelectCondition) DeepCopy() *RateLimitSelectCondition { + if in == nil { + return nil + } + out := new(RateLimitSelectCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RateLimitValue) DeepCopyInto(out *RateLimitValue) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RateLimitValue. +func (in *RateLimitValue) DeepCopy() *RateLimitValue { + if in == nil { + return nil + } + out := new(RateLimitValue) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RemoteJWKS) DeepCopyInto(out *RemoteJWKS) { *out = *in diff --git a/docs/latest/design/ratelimit.md b/docs/latest/design/ratelimit.md new file mode 100644 index 00000000000..17ba842fdba --- /dev/null +++ b/docs/latest/design/ratelimit.md @@ -0,0 +1,269 @@ +# Rate Limit Design + +## Overview + +Rate limit is a feature that allows the user to limit the number of incoming requests +to a predefined value based on attributes within the traffic flow. + +Here are some reasons why a user may want to implements Rate limits + +* To prevent malicious activity such as DDoS attacks. +* To prevent applications and its resources (such as a database) from getting overloaded. +* To create API limits based on user entitlements. + +## Scope Types + +The rate limit type here describes the scope of rate limits. + +* Global - In this case, the rate limit is common across all the instances of Envoy proxies +where its applied i.e. if the data plane has 2 replicas of Envoy running, and the rate limit is +10 requests/second, this limit is common and will be hit if 5 requests pass through the first replica +and 5 requests pass through the second replica within the same second. + +* Local - In this case, the rate limits are specific to each instance/replica of Envoy running. +Note - This is not part of the initial design and will be added as a future enhancement. + +## Match Types + +### Rate limit a specific traffic flow + +* Here is an example of a ratelimit implemented by the application developer to limit a specific user +by matching on a custom `x-user-id` header with a value set to `one` + +```yaml +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: RateLimitFilter +metadata: + name: ratelimit-specific-user +spec: + type: Global + global: + rules: + - clientSelectors: + - headers: + - name: x-user-id + value: one + limit: + requests: 10 + unit: Hour +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: example +spec: + parentRefs: + - name: eg + hostnames: + - www.example.com + rules: + - clientSelectors: + - path: + type: PathPrefix + value: /foo + filters: + - type: ExtensionRef + extensionRef: + group: gateway.envoyproxy.io + kind: RateLimitFilter + name: ratelimit-specific-user + backendRefs: + - name: backend + port: 3000 +``` + +### Rate limit all traffic flows + +* Here is an example of a rate limit implemented by the application developer that limits the total requests made +to a specific route to safeguard health of internal application components. In this case, no specific `headers` match +is specified, and the rate limit is applied to all traffic flows accepted by this `HTTPRoute`. + +```yaml +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: RateLimitFilter +metadata: + name: ratelimit-all-requests +spec: + type: Global + global: + rules: + - limit: + requests: 1000 + unit: Second +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: example +spec: + parentRefs: + - name: eg + hostnames: + - www.example.com + rules: + - clientSelectors: + - path: + type: PathPrefix + value: /foo + filters: + - type: ExtensionRef + extensionRef: + group: gateway.envoyproxy.io + kind: RateLimitFilter + name: ratelimit-all-requests + backendRefs: + - name: backend + port: 3000 +``` + +### Rate limit per distinct value + +* Here is an example of a rate limit implemented by the application developer to limit any unique user +by matching on a custom `x-user-id` header. Here, user A (recognised from the traffic flow using the header +`x-user-id` and value `a`) will be rate limited at 10 requests/hour and so will user B +(recognised from the traffic flow using the header `x-user-id` and value `b`). + +```yaml +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: RateLimitFilter +metadata: + name: ratelimit-per-user +spec: + type: Global + global: + rules: + - clientSelectors: + - headers: + - type: Distinct + name: x-user-id + limit: + requests: 10 + unit: Hour +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: example +spec: + parentRefs: + - name: eg + hostnames: + - www.example.com + rules: + - clientSelectors: + - path: + type: PathPrefix + value: /foo + filters: + - type: ExtensionRef + extensionRef: + group: gateway.envoyproxy.io + kind: RateLimitFilter + name: ratelimit-per-user + backendRefs: + - name: backend + port: 3000 +``` + +## Multiple RateLimitFilters, rules and clientSelectors +* Users can create multiple `RateLimitFilter`s and apply it to the same `HTTPRoute`. In such a case each +`RateLimitFilter` will be applied to the route and matched (and limited) in a mutually exclusive way, independent of each other. +* Rate limits are applied for each `RateLimitFilter` `rule` when ALL the conditions under `clientSelectors` hold true. + +Here's an example highlighting this - + +``` +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: RateLimitFilter +metadata: + name: ratelimit-all-safeguard-app +spec: + type: Global + global: + rules: + - limit: + requests: 100 + unit: Second +--- + +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: RateLimitFilter +metadata: + name: ratelimit-per-user +spec: + type: Global + global: + rules: + - clientSelectors: + - headers: + - type: Distinct + name: x-user-id + limit: + requests: 1000 + unit: Hour +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: example +spec: + parentRefs: + - name: eg + hostnames: + - www.example.com + rules: + - clientSelectors: + - path: + type: PathPrefix + value: /foo + filters: + - type: ExtensionRef + extensionRef: + group: gateway.envoyproxy.io + kind: RateLimitFilter + name: ratelimit-per-user + - type: ExtensionRef + extensionRef: + group: gateway.envoyproxy.io + kind: RateLimitFilter + name: ratelimit-all-safeguard-app + backendRefs: + - name: backend + port: 3000 +``` + +* The user has created two `RateLimitFilter`s and has attached it to a `HTTPRoute` - one(`ratelimit-all-safeguard-app`) to +ensure that the backend does not get overwhelmed with requests, any excess requests are rate limited irrespective of +the attributes within the traffic flow, and another(`ratelimit-per-user`) to rate limit each distinct user client +who can be differentiated using the `x-user-id` header, to ensure that each client does not make exessive requests to the backend. +* If user `baz` (identified with the header and value of `x-user-id: baz`) sends 90 requests within the first second, and +user `bar` sends 11 more requests during that same interval of 1 second, and user `bar` sends the 101th request within that second, +the rule defined in `ratelimit-all-safeguard-app` gets activated and Envoy Gateway will ratelimit the request sent by `bar` (and any other +request sent within that 1 second). After 1 second, the rate limit counter associated with the `ratelimit-all-safeguard-app` rule +is reset and again evaluated. +* If user `bar` also ends up sending 90 more requests within the hour, summing up `bar`'s total request count to 101, the rate limit rule +defined within `ratelimit-per-user` will get activated, and `bar`'s requests will be rate limited again until the hour interval ends. +* Within the same above hour, if `baz` sends 991 more requests, summing up `baz`'s total request count to 1001, the rate limit rule defined +within `ratelimit-per-user` will get activated for `baz`, and `baz`'s requests will also be rate limited until the hour interval ends. + +## Design Decisions + +* The initial design uses an Extension filter to apply the Rate Limit functionality on a specific [HTTPRoute][]. +This was preferred over the [PolicyAttachment][] extension mechanism, because it is unclear whether Rate Limit +will be required to be enforced or overridden by the platform administrator or not. +* The RateLimitFilter can only be applied as a filter to a [HTTPRouteRule[], applying it across all backends within a [HTTPRoute][] +and cannot be applied a filter within a [HTTPBackendRef][] for a specific backend. +* The [HTTPRoute][] API has a [matches][] field within each [rule][] to select a specific traffic flow to be routed to +the destination backend. The RateLimitFilter API that can be attached to an HTTPRoute via an [extensionRef][] filter, +also has a `clientSelectors` field within each `rule` to select attributes within the traffic flow to rate limit specific clients. +The two levels of selectors/matches allow for flexibility and aim to hold match information specific to its use, allowing the author/owner +of each configuration to be different. It also allows the `clientSelectors` field within the RateLimitFilter to be enhanced with other matchable +attribute such as [IP subnet][] in the future that are not relevant in the [HTTPRoute][] API. + +[PolicyAttachment]: https://gateway-api.sigs.k8s.io/references/policy-attachment/ +[HTTPRoute]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRoute +[HTTPBackendRef]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io%2fv1beta1.HTTPBackendRef +[matches]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteMatch +[rule]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteMatch +[extensionRef]: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteFilterType +[IP subnet]: https://en.wikipedia.org/wiki/Subnetwork diff --git a/internal/provider/kubernetes/config/crd/bases/gateway.envoyproxy.io_ratelimitfilters.yaml b/internal/provider/kubernetes/config/crd/bases/gateway.envoyproxy.io_ratelimitfilters.yaml new file mode 100644 index 00000000000..97ff3f1608a --- /dev/null +++ b/internal/provider/kubernetes/config/crd/bases/gateway.envoyproxy.io_ratelimitfilters.yaml @@ -0,0 +1,161 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + 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 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 + 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: \n * \"Second\" * \"Minute\" * \"Hour\" * \"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: \n * \"Global\" - In this mode, the rate limits are + applied across all Envoy proxy instances." + enum: + - Global + type: string + required: + - type + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {}