Skip to content

Commit 592ccd5

Browse files
authored
Merge branch 'main' into runner-event-metrics
Signed-off-by: Arko Dasgupta <arkodg@users.noreply.github.com>
2 parents d779078 + 21ea36d commit 592ccd5

233 files changed

Lines changed: 19996 additions & 1047 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v1.8.0-rc.0
1+
v1.8.0-rc.1

api/v1alpha1/admission_control.go

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// Copyright Envoy Gateway Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
// The full text of the Apache license is available in the LICENSE file at
4+
// the root of the repo.
5+
6+
package v1alpha1
7+
8+
import (
9+
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
10+
)
11+
12+
// AdmissionControl configures health-based load shedding for upstream backends.
13+
//
14+
// Envoy tracks recent upstream responses over a sliding sampling window. When the
15+
// observed success rate drops below the configured threshold, Envoy
16+
// probabilistically rejects new requests before forwarding them upstream. This can
17+
// reduce pressure on degraded backends and give them time to recover.
18+
//
19+
// All fields are optional. When omitted, Envoy's admission control defaults are used.
20+
//
21+
// +kubebuilder:validation:XValidation:rule="!has(self.minSuccessRate) || (self.minSuccessRate >= 1 && self.minSuccessRate <= 100)",message="minSuccessRate must be between 1 and 100"
22+
// +kubebuilder:validation:XValidation:rule="!has(self.maxRejectionPercent) || (self.maxRejectionPercent >= 0 && self.maxRejectionPercent <= 100)",message="maxRejectionPercent must be between 0 and 100"
23+
// +kubebuilder:validation:XValidation:rule="!has(self.samplingWindow) || duration(self.samplingWindow) >= duration('1s')",message="samplingWindow must be at least 1s"
24+
type AdmissionControl struct {
25+
// SamplingWindow defines the time window over which request success rates are calculated.
26+
// Must be at least 1s; Envoy truncates the window to whole seconds and uses it as the
27+
// denominator in RPS calculations, so sub-second values would produce a zero denominator.
28+
// Defaults to 30s if not specified.
29+
//
30+
// +optional
31+
SamplingWindow *gwapiv1.Duration `json:"samplingWindow,omitempty"`
32+
33+
// MinSuccessRate is the lowest request success rate, as a percentage in the
34+
// range [1, 100], at which the filter will not reject requests. Defaults to 95 if
35+
// not specified. Envoy rejects values below 1%, so values lower than 1 are not allowed.
36+
//
37+
// +optional
38+
// +kubebuilder:validation:Minimum=1
39+
// +kubebuilder:validation:Maximum=100
40+
MinSuccessRate *uint32 `json:"minSuccessRate,omitempty"`
41+
42+
// RejectionAggression controls how steeply the rejection probability rises
43+
// as the observed success rate falls below MinSuccessRate. A value of 1
44+
// produces a linear curve; higher values reject more aggressively for a
45+
// given drop in success rate. Must be greater than 0; values below 1 are
46+
// clamped to 1. Defaults to 1.
47+
//
48+
// +optional
49+
// +kubebuilder:validation:Minimum=1
50+
RejectionAggression *uint32 `json:"rejectionAggression,omitempty"`
51+
52+
// MinRequestRate defines the minimum requests per second below which requests will
53+
// pass through the filter without rejection. Defaults to 0 if not specified.
54+
//
55+
// +optional
56+
// +kubebuilder:validation:Minimum=0
57+
MinRequestRate *uint32 `json:"minRequestRate,omitempty"`
58+
59+
// MaxRejectionPercent represents the upper limit of the rejection probability,
60+
// expressed as a percentage in the range [0, 100]. Defaults to 80 if not specified.
61+
//
62+
// +optional
63+
// +kubebuilder:validation:Minimum=0
64+
// +kubebuilder:validation:Maximum=100
65+
MaxRejectionPercent *uint32 `json:"maxRejectionPercent,omitempty"`
66+
67+
// SuccessCriteria defines what constitutes a successful request for both HTTP and gRPC.
68+
//
69+
// +optional
70+
SuccessCriteria *AdmissionControlSuccessCriteria `json:"successCriteria,omitempty"`
71+
}
72+
73+
// AdmissionControlSuccessCriteria defines the criteria for determining successful requests.
74+
type AdmissionControlSuccessCriteria struct {
75+
// HTTP defines success criteria for HTTP requests.
76+
//
77+
// +optional
78+
HTTP *HTTPSuccessCriteria `json:"http,omitempty"`
79+
80+
// GRPC defines success criteria for gRPC requests.
81+
//
82+
// +optional
83+
GRPC *GRPCSuccessCriteria `json:"grpc,omitempty"`
84+
}
85+
86+
// HTTPSuccessCriteria defines success criteria for HTTP requests.
87+
type HTTPSuccessCriteria struct {
88+
// StatusCodes defines HTTP status codes that are considered successful.
89+
//
90+
// +optional
91+
StatusCodes []HTTPStatus `json:"statusCodes,omitempty"`
92+
}
93+
94+
// GRPCSuccessCode defines gRPC status codes as defined in
95+
// https://github.com/grpc/grpc/blob/master/doc/statuscodes.md#status-codes-and-their-use-in-grpc.
96+
// +kubebuilder:validation:Enum=Ok;Cancelled;Unknown;InvalidArgument;DeadlineExceeded;NotFound;AlreadyExists;PermissionDenied;ResourceExhausted;FailedPrecondition;Aborted;OutOfRange;Unimplemented;Internal;Unavailable;DataLoss;Unauthenticated
97+
type GRPCSuccessCode string
98+
99+
const (
100+
GRPCSuccessCodeOk GRPCSuccessCode = "Ok"
101+
GRPCSuccessCodeCancelled GRPCSuccessCode = "Cancelled"
102+
GRPCSuccessCodeUnknown GRPCSuccessCode = "Unknown"
103+
GRPCSuccessCodeInvalidArgument GRPCSuccessCode = "InvalidArgument"
104+
GRPCSuccessCodeDeadlineExceeded GRPCSuccessCode = "DeadlineExceeded"
105+
GRPCSuccessCodeNotFound GRPCSuccessCode = "NotFound"
106+
GRPCSuccessCodeAlreadyExists GRPCSuccessCode = "AlreadyExists"
107+
GRPCSuccessCodePermissionDenied GRPCSuccessCode = "PermissionDenied"
108+
GRPCSuccessCodeResourceExhausted GRPCSuccessCode = "ResourceExhausted"
109+
GRPCSuccessCodeFailedPrecondition GRPCSuccessCode = "FailedPrecondition"
110+
GRPCSuccessCodeAborted GRPCSuccessCode = "Aborted"
111+
GRPCSuccessCodeOutOfRange GRPCSuccessCode = "OutOfRange"
112+
GRPCSuccessCodeUnimplemented GRPCSuccessCode = "Unimplemented"
113+
GRPCSuccessCodeInternal GRPCSuccessCode = "Internal"
114+
GRPCSuccessCodeUnavailable GRPCSuccessCode = "Unavailable"
115+
GRPCSuccessCodeDataLoss GRPCSuccessCode = "DataLoss"
116+
GRPCSuccessCodeUnauthenticated GRPCSuccessCode = "Unauthenticated"
117+
)
118+
119+
// GRPCSuccessCriteria defines success criteria for gRPC requests.
120+
type GRPCSuccessCriteria struct {
121+
// StatusCodes defines gRPC status codes that are considered successful.
122+
// Status codes are defined in https://github.com/grpc/grpc/blob/master/doc/statuscodes.md#status-codes-and-their-use-in-grpc.
123+
//
124+
// +optional
125+
StatusCodes []GRPCSuccessCode `json:"statusCodes,omitempty"`
126+
}

api/v1alpha1/backendtrafficpolicy_types.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ type BackendTrafficPolicy struct {
4545
// +kubebuilder:validation:XValidation:rule="has(self.targetRefs) ? self.targetRefs.all(ref, ref.kind in ['Gateway', 'HTTPRoute', 'GRPCRoute', 'UDPRoute', 'TCPRoute', 'TLSRoute']) : true ", message="this policy can only have a targetRefs[*].kind of Gateway/HTTPRoute/GRPCRoute/TCPRoute/UDPRoute/TLSRoute"
4646
// +kubebuilder:validation:XValidation:rule="!has(self.compression) || !has(self.compressor)", message="either compression or compressor can be set, not both"
4747
// +kubebuilder:validation:XValidation:rule="!has(self.requestBuffer) || !has(self.httpUpgrade) || self.httpUpgrade.size() == 0", message="requestBuffer cannot be used together with httpUpgrade"
48+
// +kubebuilder:validation:XValidation:rule="!has(self.admissionControl) || ((!has(self.targetRef) || self.targetRef.kind in ['Gateway', 'HTTPRoute', 'GRPCRoute']) && (!has(self.targetRefs) || self.targetRefs.all(ref, ref.kind in ['Gateway', 'HTTPRoute', 'GRPCRoute'])) && (!has(self.targetSelectors) || self.targetSelectors.all(sel, sel.kind in ['Gateway', 'HTTPRoute', 'GRPCRoute'])))", message="admissionControl can only be used with HTTPRoute, GRPCRoute, or Gateway targets"
4849
type BackendTrafficPolicySpec struct {
4950
PolicyTargetReferences `json:",inline"`
5051
ClusterSettings `json:",inline"`
@@ -64,11 +65,22 @@ type BackendTrafficPolicySpec struct {
6465
// +optional
6566
RateLimit *RateLimitSpec `json:"rateLimit,omitempty"`
6667

68+
// BandwidthLimit allows the user to limit the bandwidth of traffic
69+
// sent to and received from the backend.
70+
// +optional
71+
BandwidthLimit *BandwidthLimitSpec `json:"bandwidthLimit,omitempty"`
72+
6773
// FaultInjection defines the fault injection policy to be applied. This configuration can be used to
6874
// inject delays and abort requests to mimic failure scenarios such as service failures and overloads
6975
// +optional
7076
FaultInjection *FaultInjection `json:"faultInjection,omitempty"`
7177

78+
// AdmissionControl defines the admission control policy to be applied. This configuration
79+
// probabilistically rejects requests based on the success rate of previous requests in a
80+
// configurable sliding time window.
81+
// +optional
82+
AdmissionControl *AdmissionControl `json:"admissionControl,omitempty"`
83+
7284
// UseClientProtocol configures Envoy to prefer sending requests to backends using
7385
// the same HTTP protocol that the incoming request used. Defaults to false, which means
7486
// that Envoy will use the protocol indicated by the attached BackendRef.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright Envoy Gateway Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
// The full text of the Apache license is available in the LICENSE file at
4+
// the root of the repo.
5+
6+
package v1alpha1
7+
8+
import (
9+
"k8s.io/apimachinery/pkg/api/resource"
10+
)
11+
12+
// BandwidthLimitSpec defines the desired state of BandwidthLimit.
13+
//
14+
// +kubebuilder:validation:XValidation:rule="has(self.request) || has(self.response)",message="at least one of request or response must be specified"
15+
type BandwidthLimitSpec struct {
16+
// Request configures bandwidth limits for traffic sent to the backend.
17+
//
18+
// +optional
19+
Request *BandwidthLimitRequestConfig `json:"request,omitempty"`
20+
21+
// Response configures bandwidth limits for traffic sent from the backend.
22+
//
23+
// +optional
24+
Response *BandwidthLimitResponseConfig `json:"response,omitempty"`
25+
}
26+
27+
// BandwidthLimitRequestConfig defines the bandwidth limit configuration for the request direction.
28+
type BandwidthLimitRequestConfig struct {
29+
// Limit specifies the bandwidth limit as a bytes-per-unit throughput rate.
30+
Limit BandwidthLimitValue `json:"limit"`
31+
}
32+
33+
// BandwidthLimitResponseConfig defines the bandwidth limit configuration for the response direction.
34+
type BandwidthLimitResponseConfig struct {
35+
// Limit specifies the bandwidth limit as a bytes-per-unit throughput rate.
36+
Limit BandwidthLimitValue `json:"limit"`
37+
38+
// ResponseTrailers configures the trailer headers appended to responses
39+
// when bandwidth limiting introduces delays.
40+
//
41+
// +optional
42+
ResponseTrailers *BandwidthLimitResponseTrailers `json:"responseTrailers,omitempty"`
43+
}
44+
45+
// BandwidthLimitValue defines the bandwidth limit value and its time unit.
46+
type BandwidthLimitValue struct {
47+
// Value specifies the bandwidth limit.
48+
//
49+
// +kubebuilder:validation:XIntOrString
50+
// +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
51+
Value resource.Quantity `json:"value"`
52+
53+
// Unit specifies the time unit for the bandwidth limit (e.g. Second, Minute, Hour).
54+
Unit BandwidthLimitUnit `json:"unit"`
55+
}
56+
57+
// BandwidthLimitResponseTrailers defines the trailer headers appended to responses.
58+
type BandwidthLimitResponseTrailers struct {
59+
// Prefix is prepended to each trailer header name.
60+
// If not set, no prefix is added and the trailers are named as-is.
61+
// For example, setting "x-eg" produces trailers such as "x-eg-bandwidth-request-delay-ms",
62+
// while leaving it unset produces "bandwidth-request-delay-ms".
63+
//
64+
// The following four trailers can be added:
65+
// "bandwidth-request-delay-ms" is delay time in milliseconds it took for the request stream transfer
66+
// including request body transfer time and the time added by the filter.
67+
// "bandwidth-response-delay-ms" is delay time in milliseconds it took for the response stream transfer
68+
// including response body transfer time and the time added by the filter.
69+
// "bandwidth-request-filter-delay-ms" is delay time in milliseconds in request stream transfer added by the filter.
70+
// "bandwidth-response-filter-delay-ms" is delay time in milliseconds that added by the filter.
71+
//
72+
// +kubebuilder:validation:Pattern=`^[^\r\n\x00]*$`
73+
// +optional
74+
Prefix *string `json:"prefix,omitempty"`
75+
}
76+
77+
// BandwidthLimitUnit specifies the intervals for setting bandwidth limits.
78+
// Valid BandwidthLimitUnit values are "Second", "Minute", "Hour".
79+
//
80+
// +kubebuilder:validation:Enum=Second;Minute;Hour
81+
type BandwidthLimitUnit string
82+
83+
// BandwidthLimitUnit constants.
84+
const (
85+
// BandwidthLimitUnitSecond specifies the bandwidth limit interval to be 1 second.
86+
BandwidthLimitUnitSecond BandwidthLimitUnit = "Second"
87+
88+
// BandwidthLimitUnitMinute specifies the bandwidth limit interval to be 1 minute.
89+
BandwidthLimitUnitMinute BandwidthLimitUnit = "Minute"
90+
91+
// BandwidthLimitUnitHour specifies the bandwidth limit interval to be 1 hour.
92+
BandwidthLimitUnitHour BandwidthLimitUnit = "Hour"
93+
)

api/v1alpha1/envoygateway_helpers.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,19 @@ func (kcr *KubernetesClientRateLimit) GetQPSAndBurst() (float32, int) {
381381
return float32(qps), int(burst)
382382
}
383383

384+
// GetExtensionManagers normalizes the singular ExtensionManager and plural ExtensionManagers
385+
// fields into a single list. The plural field takes precedence. If only the singular field
386+
// is set, it is returned as a single-element list. Returns nil if neither is set.
387+
func (e *EnvoyGatewaySpec) GetExtensionManagers() []ExtensionManager {
388+
if len(e.ExtensionManagers) > 0 {
389+
return e.ExtensionManagers
390+
}
391+
if e.ExtensionManager != nil {
392+
return []ExtensionManager{*e.ExtensionManager}
393+
}
394+
return nil
395+
}
396+
384397
// ShouldIncludeClusters returns true if clusters should be included in the translation hook.
385398
// When TranslationConfig is nil, defaults to true for backward compatibility.
386399
// When TranslationConfig is explicitly set, uses the configuration.

api/v1alpha1/envoygateway_types.go

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type EnvoyGateway struct {
4141
}
4242

4343
// EnvoyGatewaySpec defines the desired state of Envoy Gateway.
44+
// +kubebuilder:validation:XValidation:rule="!(has(self.extensionManager) && has(self.extensionManagers))",message="extensionManager and extensionManagers are mutually exclusive"
4445
type EnvoyGatewaySpec struct {
4546
// Gateway defines desired Gateway API specific configuration. If unset,
4647
// default configuration parameters will apply.
@@ -98,6 +99,19 @@ type EnvoyGatewaySpec struct {
9899
// +optional
99100
ExtensionManager *ExtensionManager `json:"extensionManager,omitempty"`
100101

102+
// ExtensionManagers defines multiple extension managers to register for the Envoy Gateway Control Plane.
103+
// Each extension's output becomes the next extension's input, enabling sequential chaining.
104+
// Each entry must have a unique Name field for identification.
105+
// This field is mutually exclusive with ExtensionManager.
106+
//
107+
// Warning: Enabling Extension Servers may lead to complete security compromise of your system.
108+
// Users that control Extension Servers can inject arbitrary configuration to proxies,
109+
// leading to high Confidentiality, Integrity and Availability risks.
110+
//
111+
// +optional
112+
// +kubebuilder:validation:MinItems=1
113+
ExtensionManagers []ExtensionManager `json:"extensionManagers,omitempty"`
114+
101115
// ExtensionAPIs defines the settings related to specific Gateway API Extensions
102116
// implemented by Envoy Gateway
103117
//
@@ -124,9 +138,10 @@ type EnvoyGatewaySpec struct {
124138
// 2. GatewayClass-level EnvoyProxy (referenced via GatewayClass.spec.parametersRef)
125139
// 3. This EnvoyProxy default spec
126140
//
127-
// Currently, the most specific EnvoyProxy configuration wins completely (replace semantics).
128-
// A future release will introduce merge semantics to allow combining configurations
129-
// across multiple levels.
141+
// The merge strategy for a more specific EnvoyProxy is controlled by its
142+
// spec.mergeType field. If mergeType is unset, the more specific EnvoyProxy
143+
// completely replaces less specific settings.
144+
// Note: mergeType has no effect in this default EnvoyProxySpec.
130145
//
131146
// +optional
132147
EnvoyProxy *EnvoyProxySpec `json:"envoyProxy,omitempty"`
@@ -659,14 +674,21 @@ type RateLimitRedisSettings struct {
659674
// ExtensionManager defines the configuration for registering an extension manager to
660675
// the Envoy Gateway control plane.
661676
type ExtensionManager struct {
677+
// Name is a unique identifier for this extension manager. Required when using
678+
// the plural ExtensionManagers field. Used for logging, metrics, and error identification.
679+
//
680+
// +optional
681+
Name string `json:"name,omitempty"`
682+
662683
// Resources defines the set of K8s resources the extension will handle as route
663684
// filter resources
664685
//
665686
// +optional
666687
Resources []GroupVersionKind `json:"resources,omitempty"`
667688

668689
// PolicyResources defines the set of K8S resources the extension server will handle
669-
// as directly attached GatewayAPI policies
690+
// as directly attached Gateway API policies. Only policies in the same namespace as
691+
// the target Gateway resources are supported. Cross-namespace attachments are not supported.
670692
//
671693
// +optional
672694
PolicyResources []GroupVersionKind `json:"policyResources,omitempty"`

api/v1alpha1/envoyproxy_types.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ type EnvoyProxySpec struct {
142142
//
143143
// - envoy.filters.http.ratelimit
144144
//
145+
// - envoy.filters.http.bandwidth_limit
146+
//
145147
// - envoy.filters.http.grpc_web
146148
//
147149
// - envoy.filters.http.grpc_stats
@@ -286,7 +288,7 @@ type FilterPosition struct {
286288
}
287289

288290
// EnvoyFilter defines the type of Envoy HTTP filter.
289-
// +kubebuilder:validation:Enum=envoy.filters.http.custom_response;envoy.filters.http.health_check;envoy.filters.http.fault;envoy.filters.http.cors;envoy.filters.http.header_mutation;envoy.filters.http.ext_authz;envoy.filters.http.api_key_auth;envoy.filters.http.basic_auth;envoy.filters.http.oauth2;envoy.filters.http.jwt_authn;envoy.filters.http.stateful_session;envoy.filters.http.buffer;envoy.filters.http.lua;envoy.filters.http.ext_proc;envoy.filters.http.wasm;envoy.filters.http.dynamic_modules;envoy.filters.http.geoip;envoy.filters.http.rbac;envoy.filters.http.local_ratelimit;envoy.filters.http.ratelimit;envoy.filters.http.grpc_web;envoy.filters.http.grpc_stats;envoy.filters.http.credential_injector;envoy.filters.http.compressor;envoy.filters.http.dynamic_forward_proxy
291+
// +kubebuilder:validation:Enum=envoy.filters.http.custom_response;envoy.filters.http.health_check;envoy.filters.http.fault;envoy.filters.http.cors;envoy.filters.http.header_mutation;envoy.filters.http.ext_authz;envoy.filters.http.api_key_auth;envoy.filters.http.basic_auth;envoy.filters.http.oauth2;envoy.filters.http.jwt_authn;envoy.filters.http.stateful_session;envoy.filters.http.buffer;envoy.filters.http.lua;envoy.filters.http.ext_proc;envoy.filters.http.wasm;envoy.filters.http.dynamic_modules;envoy.filters.http.geoip;envoy.filters.http.rbac;envoy.filters.http.local_ratelimit;envoy.filters.http.ratelimit;envoy.filters.http.bandwidth_limit;envoy.filters.http.grpc_web;envoy.filters.http.grpc_stats;envoy.filters.http.credential_injector;envoy.filters.http.compressor;envoy.filters.http.dynamic_forward_proxy
290292
type EnvoyFilter string
291293

292294
const (
@@ -351,6 +353,9 @@ const (
351353
// EnvoyFilterRateLimit defines the Envoy HTTP rate limit filter.
352354
EnvoyFilterRateLimit EnvoyFilter = "envoy.filters.http.ratelimit"
353355

356+
// EnvoyFilterBandwidthLimit defines the Envoy HTTP bandwidth limit filter.
357+
EnvoyFilterBandwidthLimit EnvoyFilter = "envoy.filters.http.bandwidth_limit"
358+
354359
// EnvoyFilterGRPCWeb defines the Envoy HTTP gRPC-web filter.
355360
EnvoyFilterGRPCWeb EnvoyFilter = "envoy.filters.http.grpc_web"
356361

0 commit comments

Comments
 (0)