diff --git a/api/v1alpha1/backendtrafficpolicy_types.go b/api/v1alpha1/backendtrafficpolicy_types.go index 6fee182818..42ab0c4d25 100644 --- a/api/v1alpha1/backendtrafficpolicy_types.go +++ b/api/v1alpha1/backendtrafficpolicy_types.go @@ -64,6 +64,12 @@ type BackendTrafficPolicySpec struct { // +optional RateLimit *RateLimitSpec `json:"rateLimit,omitempty"` + // BandwidthLimit allows the user to limit the bandwidth of traffic + // sent to and received from the backend. + // +optional + // +notImplementedHide + BandwidthLimit *BandwidthLimitSpec `json:"bandwidthLimit,omitempty"` + // FaultInjection defines the fault injection policy to be applied. This configuration can be used to // inject delays and abort requests to mimic failure scenarios such as service failures and overloads // +optional diff --git a/api/v1alpha1/bandwidthlimit_types.go b/api/v1alpha1/bandwidthlimit_types.go new file mode 100644 index 0000000000..3ae3cede69 --- /dev/null +++ b/api/v1alpha1/bandwidthlimit_types.go @@ -0,0 +1,92 @@ +// 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 ( + "k8s.io/apimachinery/pkg/api/resource" +) + +// BandwidthLimitSpec defines the desired state of BandwidthLimit. +// +// +kubebuilder:validation:XValidation:rule="has(self.request) || has(self.response)",message="at least one of request or response must be specified" +type BandwidthLimitSpec struct { + // Request configures bandwidth limits for traffic sent to the backend. + // + // +optional + Request *BandwidthLimitRequestConfig `json:"request,omitempty"` + + // Response configures bandwidth limits for traffic sent from the backend. + // + // +optional + Response *BandwidthLimitResponseConfig `json:"response,omitempty"` +} + +// BandwidthLimitRequestConfig defines the bandwidth limit configuration for the request direction. +type BandwidthLimitRequestConfig struct { + // Limit specifies the bandwidth limit as a bytes-per-unit throughput rate. + Limit BandwidthLimitValue `json:"limit"` +} + +// BandwidthLimitResponseConfig defines the bandwidth limit configuration for the response direction. +type BandwidthLimitResponseConfig struct { + // Limit specifies the bandwidth limit as a bytes-per-unit throughput rate. + Limit BandwidthLimitValue `json:"limit"` + + // ResponseTrailers configures the trailer headers appended to responses + // when bandwidth limiting introduces delays. + // + // +optional + ResponseTrailers *BandwidthLimitResponseTrailers `json:"responseTrailers,omitempty"` +} + +// BandwidthLimitValue defines the bandwidth limit value and its time unit. +type BandwidthLimitValue struct { + // Value specifies the bandwidth limit. + // + // +kubebuilder:validation:XIntOrString + // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" + Value resource.Quantity `json:"value"` + + // Unit specifies the time unit for the bandwidth limit (e.g. Second, Minute, Hour). + Unit BandwidthLimitUnit `json:"unit"` +} + +// BandwidthLimitResponseTrailers defines the trailer headers appended to responses. +type BandwidthLimitResponseTrailers struct { + // Prefix is prepended to each trailer header name. + // If not set, no prefix is added and the trailers are named as-is. + // For example, setting "x-eg" produces trailers such as "x-eg-bandwidth-request-delay-ms", + // while leaving it unset produces "bandwidth-request-delay-ms". + // + // The following four trailers can be added: + // "bandwidth-request-delay-ms" is delay time in milliseconds it took for the request stream transfer + // including request body transfer time and the time added by the filter. + // "bandwidth-response-delay-ms" is delay time in milliseconds it took for the response stream transfer + // including response body transfer time and the time added by the filter. + // "bandwidth-request-filter-delay-ms" is delay time in milliseconds in request stream transfer added by the filter. + // "bandwidth-response-filter-delay-ms" is delay time in milliseconds that added by the filter. + // + // +optional + Prefix *string `json:"prefix,omitempty"` +} + +// BandwidthLimitUnit specifies the intervals for setting bandwidth limits. +// Valid BandwidthLimitUnit values are "Second", "Minute", "Hour". +// +// +kubebuilder:validation:Enum=Second;Minute;Hour +type BandwidthLimitUnit string + +// BandwidthLimitUnit constants. +const ( + // BandwidthLimitUnitSecond specifies the bandwidth limit interval to be 1 second. + BandwidthLimitUnitSecond BandwidthLimitUnit = "Second" + + // BandwidthLimitUnitMinute specifies the bandwidth limit interval to be 1 minute. + BandwidthLimitUnitMinute BandwidthLimitUnit = "Minute" + + // BandwidthLimitUnitHour specifies the bandwidth limit interval to be 1 hour. + BandwidthLimitUnitHour BandwidthLimitUnit = "Hour" +) diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 22be0adbc7..746c6c732f 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -733,6 +733,11 @@ func (in *BackendTrafficPolicySpec) DeepCopyInto(out *BackendTrafficPolicySpec) *out = new(RateLimitSpec) (*in).DeepCopyInto(*out) } + if in.BandwidthLimit != nil { + in, out := &in.BandwidthLimit, &out.BandwidthLimit + *out = new(BandwidthLimitSpec) + (*in).DeepCopyInto(*out) + } if in.FaultInjection != nil { in, out := &in.FaultInjection, &out.FaultInjection *out = new(FaultInjection) @@ -859,6 +864,104 @@ func (in *BackendUtilization) DeepCopy() *BackendUtilization { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BandwidthLimitRequestConfig) DeepCopyInto(out *BandwidthLimitRequestConfig) { + *out = *in + in.Limit.DeepCopyInto(&out.Limit) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BandwidthLimitRequestConfig. +func (in *BandwidthLimitRequestConfig) DeepCopy() *BandwidthLimitRequestConfig { + if in == nil { + return nil + } + out := new(BandwidthLimitRequestConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BandwidthLimitResponseConfig) DeepCopyInto(out *BandwidthLimitResponseConfig) { + *out = *in + in.Limit.DeepCopyInto(&out.Limit) + if in.ResponseTrailers != nil { + in, out := &in.ResponseTrailers, &out.ResponseTrailers + *out = new(BandwidthLimitResponseTrailers) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BandwidthLimitResponseConfig. +func (in *BandwidthLimitResponseConfig) DeepCopy() *BandwidthLimitResponseConfig { + if in == nil { + return nil + } + out := new(BandwidthLimitResponseConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BandwidthLimitResponseTrailers) DeepCopyInto(out *BandwidthLimitResponseTrailers) { + *out = *in + if in.Prefix != nil { + in, out := &in.Prefix, &out.Prefix + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BandwidthLimitResponseTrailers. +func (in *BandwidthLimitResponseTrailers) DeepCopy() *BandwidthLimitResponseTrailers { + if in == nil { + return nil + } + out := new(BandwidthLimitResponseTrailers) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BandwidthLimitSpec) DeepCopyInto(out *BandwidthLimitSpec) { + *out = *in + if in.Request != nil { + in, out := &in.Request, &out.Request + *out = new(BandwidthLimitRequestConfig) + (*in).DeepCopyInto(*out) + } + if in.Response != nil { + in, out := &in.Response, &out.Response + *out = new(BandwidthLimitResponseConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BandwidthLimitSpec. +func (in *BandwidthLimitSpec) DeepCopy() *BandwidthLimitSpec { + if in == nil { + return nil + } + out := new(BandwidthLimitSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BandwidthLimitValue) DeepCopyInto(out *BandwidthLimitValue) { + *out = *in + out.Value = in.Value.DeepCopy() +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BandwidthLimitValue. +func (in *BandwidthLimitValue) DeepCopy() *BandwidthLimitValue { + if in == nil { + return nil + } + out := new(BandwidthLimitValue) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BasicAuth) DeepCopyInto(out *BasicAuth) { *out = *in diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml index 7fbc5880d0..bc9767dde0 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -50,6 +50,100 @@ spec: spec: description: spec defines the desired state of BackendTrafficPolicy. properties: + bandwidthLimit: + description: |- + BandwidthLimit allows the user to limit the bandwidth of traffic + sent to and received from the backend. + properties: + request: + description: Request configures bandwidth limits for traffic sent + to the backend. + properties: + limit: + description: Limit specifies the bandwidth limit as a bytes-per-unit + throughput rate. + properties: + unit: + description: Unit specifies the time unit for the bandwidth + limit (e.g. Second, Minute, Hour). + enum: + - Second + - Minute + - Hour + type: string + value: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: Value specifies the bandwidth limit. + x-kubernetes-int-or-string: true + required: + - unit + - value + type: object + required: + - limit + type: object + response: + description: Response configures bandwidth limits for traffic + sent from the backend. + properties: + limit: + description: Limit specifies the bandwidth limit as a bytes-per-unit + throughput rate. + properties: + unit: + description: Unit specifies the time unit for the bandwidth + limit (e.g. Second, Minute, Hour). + enum: + - Second + - Minute + - Hour + type: string + value: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: Value specifies the bandwidth limit. + x-kubernetes-int-or-string: true + required: + - unit + - value + type: object + responseTrailers: + description: |- + ResponseTrailers configures the trailer headers appended to responses + when bandwidth limiting introduces delays. + properties: + prefix: + description: |- + Prefix is prepended to each trailer header name. + If not set, no prefix is added and the trailers are named as-is. + For example, setting "x-eg" produces trailers such as "x-eg-bandwidth-request-delay-ms", + while leaving it unset produces "bandwidth-request-delay-ms". + + The following four trailers can be added: + "bandwidth-request-delay-ms" is delay time in milliseconds it took for the request stream transfer + including request body transfer time and the time added by the filter. + "bandwidth-response-delay-ms" is delay time in milliseconds it took for the response stream transfer + including response body transfer time and the time added by the filter. + "bandwidth-request-filter-delay-ms" is delay time in milliseconds in request stream transfer added by the filter. + "bandwidth-response-filter-delay-ms" is delay time in milliseconds that added by the filter. + type: string + type: object + required: + - limit + type: object + type: object + x-kubernetes-validations: + - message: at least one of request or response must be specified + rule: has(self.request) || has(self.response) circuitBreaker: description: |- Circuit Breaker settings for the upstream connections and requests. diff --git a/charts/gateway-helm/charts/crds/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-helm/charts/crds/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml index 22fdb12bda..0d8f2ee79a 100644 --- a/charts/gateway-helm/charts/crds/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-helm/charts/crds/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -49,6 +49,100 @@ spec: spec: description: spec defines the desired state of BackendTrafficPolicy. properties: + bandwidthLimit: + description: |- + BandwidthLimit allows the user to limit the bandwidth of traffic + sent to and received from the backend. + properties: + request: + description: Request configures bandwidth limits for traffic sent + to the backend. + properties: + limit: + description: Limit specifies the bandwidth limit as a bytes-per-unit + throughput rate. + properties: + unit: + description: Unit specifies the time unit for the bandwidth + limit (e.g. Second, Minute, Hour). + enum: + - Second + - Minute + - Hour + type: string + value: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: Value specifies the bandwidth limit. + x-kubernetes-int-or-string: true + required: + - unit + - value + type: object + required: + - limit + type: object + response: + description: Response configures bandwidth limits for traffic + sent from the backend. + properties: + limit: + description: Limit specifies the bandwidth limit as a bytes-per-unit + throughput rate. + properties: + unit: + description: Unit specifies the time unit for the bandwidth + limit (e.g. Second, Minute, Hour). + enum: + - Second + - Minute + - Hour + type: string + value: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: Value specifies the bandwidth limit. + x-kubernetes-int-or-string: true + required: + - unit + - value + type: object + responseTrailers: + description: |- + ResponseTrailers configures the trailer headers appended to responses + when bandwidth limiting introduces delays. + properties: + prefix: + description: |- + Prefix is prepended to each trailer header name. + If not set, no prefix is added and the trailers are named as-is. + For example, setting "x-eg" produces trailers such as "x-eg-bandwidth-request-delay-ms", + while leaving it unset produces "bandwidth-request-delay-ms". + + The following four trailers can be added: + "bandwidth-request-delay-ms" is delay time in milliseconds it took for the request stream transfer + including request body transfer time and the time added by the filter. + "bandwidth-response-delay-ms" is delay time in milliseconds it took for the response stream transfer + including response body transfer time and the time added by the filter. + "bandwidth-request-filter-delay-ms" is delay time in milliseconds in request stream transfer added by the filter. + "bandwidth-response-filter-delay-ms" is delay time in milliseconds that added by the filter. + type: string + type: object + required: + - limit + type: object + type: object + x-kubernetes-validations: + - message: at least one of request or response must be specified + rule: has(self.request) || has(self.response) circuitBreaker: description: |- Circuit Breaker settings for the upstream connections and requests. diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index f95ef5339a..176fd56a7e 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -600,6 +600,97 @@ _Appears in:_ | `keepResponseHeaders` | _boolean_ | false | false | KeepResponseHeaders keeps the ORCA load report headers/trailers before sending the response to the client.
Defaults to false. | +#### BandwidthLimitRequestConfig + + + +BandwidthLimitRequestConfig defines the bandwidth limit configuration for the request direction. + +_Appears in:_ +- [BandwidthLimitSpec](#bandwidthlimitspec) + +| Field | Type | Required | Default | Description | +| --- | --- | --- | --- | --- | +| `limit` | _[BandwidthLimitValue](#bandwidthlimitvalue)_ | true | | Limit specifies the bandwidth limit as a bytes-per-unit throughput rate. | + + +#### BandwidthLimitResponseConfig + + + +BandwidthLimitResponseConfig defines the bandwidth limit configuration for the response direction. + +_Appears in:_ +- [BandwidthLimitSpec](#bandwidthlimitspec) + +| Field | Type | Required | Default | Description | +| --- | --- | --- | --- | --- | +| `limit` | _[BandwidthLimitValue](#bandwidthlimitvalue)_ | true | | Limit specifies the bandwidth limit as a bytes-per-unit throughput rate. | +| `responseTrailers` | _[BandwidthLimitResponseTrailers](#bandwidthlimitresponsetrailers)_ | false | | ResponseTrailers configures the trailer headers appended to responses
when bandwidth limiting introduces delays. | + + +#### BandwidthLimitResponseTrailers + + + +BandwidthLimitResponseTrailers defines the trailer headers appended to responses. + +_Appears in:_ +- [BandwidthLimitResponseConfig](#bandwidthlimitresponseconfig) + +| Field | Type | Required | Default | Description | +| --- | --- | --- | --- | --- | +| `prefix` | _string_ | false | | Prefix is prepended to each trailer header name.
If not set, no prefix is added and the trailers are named as-is.
For example, setting "x-eg" produces trailers such as "x-eg-bandwidth-request-delay-ms",
while leaving it unset produces "bandwidth-request-delay-ms".
The following four trailers can be added:
"bandwidth-request-delay-ms" is delay time in milliseconds it took for the request stream transfer
including request body transfer time and the time added by the filter.
"bandwidth-response-delay-ms" is delay time in milliseconds it took for the response stream transfer
including response body transfer time and the time added by the filter.
"bandwidth-request-filter-delay-ms" is delay time in milliseconds in request stream transfer added by the filter.
"bandwidth-response-filter-delay-ms" is delay time in milliseconds that added by the filter. | + + +#### BandwidthLimitSpec + + + +BandwidthLimitSpec defines the desired state of BandwidthLimit. + +_Appears in:_ +- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) + +| Field | Type | Required | Default | Description | +| --- | --- | --- | --- | --- | +| `request` | _[BandwidthLimitRequestConfig](#bandwidthlimitrequestconfig)_ | false | | Request configures bandwidth limits for traffic sent to the backend. | +| `response` | _[BandwidthLimitResponseConfig](#bandwidthlimitresponseconfig)_ | false | | Response configures bandwidth limits for traffic sent from the backend. | + + +#### BandwidthLimitUnit + +_Underlying type:_ _string_ + +BandwidthLimitUnit specifies the intervals for setting bandwidth limits. +Valid BandwidthLimitUnit values are "Second", "Minute", "Hour". + +_Appears in:_ +- [BandwidthLimitValue](#bandwidthlimitvalue) + +| Value | Description | +| ----- | ----------- | +| `Second` | BandwidthLimitUnitSecond specifies the bandwidth limit interval to be 1 second.
| +| `Minute` | BandwidthLimitUnitMinute specifies the bandwidth limit interval to be 1 minute.
| +| `Hour` | BandwidthLimitUnitHour specifies the bandwidth limit interval to be 1 hour.
| + + +#### BandwidthLimitValue + + + +BandwidthLimitValue defines the bandwidth limit value and its time unit. + +_Appears in:_ +- [BandwidthLimitRequestConfig](#bandwidthlimitrequestconfig) +- [BandwidthLimitResponseConfig](#bandwidthlimitresponseconfig) + +| Field | Type | Required | Default | Description | +| --- | --- | --- | --- | --- | +| `value` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.32/#quantity-resource-api)_ | true | | Value specifies the bandwidth limit. | +| `unit` | _[BandwidthLimitUnit](#bandwidthlimitunit)_ | true | | Unit specifies the time unit for the bandwidth limit (e.g. Second, Minute, Hour). | + + #### BasicAuth diff --git a/test/cel-validation/backendtrafficpolicy_test.go b/test/cel-validation/backendtrafficpolicy_test.go index bb01173877..b8d283d020 100644 --- a/test/cel-validation/backendtrafficpolicy_test.go +++ b/test/cel-validation/backendtrafficpolicy_test.go @@ -3077,6 +3077,133 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, wantErrors: []string{"either compression or compressor can be set, not both"}, }, + { + desc: "valid bandwidthLimit with request only", + mutate: func(btp *egv1a1.BackendTrafficPolicy) { + btp.Spec = egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: "gateway.networking.k8s.io", + Kind: "Gateway", + Name: "eg", + }, + }, + }, + BandwidthLimit: &egv1a1.BandwidthLimitSpec{ + Request: &egv1a1.BandwidthLimitRequestConfig{ + Limit: egv1a1.BandwidthLimitValue{ + Value: resource.MustParse("10M"), + Unit: egv1a1.BandwidthLimitUnitSecond, + }, + }, + }, + } + }, + wantErrors: []string{}, + }, + { + desc: "valid bandwidthLimit with response only", + mutate: func(btp *egv1a1.BackendTrafficPolicy) { + btp.Spec = egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: "gateway.networking.k8s.io", + Kind: "Gateway", + Name: "eg", + }, + }, + }, + BandwidthLimit: &egv1a1.BandwidthLimitSpec{ + Response: &egv1a1.BandwidthLimitResponseConfig{ + Limit: egv1a1.BandwidthLimitValue{ + Value: resource.MustParse("100M"), + Unit: egv1a1.BandwidthLimitUnitSecond, + }, + }, + }, + } + }, + wantErrors: []string{}, + }, + { + desc: "valid bandwidthLimit with request and response set to different limits", + mutate: func(btp *egv1a1.BackendTrafficPolicy) { + btp.Spec = egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: "gateway.networking.k8s.io", + Kind: "Gateway", + Name: "eg", + }, + }, + }, + BandwidthLimit: &egv1a1.BandwidthLimitSpec{ + Request: &egv1a1.BandwidthLimitRequestConfig{ + Limit: egv1a1.BandwidthLimitValue{ + Value: resource.MustParse("10M"), + Unit: egv1a1.BandwidthLimitUnitSecond, + }, + }, + Response: &egv1a1.BandwidthLimitResponseConfig{ + Limit: egv1a1.BandwidthLimitValue{ + Value: resource.MustParse("100M"), + Unit: egv1a1.BandwidthLimitUnitSecond, + }, + }, + }, + } + }, + wantErrors: []string{}, + }, + { + desc: "valid bandwidthLimit with response and responseTrailers", + mutate: func(btp *egv1a1.BackendTrafficPolicy) { + btp.Spec = egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: "gateway.networking.k8s.io", + Kind: "Gateway", + Name: "eg", + }, + }, + }, + BandwidthLimit: &egv1a1.BandwidthLimitSpec{ + Response: &egv1a1.BandwidthLimitResponseConfig{ + Limit: egv1a1.BandwidthLimitValue{ + Value: resource.MustParse("10M"), + Unit: egv1a1.BandwidthLimitUnitSecond, + }, + ResponseTrailers: &egv1a1.BandwidthLimitResponseTrailers{ + Prefix: new("x-eg"), + }, + }, + }, + } + }, + wantErrors: []string{}, + }, + { + desc: "invalid bandwidthLimit with neither request nor response", + mutate: func(btp *egv1a1.BackendTrafficPolicy) { + btp.Spec = egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1.LocalPolicyTargetReference{ + Group: "gateway.networking.k8s.io", + Kind: "Gateway", + Name: "eg", + }, + }, + }, + BandwidthLimit: &egv1a1.BandwidthLimitSpec{}, + } + }, + wantErrors: []string{"at least one of request or response must be specified"}, + }, } for _, tc := range cases { diff --git a/test/helm/gateway-crds-helm/all.out.yaml b/test/helm/gateway-crds-helm/all.out.yaml index 61c6326964..3444c8b601 100644 --- a/test/helm/gateway-crds-helm/all.out.yaml +++ b/test/helm/gateway-crds-helm/all.out.yaml @@ -22577,6 +22577,100 @@ spec: spec: description: spec defines the desired state of BackendTrafficPolicy. properties: + bandwidthLimit: + description: |- + BandwidthLimit allows the user to limit the bandwidth of traffic + sent to and received from the backend. + properties: + request: + description: Request configures bandwidth limits for traffic sent + to the backend. + properties: + limit: + description: Limit specifies the bandwidth limit as a bytes-per-unit + throughput rate. + properties: + unit: + description: Unit specifies the time unit for the bandwidth + limit (e.g. Second, Minute, Hour). + enum: + - Second + - Minute + - Hour + type: string + value: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: Value specifies the bandwidth limit. + x-kubernetes-int-or-string: true + required: + - unit + - value + type: object + required: + - limit + type: object + response: + description: Response configures bandwidth limits for traffic + sent from the backend. + properties: + limit: + description: Limit specifies the bandwidth limit as a bytes-per-unit + throughput rate. + properties: + unit: + description: Unit specifies the time unit for the bandwidth + limit (e.g. Second, Minute, Hour). + enum: + - Second + - Minute + - Hour + type: string + value: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: Value specifies the bandwidth limit. + x-kubernetes-int-or-string: true + required: + - unit + - value + type: object + responseTrailers: + description: |- + ResponseTrailers configures the trailer headers appended to responses + when bandwidth limiting introduces delays. + properties: + prefix: + description: |- + Prefix is prepended to each trailer header name. + If not set, no prefix is added and the trailers are named as-is. + For example, setting "x-eg" produces trailers such as "x-eg-bandwidth-request-delay-ms", + while leaving it unset produces "bandwidth-request-delay-ms". + + The following four trailers can be added: + "bandwidth-request-delay-ms" is delay time in milliseconds it took for the request stream transfer + including request body transfer time and the time added by the filter. + "bandwidth-response-delay-ms" is delay time in milliseconds it took for the response stream transfer + including response body transfer time and the time added by the filter. + "bandwidth-request-filter-delay-ms" is delay time in milliseconds in request stream transfer added by the filter. + "bandwidth-response-filter-delay-ms" is delay time in milliseconds that added by the filter. + type: string + type: object + required: + - limit + type: object + type: object + x-kubernetes-validations: + - message: at least one of request or response must be specified + rule: has(self.request) || has(self.response) circuitBreaker: description: |- Circuit Breaker settings for the upstream connections and requests. diff --git a/test/helm/gateway-crds-helm/e2e.out.yaml b/test/helm/gateway-crds-helm/e2e.out.yaml index 764351c320..6812184192 100644 --- a/test/helm/gateway-crds-helm/e2e.out.yaml +++ b/test/helm/gateway-crds-helm/e2e.out.yaml @@ -550,6 +550,100 @@ spec: spec: description: spec defines the desired state of BackendTrafficPolicy. properties: + bandwidthLimit: + description: |- + BandwidthLimit allows the user to limit the bandwidth of traffic + sent to and received from the backend. + properties: + request: + description: Request configures bandwidth limits for traffic sent + to the backend. + properties: + limit: + description: Limit specifies the bandwidth limit as a bytes-per-unit + throughput rate. + properties: + unit: + description: Unit specifies the time unit for the bandwidth + limit (e.g. Second, Minute, Hour). + enum: + - Second + - Minute + - Hour + type: string + value: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: Value specifies the bandwidth limit. + x-kubernetes-int-or-string: true + required: + - unit + - value + type: object + required: + - limit + type: object + response: + description: Response configures bandwidth limits for traffic + sent from the backend. + properties: + limit: + description: Limit specifies the bandwidth limit as a bytes-per-unit + throughput rate. + properties: + unit: + description: Unit specifies the time unit for the bandwidth + limit (e.g. Second, Minute, Hour). + enum: + - Second + - Minute + - Hour + type: string + value: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: Value specifies the bandwidth limit. + x-kubernetes-int-or-string: true + required: + - unit + - value + type: object + responseTrailers: + description: |- + ResponseTrailers configures the trailer headers appended to responses + when bandwidth limiting introduces delays. + properties: + prefix: + description: |- + Prefix is prepended to each trailer header name. + If not set, no prefix is added and the trailers are named as-is. + For example, setting "x-eg" produces trailers such as "x-eg-bandwidth-request-delay-ms", + while leaving it unset produces "bandwidth-request-delay-ms". + + The following four trailers can be added: + "bandwidth-request-delay-ms" is delay time in milliseconds it took for the request stream transfer + including request body transfer time and the time added by the filter. + "bandwidth-response-delay-ms" is delay time in milliseconds it took for the response stream transfer + including response body transfer time and the time added by the filter. + "bandwidth-request-filter-delay-ms" is delay time in milliseconds in request stream transfer added by the filter. + "bandwidth-response-filter-delay-ms" is delay time in milliseconds that added by the filter. + type: string + type: object + required: + - limit + type: object + type: object + x-kubernetes-validations: + - message: at least one of request or response must be specified + rule: has(self.request) || has(self.response) circuitBreaker: description: |- Circuit Breaker settings for the upstream connections and requests. diff --git a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml index e6a7cf53d0..563325d13c 100644 --- a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml +++ b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml @@ -550,6 +550,100 @@ spec: spec: description: spec defines the desired state of BackendTrafficPolicy. properties: + bandwidthLimit: + description: |- + BandwidthLimit allows the user to limit the bandwidth of traffic + sent to and received from the backend. + properties: + request: + description: Request configures bandwidth limits for traffic sent + to the backend. + properties: + limit: + description: Limit specifies the bandwidth limit as a bytes-per-unit + throughput rate. + properties: + unit: + description: Unit specifies the time unit for the bandwidth + limit (e.g. Second, Minute, Hour). + enum: + - Second + - Minute + - Hour + type: string + value: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: Value specifies the bandwidth limit. + x-kubernetes-int-or-string: true + required: + - unit + - value + type: object + required: + - limit + type: object + response: + description: Response configures bandwidth limits for traffic + sent from the backend. + properties: + limit: + description: Limit specifies the bandwidth limit as a bytes-per-unit + throughput rate. + properties: + unit: + description: Unit specifies the time unit for the bandwidth + limit (e.g. Second, Minute, Hour). + enum: + - Second + - Minute + - Hour + type: string + value: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: Value specifies the bandwidth limit. + x-kubernetes-int-or-string: true + required: + - unit + - value + type: object + responseTrailers: + description: |- + ResponseTrailers configures the trailer headers appended to responses + when bandwidth limiting introduces delays. + properties: + prefix: + description: |- + Prefix is prepended to each trailer header name. + If not set, no prefix is added and the trailers are named as-is. + For example, setting "x-eg" produces trailers such as "x-eg-bandwidth-request-delay-ms", + while leaving it unset produces "bandwidth-request-delay-ms". + + The following four trailers can be added: + "bandwidth-request-delay-ms" is delay time in milliseconds it took for the request stream transfer + including request body transfer time and the time added by the filter. + "bandwidth-response-delay-ms" is delay time in milliseconds it took for the response stream transfer + including response body transfer time and the time added by the filter. + "bandwidth-request-filter-delay-ms" is delay time in milliseconds in request stream transfer added by the filter. + "bandwidth-response-filter-delay-ms" is delay time in milliseconds that added by the filter. + type: string + type: object + required: + - limit + type: object + type: object + x-kubernetes-validations: + - message: at least one of request or response must be specified + rule: has(self.request) || has(self.response) circuitBreaker: description: |- Circuit Breaker settings for the upstream connections and requests.