Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions api/v1alpha1/ratelimit_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,10 @@ type GlobalRateLimit struct {
// matches two rules, one rate limited and one not, the final decision will be
// to rate limit the request.
//
// +patchMergeKey:"name"
// +patchStrategy:"merge"
// +kubebuilder:validation:MaxItems=64
Rules []RateLimitRule `json:"rules"`
Rules []RateLimitRule `json:"rules" patchMergeKey:"name" patchStrategy:"merge"`

// Shared determines whether the rate limit rules apply across all the policy targets.
// If set to true, the rule is treated as a common bucket and is shared across all policy targets (xRoutes).
Expand All @@ -69,15 +71,23 @@ type LocalRateLimit struct {
// matches two rules, one with 10rps and one with 20rps, the final limit will
// be based on the rule with 10rps.
//
// +patchMergeKey:"name"
// +patchStrategy:"merge"
//
// +optional
// +kubebuilder:validation:MaxItems=16
// +kubebuilder:validation:XValidation:rule="self.all(foo, !has(foo.cost) || !has(foo.cost.response))", message="response cost is not supported for Local Rate Limits"
Rules []RateLimitRule `json:"rules"`
Rules []RateLimitRule `json:"rules" patchMergeKey:"name" patchStrategy:"merge"`
}

// RateLimitRule defines the semantics for matching attributes
// from the incoming requests, and setting limits for them.
type RateLimitRule struct {
// Name is the name of the rule. This is used to identify the rule
// in the Envoy configuration and as a unique identifier for merging.
//
// +optional
Name string `json:"name,omitempty"`
Copy link
Member

@zhaohuabing zhaohuabing May 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An unique name will be generated if not provided by the user?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it won't happen.

// 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,11 @@ spec:
- requests
- unit
type: object
name:
description: |-
Name is the name of the rule. This is used to identify the rule
in the Envoy configuration and as a unique identifier for merging.
type: string
required:
- limit
type: object
Expand Down Expand Up @@ -1198,6 +1203,11 @@ spec:
- requests
- unit
type: object
name:
description: |-
Name is the name of the rule. This is used to identify the rule
in the Envoy configuration and as a unique identifier for merging.
type: string
required:
- limit
type: object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,11 @@ spec:
- requests
- unit
type: object
name:
description: |-
Name is the name of the rule. This is used to identify the rule
in the Envoy configuration and as a unique identifier for merging.
type: string
required:
- limit
type: object
Expand Down Expand Up @@ -1197,6 +1202,11 @@ spec:
- requests
- unit
type: object
name:
description: |-
Name is the name of the rule. This is used to identify the rule
in the Envoy configuration and as a unique identifier for merging.
type: string
required:
- limit
type: object
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
kind: BackendTrafficPolicy
metadata:
name: original
spec:
rateLimit:
type: Global
global:
rules:
- name: one
clientSelectors:
- headers:
- name: x-user-id
type: Exact
value: one
limit:
# 21 instead of 20 to test the zero request cost.
requests: 21
unit: Hour
cost:
request:
from: Number
number: 0
response:
from: Metadata
metadata:
namespace: io.envoyproxy.gateway.e2e
key: request_cost_set_by_ext_proc
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
kind: BackendTrafficPolicy
metadata:
creationTimestamp: null
name: original
spec:
rateLimit:
global:
rules:
- clientSelectors:
- headers:
- name: x-user-id
type: Exact
value: two
cost:
request:
from: Number
number: 0
response:
from: Metadata
metadata:
key: request_cost_set_by_ext_proc
namespace: io.envoyproxy.gateway.e2e
limit:
requests: 21
unit: Hour
name: two
type: Global
status:
ancestors: null
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
kind: BackendTrafficPolicy
metadata:
name: original
spec:
rateLimit:
type: Global
global:
rules:
- name: two
clientSelectors:
- headers:
- name: x-user-id
type: Exact
value: two
limit:
# 21 instead of 20 to test the zero request cost.
requests: 21
unit: Hour
cost:
request:
from: Number
number: 0
response:
from: Metadata
metadata:
namespace: io.envoyproxy.gateway.e2e
key: request_cost_set_by_ext_proc
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
kind: BackendTrafficPolicy
metadata:
creationTimestamp: null
name: original
spec:
rateLimit:
global:
rules:
- clientSelectors:
- headers:
- name: x-user-id
type: Exact
value: two
cost:
request:
from: Number
number: 0
response:
from: Metadata
metadata:
key: request_cost_set_by_ext_proc
namespace: io.envoyproxy.gateway.e2e
limit:
requests: 21
unit: Hour
name: two
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is order arbitrary or deterministic ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I.e. two before one / patch before original

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to double check, but I don't think we have way to control it.

- clientSelectors:
- headers:
- name: x-user-id
type: Exact
value: one
cost:
request:
from: Number
number: 0
response:
from: Metadata
metadata:
key: request_cost_set_by_ext_proc
namespace: io.envoyproxy.gateway.e2e
limit:
requests: 21
unit: Hour
name: one
type: Global
status:
ancestors: null
1 change: 1 addition & 0 deletions site/content/en/latest/api/extension_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -3869,6 +3869,7 @@ _Appears in:_

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `name` | _string_ | false | | Name is the name of the rule. This is used to identify the rule<br />in the Envoy configuration and as a unique identifier for merging. |
| `clientSelectors` | _[RateLimitSelectCondition](#ratelimitselectcondition) array_ | false | | ClientSelectors holds the list of select conditions to select<br />specific clients using attributes from the traffic flow.<br />All individual select conditions must hold True for this rule<br />and its limit to be applied.<br />If no client selectors are specified, the rule applies to all traffic of<br />the targeted Route.<br />If the policy targets a Gateway, the rule applies to each Route of the Gateway.<br />Please note that each Route has its own rate limit counters. For example,<br />if a Gateway has two Routes, and the policy has a rule with limit 10rps,<br />each Route will have its own 10rps limit. |
| `limit` | _[RateLimitValue](#ratelimitvalue)_ | true | | Limit holds the rate limit values.<br />This limit is applied for traffic flows when the selectors<br />compute to True, causing the request to be counted towards the limit.<br />The limit is enforced and the request is ratelimited, i.e. a response with<br />429 HTTP status code is sent back to the client when<br />the selected requests have reached the limit. |
| `cost` | _[RateLimitCost](#ratelimitcost)_ | false | | Cost specifies the cost of requests and responses for the rule.<br />This is optional and if not specified, the default behavior is to reduce the rate limit counters by 1 on<br />the request path and do not reduce the rate limit counters on the response path. |
Expand Down
10 changes: 10 additions & 0 deletions test/helm/gateway-crds-helm/all.out.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18559,6 +18559,11 @@ spec:
- requests
- unit
type: object
name:
description: |-
Name is the name of the rule. This is used to identify the rule
in the Envoy configuration and as a unique identifier for merging.
type: string
required:
- limit
type: object
Expand Down Expand Up @@ -18809,6 +18814,11 @@ spec:
- requests
- unit
type: object
name:
description: |-
Name is the name of the rule. This is used to identify the rule
in the Envoy configuration and as a unique identifier for merging.
type: string
required:
- limit
type: object
Expand Down
10 changes: 10 additions & 0 deletions test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1247,6 +1247,11 @@ spec:
- requests
- unit
type: object
name:
description: |-
Name is the name of the rule. This is used to identify the rule
in the Envoy configuration and as a unique identifier for merging.
type: string
required:
- limit
type: object
Expand Down Expand Up @@ -1497,6 +1502,11 @@ spec:
- requests
- unit
type: object
name:
description: |-
Name is the name of the rule. This is used to identify the rule
in the Envoy configuration and as a unique identifier for merging.
type: string
required:
- limit
type: object
Expand Down