Skip to content

Commit 70e8b66

Browse files
authored
api: adds cost specifier to RateLimitRule (#4957)
* api: usage based rate limit API support Signed-off-by: Takeshi Yoneda <[email protected]>
1 parent 4c29175 commit 70e8b66

File tree

6 files changed

+618
-0
lines changed

6 files changed

+618
-0
lines changed

api/v1alpha1/ratelimit_types.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ type LocalRateLimit struct {
6262
//
6363
// +optional
6464
// +kubebuilder:validation:MaxItems=16
65+
// +kubebuilder:validation:XValidation:rule="self.all(foo, !has(foo.cost) || !has(foo.cost.response))", message="response cost is not supported for Local Rate Limits"
6566
Rules []RateLimitRule `json:"rules"`
6667
}
6768

@@ -91,6 +92,91 @@ type RateLimitRule struct {
9192
// 429 HTTP status code is sent back to the client when
9293
// the selected requests have reached the limit.
9394
Limit RateLimitValue `json:"limit"`
95+
// Cost specifies the cost of requests and responses for the rule.
96+
//
97+
// This is optional and if not specified, the default behavior is to reduce the rate limit counters by 1 on
98+
// the request path and do not reduce the rate limit counters on the response path.
99+
//
100+
// +optional
101+
// +notImplementedHide
102+
Cost *RateLimitCost `json:"cost,omitempty"`
103+
}
104+
105+
type RateLimitCost struct {
106+
// Request specifies the number to reduce the rate limit counters
107+
// on the request path. If this is not specified, the default behavior
108+
// is to reduce the rate limit counters by 1.
109+
//
110+
// When Envoy receives a request that matches the rule, it tries to reduce the
111+
// rate limit counters by the specified number. If the counter doesn't have
112+
// enough capacity, the request is rate limited.
113+
//
114+
// +optional
115+
// +notImplementedHide
116+
Request *RateLimitCostSpecifier `json:"request,omitempty"`
117+
// Response specifies the number to reduce the rate limit counters
118+
// after the response is sent back to the client or the request stream is closed.
119+
//
120+
// The cost is used to reduce the rate limit counters for the matching requests.
121+
// Since the reduction happens after the request stream is complete, the rate limit
122+
// won't be enforced for the current request, but for the subsequent matching requests.
123+
//
124+
// This is optional and if not specified, the rate limit counters are not reduced
125+
// on the response path.
126+
//
127+
// Currently, this is only supported for HTTP Global Rate Limits.
128+
//
129+
// +optional
130+
// +notImplementedHide
131+
Response *RateLimitCostSpecifier `json:"response,omitempty"`
132+
}
133+
134+
// RateLimitCostSpecifier specifies where the Envoy retrieves the number to reduce the rate limit counters.
135+
//
136+
// +kubebuilder:validation:XValidation:rule="!(has(self.number) && has(self.metadata))",message="only one of number or metadata can be specified"
137+
type RateLimitCostSpecifier struct {
138+
// From specifies where to get the rate limit cost. Currently, only "Number" and "Metadata" are supported.
139+
//
140+
// +kubebuilder:validation:Required
141+
From RateLimitCostFrom `json:"from"`
142+
// Number specifies the fixed usage number to reduce the rate limit counters.
143+
// Using zero can be used to only check the rate limit counters without reducing them.
144+
//
145+
// +optional
146+
// +notImplementedHide
147+
Number *uint64 `json:"number,omitempty"`
148+
// Metadata specifies the per-request metadata to retrieve the usage number from.
149+
//
150+
// +optional
151+
// +notImplementedHide
152+
Metadata *RateLimitCostMetadata `json:"metadata,omitempty"`
153+
}
154+
155+
// RateLimitCostFrom specifies the source of the rate limit cost.
156+
// Valid RateLimitCostType values are "Number" and "Metadata".
157+
//
158+
// +kubebuilder:validation:Enum=Number;Metadata
159+
type RateLimitCostFrom string
160+
161+
const (
162+
// RateLimitCostFromNumber specifies the rate limit cost to be a fixed number.
163+
RateLimitCostFromNumber RateLimitCostFrom = "Number"
164+
// RateLimitCostFromMetadata specifies the rate limit cost to be retrieved from the per-request dynamic metadata.
165+
RateLimitCostFromMetadata RateLimitCostFrom = "Metadata"
166+
// TODO: add headers, etc. Anything that can be represented in "Format" can be added here.
167+
// https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#config-access-log-format
168+
)
169+
170+
// RateLimitCostMetadata specifies the filter metadata to retrieve the usage number from.
171+
type RateLimitCostMetadata struct {
172+
// Namespace is the namespace of the dynamic metadata.
173+
//
174+
// +kubebuilder:validation:Required
175+
Namespace string `json:"namespace"`
176+
// Key is the key to retrieve the usage number from the filter metadata.
177+
//
178+
// +kubebuilder:validation:Required
179+
Key string `json:"key"`
94180
}
95181

96182
// RateLimitSelectCondition specifies the attributes within the traffic flow that can

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 70 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)