diff --git a/api/v1alpha1/ratelimit_types.go b/api/v1alpha1/ratelimit_types.go
index 7ecca9e904..21727bb057 100644
--- a/api/v1alpha1/ratelimit_types.go
+++ b/api/v1alpha1/ratelimit_types.go
@@ -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).
@@ -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"`
// 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
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 b58c751757..66c01520e6 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
@@ -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
@@ -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
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml
index fb186d33d6..af436290d9 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml
@@ -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
@@ -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
diff --git a/internal/utils/testdata/backendtrafficpolicy_ratelimitrule_merge.in.yaml b/internal/utils/testdata/backendtrafficpolicy_ratelimitrule_merge.in.yaml
new file mode 100644
index 0000000000..3dc8eee659
--- /dev/null
+++ b/internal/utils/testdata/backendtrafficpolicy_ratelimitrule_merge.in.yaml
@@ -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
diff --git a/internal/utils/testdata/backendtrafficpolicy_ratelimitrule_merge.jsonmerge.out.yaml b/internal/utils/testdata/backendtrafficpolicy_ratelimitrule_merge.jsonmerge.out.yaml
new file mode 100644
index 0000000000..a679b04d1b
--- /dev/null
+++ b/internal/utils/testdata/backendtrafficpolicy_ratelimitrule_merge.jsonmerge.out.yaml
@@ -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
diff --git a/internal/utils/testdata/backendtrafficpolicy_ratelimitrule_merge.patch.yaml b/internal/utils/testdata/backendtrafficpolicy_ratelimitrule_merge.patch.yaml
new file mode 100644
index 0000000000..2d13bd03b0
--- /dev/null
+++ b/internal/utils/testdata/backendtrafficpolicy_ratelimitrule_merge.patch.yaml
@@ -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
diff --git a/internal/utils/testdata/backendtrafficpolicy_ratelimitrule_merge.strategicmerge.out.yaml b/internal/utils/testdata/backendtrafficpolicy_ratelimitrule_merge.strategicmerge.out.yaml
new file mode 100644
index 0000000000..1833716e3e
--- /dev/null
+++ b/internal/utils/testdata/backendtrafficpolicy_ratelimitrule_merge.strategicmerge.out.yaml
@@ -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
+ - 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
diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md
index 2c7a476643..bab62ebc7b 100644
--- a/site/content/en/latest/api/extension_types.md
+++ b/site/content/en/latest/api/extension_types.md
@@ -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
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
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 no client selectors are specified, the rule applies to all traffic of
the targeted Route.
If the policy targets a Gateway, the rule applies to each Route of the Gateway.
Please note that each Route has its own rate limit counters. For example,
if a Gateway has two Routes, and the policy has a rule with limit 10rps,
each Route will have its own 10rps limit. |
| `limit` | _[RateLimitValue](#ratelimitvalue)_ | true | | 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. |
| `cost` | _[RateLimitCost](#ratelimitcost)_ | false | | Cost specifies the cost of requests and responses for the rule.
This is optional and if not specified, the default behavior is to reduce the rate limit counters by 1 on
the request path and do not reduce the rate limit counters on the response path. |
diff --git a/test/helm/gateway-crds-helm/all.out.yaml b/test/helm/gateway-crds-helm/all.out.yaml
index 68bac7a103..e88959ed64 100644
--- a/test/helm/gateway-crds-helm/all.out.yaml
+++ b/test/helm/gateway-crds-helm/all.out.yaml
@@ -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
@@ -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
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 c478588002..addf7bddf1 100644
--- a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml
+++ b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml
@@ -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
@@ -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