Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
ae64948
add admission control functionality
aburan28 Nov 15, 2025
fead370
add admission control functionality crds
aburan28 Nov 15, 2025
ed7451d
fix the lint errors
aburan28 Nov 30, 2025
31febb0
fix: address CI lint and gen-check failures for admission control
aburan28 Feb 13, 2026
0fca7f5
incorporate some feedback
aburan28 Feb 23, 2026
ce38d07
update helm template test outputs after merge with upstream/main
aburan28 Feb 28, 2026
eef4e1a
use envoy defaults
aburan28 Mar 2, 2026
24f177b
use envoy defaults
aburan28 Mar 2, 2026
37b648f
add out files
aburan28 Mar 6, 2026
a75dfac
add testdata gen
aburan28 Mar 8, 2026
4988451
regenerate crds
aburan28 Mar 8, 2026
3f7d253
setup admission control as http upstream filter
aburan28 Mar 15, 2026
3696a2c
change to aggression
aburan28 Mar 22, 2026
566c3a9
change to aggression
aburan28 Mar 22, 2026
a16039d
fix: resolve rebase conflicts and regenerate testdata
aburan28 Mar 30, 2026
807a476
fix: address review feedback for admission control
aburan28 Apr 10, 2026
6545ecc
Merge branch 'main' into adam--add-admission-control
aburan28 Apr 11, 2026
97fc2da
test: regenerate admission-control testdata
aburan28 Apr 11, 2026
ead9d6d
test: regenerate helm-template snapshots and extension docs
aburan28 Apr 11, 2026
2a8a41a
Merge remote-tracking branch 'upstream/main' into adam--add-admission…
aburan28 Apr 17, 2026
a65fc3d
fix(admission-control): use new() instead of ptr.To to satisfy forbid…
aburan28 Apr 17, 2026
a98b9e2
address review feedback: revert HCM filter ordering, hoist gRPC code …
aburan28 Apr 17, 2026
7b7bfdb
Remove namespace from admission control targetRef
aburan28 Apr 18, 2026
16fc1f4
Address admission control review feedback
aburan28 Apr 24, 2026
80c8975
Merge branch 'main' into adam--add-admission-control
jukie Apr 24, 2026
42a3dd0
Merge branch main into adam--add-admission-control
jukie Apr 27, 2026
d59ae24
Release note
jukie Apr 27, 2026
d9e91ff
CEL filtering for route types
jukie Apr 27, 2026
5b98d84
feedback
jukie Apr 29, 2026
ee5eba3
Merge branch 'main' into admission-control
jukie Apr 29, 2026
9962371
regen
jukie Apr 29, 2026
da89291
lint
jukie Apr 29, 2026
af4336f
Merge branch 'main' into admission-control
jukie Apr 29, 2026
c820084
trim statuscode field names
jukie Apr 29, 2026
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
126 changes: 126 additions & 0 deletions api/v1alpha1/admission_control.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// Copyright Envoy Gateway Authors
// SPDX-License-Identifier: Apache-2.0
// The full text of the Apache license is available in the LICENSE file at
// the root of the repo.

package v1alpha1

import (
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
)

// AdmissionControl configures health-based load shedding for upstream backends.
//
// Envoy tracks recent upstream responses over a sliding sampling window. When the
// observed success rate drops below the configured threshold, Envoy
// probabilistically rejects new requests before forwarding them upstream. This can
// reduce pressure on degraded backends and give them time to recover.
//
// All fields are optional. When omitted, Envoy's admission control defaults are used.
//
// +kubebuilder:validation:XValidation:rule="!has(self.minSuccessRate) || (self.minSuccessRate >= 1 && self.minSuccessRate <= 100)",message="minSuccessRate must be between 1 and 100"
// +kubebuilder:validation:XValidation:rule="!has(self.maxRejectionPercent) || (self.maxRejectionPercent >= 0 && self.maxRejectionPercent <= 100)",message="maxRejectionPercent must be between 0 and 100"
// +kubebuilder:validation:XValidation:rule="!has(self.samplingWindow) || duration(self.samplingWindow) >= duration('1s')",message="samplingWindow must be at least 1s"
type AdmissionControl struct {
// SamplingWindow defines the time window over which request success rates are calculated.
// Must be at least 1s; Envoy truncates the window to whole seconds and uses it as the
// denominator in RPS calculations, so sub-second values would produce a zero denominator.
// Defaults to 30s if not specified.
//
// +optional
SamplingWindow *gwapiv1.Duration `json:"samplingWindow,omitempty"`
Comment thread
jukie marked this conversation as resolved.

// MinSuccessRate is the lowest request success rate, as a percentage in the
// range [1, 100], at which the filter will not reject requests. Defaults to 95 if
// not specified. Envoy rejects values below 1%, so values lower than 1 are not allowed.
//
// +optional
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=100
MinSuccessRate *uint32 `json:"minSuccessRate,omitempty"`

// RejectionAggression controls how steeply the rejection probability rises
// as the observed success rate falls below MinSuccessRate. A value of 1
// produces a linear curve; higher values reject more aggressively for a
// given drop in success rate. Must be greater than 0; values below 1 are
// clamped to 1. Defaults to 1.
//
// +optional
// +kubebuilder:validation:Minimum=1
RejectionAggression *uint32 `json:"rejectionAggression,omitempty"`

// MinRequestRate defines the minimum requests per second below which requests will
// pass through the filter without rejection. Defaults to 0 if not specified.
//
// +optional
// +kubebuilder:validation:Minimum=0
MinRequestRate *uint32 `json:"minRequestRate,omitempty"`

// MaxRejectionPercent represents the upper limit of the rejection probability,
// expressed as a percentage in the range [0, 100]. Defaults to 80 if not specified.
//
// +optional
// +kubebuilder:validation:Minimum=0
// +kubebuilder:validation:Maximum=100
MaxRejectionPercent *uint32 `json:"maxRejectionPercent,omitempty"`

// SuccessCriteria defines what constitutes a successful request for both HTTP and gRPC.
//
// +optional
SuccessCriteria *AdmissionControlSuccessCriteria `json:"successCriteria,omitempty"`
}
Comment thread
jukie marked this conversation as resolved.

