Description:
A BackendTrafficPolicy global rate-limit rule currently carries a static limit (RateLimitValue{Requests, Unit}). Add the ability to source the limit per-request from dynamic metadata, the same way cost is already sourced from metadata via RateLimitCostFromMetadata (HitsAddend).
Use case: a multi-tenant gateway where each tenant has a different limit but all share one BackendTrafficPolicy. An upstream ext_proc writes the tenant limit into dynamic metadata and the rule reads it per-request, instead of creating a policy/route per tenant.
Envoy supports this on the route-level rate-limit action via RateLimit.limit (RateLimit_Override with a DynamicMetadata source). It uses the Global rate-limit service (RLS) path, the same path cost-from-metadata uses.
Proposed change, symmetric with cost-from-metadata:
API (api/v1alpha1/ratelimit_types.go) — add an optional metadata source to RateLimitValue, analogous to RateLimitCostMetadata. Requests/Unit stay required and act as the default when the metadata is absent. Restrict to Global via CEL.
type RateLimitValue struct {
Requests uint32 `json:"requests"`
Unit RateLimitUnit `json:"unit"`
// FromMetadata, when set, overrides Requests/Unit per-request from dynamic
// metadata. The metadata value must be a struct with `requests_per_unit`
// and `unit`. Requests/Unit are used as the default when metadata is absent.
// Only supported for Global rate limits.
// +optional
FromMetadata *RateLimitValueMetadata `json:"fromMetadata,omitempty"`
}
type RateLimitValueMetadata struct {
// +kubebuilder:validation:Required
Namespace string `json:"namespace"`
// +kubebuilder:validation:Required
Key string `json:"key"`
}
IR (internal/ir/xds.go) — carry the metadata source on ir.RateLimitRule (regenerate deepcopy).
Translator (internal/xds/translator/ratelimit.go, buildRouteRateLimits) — set the override on the route-level action, mirroring the existing HitsAddend block:
if m := rule.LimitMetadata; m != nil {
rateLimit.Limit = &routev3.RateLimit_Override{
OverrideSpecifier: &routev3.RateLimit_Override_DynamicMetadata_{
DynamicMetadata: &routev3.RateLimit_Override_DynamicMetadata{
MetadataKey: &metadatav3.MetadataKey{
Key: m.Namespace,
Path: []*metadatav3.MetadataKey_PathSegment{{
Segment: &metadatav3.MetadataKey_PathSegment_Key{Key: m.Key},
}},
},
},
},
}
}
Note: the override expects the metadata value to be a struct {requests_per_unit, unit}, not a plain number like cost. The ext_proc must write that struct.
Relevant Links:
Description:
A
BackendTrafficPolicyglobal rate-limit rule currently carries a static limit (RateLimitValue{Requests, Unit}). Add the ability to source the limit per-request from dynamic metadata, the same way cost is already sourced from metadata viaRateLimitCostFromMetadata(HitsAddend).Use case: a multi-tenant gateway where each tenant has a different limit but all share one
BackendTrafficPolicy. An upstream ext_proc writes the tenant limit into dynamic metadata and the rule reads it per-request, instead of creating a policy/route per tenant.Envoy supports this on the route-level rate-limit action via
RateLimit.limit(RateLimit_Overridewith aDynamicMetadatasource). It uses the Global rate-limit service (RLS) path, the same path cost-from-metadata uses.Proposed change, symmetric with cost-from-metadata:
API (
api/v1alpha1/ratelimit_types.go) — add an optional metadata source toRateLimitValue, analogous toRateLimitCostMetadata.Requests/Unitstay required and act as the default when the metadata is absent. Restrict to Global via CEL.IR (
internal/ir/xds.go) — carry the metadata source onir.RateLimitRule(regenerate deepcopy).Translator (
internal/xds/translator/ratelimit.go,buildRouteRateLimits) — set the override on the route-level action, mirroring the existingHitsAddendblock:Note: the override expects the metadata value to be a struct
{requests_per_unit, unit}, not a plain number like cost. The ext_proc must write that struct.Relevant Links:
RateLimit.Override: https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#config-route-v3-ratelimit-overrideRateLimitCostFromMetadatainapi/v1alpha1/ratelimit_types.go,rateLimitCostToHitsAddendininternal/xds/translator/ratelimit.go