// AdmissionControlSuccessCriteria defines the criteria for determining successful requests.
type AdmissionControlSuccessCriteria struct {
// HTTP defines success criteria for HTTP requests.
//
// +optional
HTTP *HTTPSuccessCriteria `json:"http,omitempty"`

// GRPC defines success criteria for gRPC requests.
//
// +optional
GRPC *GRPCSuccessCriteria `json:"grpc,omitempty"`
}

// HTTPSuccessCriteria defines success criteria for HTTP requests.
type HTTPSuccessCriteria struct {
// StatusCodes defines HTTP status codes that are considered successful.
//
// +optional
StatusCodes []HTTPStatus `json:"statusCodes,omitempty"`
}

// GRPCSuccessCode defines gRPC status codes as defined in
// https://github.com/grpc/grpc/blob/master/doc/statuscodes.md#status-codes-and-their-use-in-grpc.
// +kubebuilder:validation:Enum=Ok;Cancelled;Unknown;InvalidArgument;DeadlineExceeded;NotFound;AlreadyExists;PermissionDenied;ResourceExhausted;FailedPrecondition;Aborted;OutOfRange;Unimplemented;Internal;Unavailable;DataLoss;Unauthenticated
type GRPCSuccessCode string

const (
GRPCSuccessCodeOk GRPCSuccessCode = "Ok"
GRPCSuccessCodeCancelled GRPCSuccessCode = "Cancelled"
GRPCSuccessCodeUnknown GRPCSuccessCode = "Unknown"
GRPCSuccessCodeInvalidArgument GRPCSuccessCode = "InvalidArgument"
GRPCSuccessCodeDeadlineExceeded GRPCSuccessCode = "DeadlineExceeded"
GRPCSuccessCodeNotFound GRPCSuccessCode = "NotFound"
GRPCSuccessCodeAlreadyExists GRPCSuccessCode = "AlreadyExists"
GRPCSuccessCodePermissionDenied GRPCSuccessCode = "PermissionDenied"
GRPCSuccessCodeResourceExhausted GRPCSuccessCode = "ResourceExhausted"
GRPCSuccessCodeFailedPrecondition GRPCSuccessCode = "FailedPrecondition"
GRPCSuccessCodeAborted GRPCSuccessCode = "Aborted"
GRPCSuccessCodeOutOfRange GRPCSuccessCode = "OutOfRange"
GRPCSuccessCodeUnimplemented GRPCSuccessCode = "Unimplemented"
GRPCSuccessCodeInternal GRPCSuccessCode = "Internal"
GRPCSuccessCodeUnavailable GRPCSuccessCode = "Unavailable"
GRPCSuccessCodeDataLoss GRPCSuccessCode = "DataLoss"
GRPCSuccessCodeUnauthenticated GRPCSuccessCode = "Unauthenticated"
)

// GRPCSuccessCriteria defines success criteria for gRPC requests.
type GRPCSuccessCriteria struct {
// StatusCodes defines gRPC status codes that are considered successful.
// Status codes are defined in https://github.com/grpc/grpc/blob/master/doc/statuscodes.md#status-codes-and-their-use-in-grpc.
//
// +optional
StatusCodes []GRPCSuccessCode `json:"statusCodes,omitempty"`
}
7 changes: 7 additions & 0 deletions api/v1alpha1/backendtrafficpolicy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type BackendTrafficPolicy struct {
// +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"
// +kubebuilder:validation:XValidation:rule="!has(self.compression) || !has(self.compressor)", message="either compression or compressor can be set, not both"
// +kubebuilder:validation:XValidation:rule="!has(self.requestBuffer) || !has(self.httpUpgrade) || self.httpUpgrade.size() == 0", message="requestBuffer cannot be used together with httpUpgrade"
// +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"
type BackendTrafficPolicySpec struct {
PolicyTargetReferences `json:",inline"`
ClusterSettings `json:",inline"`
Expand Down Expand Up @@ -74,6 +75,12 @@ type BackendTrafficPolicySpec struct {
// +optional
FaultInjection *FaultInjection `json:"faultInjection,omitempty"`

// AdmissionControl defines the admission control policy to be applied. This configuration
// probabilistically rejects requests based on the success rate of previous requests in a
// configurable sliding time window.
// +optional
AdmissionControl *AdmissionControl `json:"admissionControl,omitempty"`
Comment thread
jukie marked this conversation as resolved.

// UseClientProtocol configures Envoy to prefer sending requests to backends using
// the same HTTP protocol that the incoming request used. Defaults to false, which means
// that Envoy will use the protocol indicated by the attached BackendRef.
Expand Down
115 changes: 115 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading