diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index c7a5bee84ff..938a0fa2c49 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -6,26 +6,24 @@
version: 2
updates:
- package-ecosystem: docker
- directory: /tools/docker/envoy-gateway/
- schedule:
- interval: weekly
- - package-ecosystem: docker
- directory: /site
+ directories:
+ - /tools/docker/envoy-gateway/
+ - /site
schedule:
interval: weekly
- package-ecosystem: github-actions
- directory: /
+ directories:
+ - /
+ - /tools/github-actions/setup-deps
schedule:
interval: weekly
ignore:
# skip to update retest, because it won't work with the latest version
- dependency-name: "envoyproxy/toolshed/gh-actions/retest"
- - package-ecosystem: github-actions
- directory: /tools/github-actions/setup-deps
- schedule:
- interval: weekly
- package-ecosystem: gomod
- directory: /
+ directories:
+ - "/"
+ - "examples/extension-server"
schedule:
interval: weekly
groups:
@@ -35,35 +33,22 @@ updates:
go.opentelemetry.io:
patterns:
- "go.opentelemetry.io/*"
+ golang.org:
+ patterns:
+ - "golang.org/*"
- package-ecosystem: pip
- directory: /tools/src/codespell
- schedule:
- interval: weekly
- - package-ecosystem: gomod
- directory: /tools/src/helm-docs
- schedule:
- interval: weekly
- - package-ecosystem: gomod
- directory: /tools/src/buf
+ directories:
+ - /tools/src/codespell
+ - /tools/src/sphinx-build
+ - /tools/src/yamllint
schedule:
interval: weekly
- package-ecosystem: gomod
- directory: /tools/src/golangci-lint
- schedule:
- interval: weekly
- - package-ecosystem: gomod
- directory: /tools/src/kind
- schedule:
- interval: weekly
- - package-ecosystem: gomod
- directory: /tools/src/setup-envtest
- schedule:
- interval: weekly
- - package-ecosystem: pip
- directory: /tools/src/sphinx-build
- schedule:
- interval: weekly
- - package-ecosystem: pip
- directory: /tools/src/yamllint
+ directories:
+ - /tools/src/helm-docs
+ - /tools/src/buf
+ - /tools/src/golangci-lint
+ - /tools/src/kind
+ - /tools/src/setup-envtest
schedule:
interval: weekly
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index d3e4cd0a458..5cde7a2c549 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -36,14 +36,14 @@ jobs:
- uses: ./tools/github-actions/setup-deps
- name: Initialize CodeQL
- uses: github/codeql-action/init@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a # v3.25.15
+ uses: github/codeql-action/init@429e1977040da7a23b6822b13c129cd1ba93dbb2 # v3.26.2
with:
languages: ${{ matrix.language }}
- name: Autobuild
- uses: github/codeql-action/autobuild@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a # v3.25.15
+ uses: github/codeql-action/autobuild@429e1977040da7a23b6822b13c129cd1ba93dbb2 # v3.26.2
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a # v3.25.15
+ uses: github/codeql-action/analyze@429e1977040da7a23b6822b13c129cd1ba93dbb2 # v3.26.2
with:
category: "/language:${{matrix.language}}"
diff --git a/.github/workflows/license-scan.yml b/.github/workflows/license-scan.yml
index 31014adf8a5..68143314ecc 100644
--- a/.github/workflows/license-scan.yml
+++ b/.github/workflows/license-scan.yml
@@ -18,7 +18,7 @@ jobs:
- name: Checkout code
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Run scanner
- uses: google/osv-scanner-action/osv-scanner-action@7ac94f9d40028db4cacf8d53adec6626f5d3d2f7 # v1.8.2
+ uses: google/osv-scanner-action/osv-scanner-action@c615bb556a9a61495d218c7d439e7c8abbbfb151 # v1.8.3
with:
scan-args: |-
--skip-git
diff --git a/.github/workflows/osv-scanner.yml b/.github/workflows/osv-scanner.yml
index 424ff41a189..8e2117a97e1 100644
--- a/.github/workflows/osv-scanner.yml
+++ b/.github/workflows/osv-scanner.yml
@@ -16,7 +16,7 @@ on:
jobs:
scan-scheduled:
if: ${{ github.event_name == 'push' || github.event_name == 'schedule' }}
- uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@7ac94f9d40028db4cacf8d53adec6626f5d3d2f7" # v1.8.2
+ uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@c615bb556a9a61495d218c7d439e7c8abbbfb151" # v1.8.3
permissions:
actions: read
contents: read
@@ -32,7 +32,7 @@ jobs:
scan-pr:
if: ${{ github.event_name == 'pull_request' || github.event_name == 'merge_group' }}
- uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml@7ac94f9d40028db4cacf8d53adec6626f5d3d2f7" # v1.8.2
+ uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable-pr.yml@c615bb556a9a61495d218c7d439e7c8abbbfb151" # v1.8.3
permissions:
actions: read
contents: read
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
index 99a10164ed7..5cb58c15398 100644
--- a/.github/workflows/scorecard.yml
+++ b/.github/workflows/scorecard.yml
@@ -40,6 +40,6 @@ jobs:
retention-days: 5
- name: "Upload to code-scanning"
- uses: github/codeql-action/upload-sarif@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a # v3.25.15
+ uses: github/codeql-action/upload-sarif@429e1977040da7a23b6822b13c129cd1ba93dbb2 # v3.26.2
with:
sarif_file: results.sarif
diff --git a/api/v1alpha1/accesslogging_types.go b/api/v1alpha1/accesslogging_types.go
index 24272564488..78b78a485d6 100644
--- a/api/v1alpha1/accesslogging_types.go
+++ b/api/v1alpha1/accesslogging_types.go
@@ -123,15 +123,13 @@ const (
// - `x-accesslog-attr` - JSON encoded key/value pairs when a JSON format is used.
//
// +kubebuilder:validation:XValidation:rule="self.type == 'HTTP' || !has(self.http)",message="The http field may only be set when type is HTTP."
+// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)"
+// +kubebuilder:validation:XValidation:message="must have at least one backend in backendRefs",rule="has(self.backendRefs) && self.backendRefs.size() > 0"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Service kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service') : true"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\")) : true"
type ALSEnvoyProxyAccessLog struct {
- // BackendRefs references a Kubernetes object that represents the gRPC service to which
- // the access logs will be sent. Currently only Service is supported.
- //
- // +kubebuilder:validation:MinItems=1
- // +kubebuilder:validation:MaxItems=1
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Service kind.",rule="self.all(f, f.kind == 'Service')"
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')"
- BackendRefs []BackendRef `json:"backendRefs"`
+ BackendCluster `json:",inline"`
+
// LogName defines the friendly name of the access log to be returned in
// StreamAccessLogsMessage.Identifier. This allows the access log server
// to differentiate between different access logs coming from the same Envoy.
@@ -167,7 +165,11 @@ type FileEnvoyProxyAccessLog struct {
// OpenTelemetryEnvoyProxyAccessLog defines the OpenTelemetry access log sink.
//
// +kubebuilder:validation:XValidation:message="host or backendRefs needs to be set",rule="has(self.host) || self.backendRefs.size() > 0"
+// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Service kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service') : true"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\")) : true"
type OpenTelemetryEnvoyProxyAccessLog struct {
+ BackendCluster `json:",inline"`
// Host define the extension service hostname.
// Deprecated: Use BackendRefs instead.
//
@@ -180,15 +182,6 @@ type OpenTelemetryEnvoyProxyAccessLog struct {
// +kubebuilder:validation:Minimum=0
// +kubebuilder:default=4317
Port int32 `json:"port,omitempty"`
- // BackendRefs references a Kubernetes object that represents the
- // backend server to which the access log will be sent.
- // Only Service kind is supported for now.
- //
- // +optional
- // +kubebuilder:validation:MaxItems=1
- // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')"
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')"
- BackendRefs []BackendRef `json:"backendRefs,omitempty"`
// Resources is a set of labels that describe the source of a log entry, including envoy node info.
// It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/).
// +optional
diff --git a/api/v1alpha1/backendtrafficpolicy_types.go b/api/v1alpha1/backendtrafficpolicy_types.go
index 061748bc3cd..9d15ccd6896 100644
--- a/api/v1alpha1/backendtrafficpolicy_types.go
+++ b/api/v1alpha1/backendtrafficpolicy_types.go
@@ -45,14 +45,51 @@ type BackendTrafficPolicy struct {
// BackendTrafficPolicySpec defines the desired state of BackendTrafficPolicy.
type BackendTrafficPolicySpec struct {
PolicyTargetReferences `json:",inline"`
+ ClusterSettings `json:",inline"`
// RateLimit allows the user to limit the number of incoming requests
// to a predefined value based on attributes within the traffic flow.
// +optional
RateLimit *RateLimitSpec `json:"rateLimit,omitempty"`
+ // FaultInjection defines the fault injection policy to be applied. This configuration can be used to
+ // inject delays and abort requests to mimic failure scenarios such as service failures and overloads
+ // +optional
+ FaultInjection *FaultInjection `json:"faultInjection,omitempty"`
+
+ // Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
+ // If not set, retry will be disabled.
+ // +optional
+ Retry *Retry `json:"retry,omitempty"`
+
+ // 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.
+ //
+ // +optional
+ UseClientProtocol *bool `json:"useClientProtocol,omitempty"`
+
+ // The compression config for the http streams.
+ //
+ // +optional
+ // +notImplementedHide
+ Compression []*Compression `json:"compression,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+
+// BackendTrafficPolicyList contains a list of BackendTrafficPolicy resources.
+type BackendTrafficPolicyList struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ListMeta `json:"metadata,omitempty"`
+ Items []BackendTrafficPolicy `json:"items"`
+}
+
+// ClusterSettings provides the various knobs that can be set to control how traffic to a given
+// backend will be configured.
+type ClusterSettings struct {
// LoadBalancer policy to apply when routing traffic from the gateway to
- // the backend endpoints
+ // the backend endpoints. Defaults to `LeastRequest`.
// +optional
LoadBalancer *LoadBalancer `json:"loadBalancer,omitempty"`
@@ -71,44 +108,22 @@ type BackendTrafficPolicySpec struct {
// +optional
HealthCheck *HealthCheck `json:"healthCheck,omitempty"`
- // FaultInjection defines the fault injection policy to be applied. This configuration can be used to
- // inject delays and abort requests to mimic failure scenarios such as service failures and overloads
- // +optional
- FaultInjection *FaultInjection `json:"faultInjection,omitempty"`
-
// Circuit Breaker settings for the upstream connections and requests.
// If not set, circuit breakers will be enabled with the default thresholds
//
// +optional
CircuitBreaker *CircuitBreaker `json:"circuitBreaker,omitempty"`
- // Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
- // If not set, retry will be disabled.
- // +optional
- Retry *Retry `json:"retry,omitempty"`
-
- // 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.
- //
- // +optional
- UseClientProtocol *bool `json:"useClientProtocol,omitempty"`
-
// Timeout settings for the backend connections.
//
// +optional
Timeout *Timeout `json:"timeout,omitempty"`
- // The compression config for the http streams.
- //
- // +optional
- // +notImplementedHide
- Compression []*Compression `json:"compression,omitempty"`
-
// Connection includes backend connection settings.
//
// +optional
Connection *BackendConnection `json:"connection,omitempty"`
+
// DNS includes dns resolution settings.
//
// +optional
@@ -120,15 +135,6 @@ type BackendTrafficPolicySpec struct {
HTTP2 *HTTP2Settings `json:"http2,omitempty"`
}
-// +kubebuilder:object:root=true
-
-// BackendTrafficPolicyList contains a list of BackendTrafficPolicy resources.
-type BackendTrafficPolicyList struct {
- metav1.TypeMeta `json:",inline"`
- metav1.ListMeta `json:"metadata,omitempty"`
- Items []BackendTrafficPolicy `json:"items"`
-}
-
func init() {
SchemeBuilder.Register(&BackendTrafficPolicy{}, &BackendTrafficPolicyList{})
}
diff --git a/api/v1alpha1/clienttrafficpolicy_types.go b/api/v1alpha1/clienttrafficpolicy_types.go
index 347eb946353..63b2c91fb2e 100644
--- a/api/v1alpha1/clienttrafficpolicy_types.go
+++ b/api/v1alpha1/clienttrafficpolicy_types.go
@@ -7,6 +7,7 @@ package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
)
@@ -134,6 +135,12 @@ type HeaderSettings struct {
//
// +optional
PreserveXRequestID *bool `json:"preserveXRequestID,omitempty"`
+
+ // EarlyRequestHeaders defines settings for early request header modification, before envoy performs
+ // routing, tracing and built-in header manipulation.
+ //
+ // +optional
+ EarlyRequestHeaders *gwapiv1.HTTPHeaderFilter `json:"earlyRequestHeaders,omitempty"`
}
// WithUnderscoresAction configures the action to take when an HTTP header with underscores
diff --git a/api/v1alpha1/connection_types.go b/api/v1alpha1/connection_types.go
index ff24c8edd4d..6f27794748b 100644
--- a/api/v1alpha1/connection_types.go
+++ b/api/v1alpha1/connection_types.go
@@ -22,7 +22,8 @@ type ClientConnection struct {
// Note that when the suffix is not provided, the value is interpreted as bytes.
// Default: 32768 bytes.
//
- // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="bufferLimit must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\""
+ // +kubebuilder:validation:XIntOrString
+ // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
// +optional
BufferLimit *resource.Quantity `json:"bufferLimit,omitempty"`
// SocketBufferLimit provides configuration for the maximum buffer size in bytes for each incoming socket.
@@ -30,7 +31,8 @@ type ClientConnection struct {
// For example, 20Mi, 1Gi, 256Ki etc.
// Note that when the suffix is not provided, the value is interpreted as bytes.
//
- // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="socketBufferLimit must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\""
+ // +kubebuilder:validation:XIntOrString
+ // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
// +optional
// +notImplementedHide
SocketBufferLimit *resource.Quantity `json:"socketBufferLimit,omitempty"`
@@ -44,7 +46,8 @@ type BackendConnection struct {
// For example, 20Mi, 1Gi, 256Ki etc.
// Note: that when the suffix is not provided, the value is interpreted as bytes.
//
- // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="BufferLimit must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\""
+ // +kubebuilder:validation:XIntOrString
+ // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
// +optional
BufferLimit *resource.Quantity `json:"bufferLimit,omitempty"`
// SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket
@@ -53,7 +56,8 @@ type BackendConnection struct {
// For example, 20Mi, 1Gi, 256Ki etc.
// Note that when the suffix is not provided, the value is interpreted as bytes.
//
- // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="socketBufferLimit must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\""
+ // +kubebuilder:validation:XIntOrString
+ // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
// +optional
// +notImplementedHide
SocketBufferLimit *resource.Quantity `json:"socketBufferLimit,omitempty"`
diff --git a/api/v1alpha1/envoypatchpolicy_types.go b/api/v1alpha1/envoypatchpolicy_types.go
index 22effb69756..b23002e678f 100644
--- a/api/v1alpha1/envoypatchpolicy_types.go
+++ b/api/v1alpha1/envoypatchpolicy_types.go
@@ -111,7 +111,12 @@ type JSONPatchOperation struct {
Op JSONPatchOperationType `json:"op"`
// Path is the location of the target document/field where the operation will be performed
// Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details.
- Path string `json:"path"`
+ // +optional
+ Path *string `json:"path,omitempty"`
+ // JSONPath specifies the locations of the target document/field where the operation will be performed
+ // Refer to https://datatracker.ietf.org/doc/rfc9535/ for more details.
+ // +optional
+ JSONPath *string `json:"jsonPath,omitempty"`
// From is the source location of the value to be copied or moved. Only valid
// for move or copy operations
// Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details.
diff --git a/api/v1alpha1/envoyproxy_metric_types.go b/api/v1alpha1/envoyproxy_metric_types.go
index 8791ddbd490..0e571ef23c9 100644
--- a/api/v1alpha1/envoyproxy_metric_types.go
+++ b/api/v1alpha1/envoyproxy_metric_types.go
@@ -15,6 +15,7 @@ type ProxyMetrics struct {
// Prometheus defines the configuration for Admin endpoint `/stats/prometheus`.
Prometheus *ProxyPrometheusProvider `json:"prometheus,omitempty"`
// Sinks defines the metric sinks where metrics are sent to.
+ // +kubebuilder:validation:MaxItems=16
Sinks []ProxyMetricSink `json:"sinks,omitempty"`
// Matches defines configuration for selecting specific metrics instead of generating all metrics stats
// that are enabled by default. This helps reduce CPU and memory overhead in Envoy, but eliminating some stats
@@ -54,7 +55,11 @@ type ProxyMetricSink struct {
// ProxyOpenTelemetrySink defines the configuration for OpenTelemetry sink.
//
// +kubebuilder:validation:XValidation:message="host or backendRefs needs to be set",rule="has(self.host) || self.backendRefs.size() > 0"
+// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)"
+// +kubebuilder:validation:XValidation:message="only supports Service kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service') : true"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\")) : true"
type ProxyOpenTelemetrySink struct {
+ BackendCluster `json:",inline"`
// Host define the service hostname.
// Deprecated: Use BackendRefs instead.
//
@@ -68,15 +73,6 @@ type ProxyOpenTelemetrySink struct {
// +kubebuilder:validation:Maximum=65535
// +kubebuilder:default=4317
Port int32 `json:"port,omitempty"`
- // BackendRefs references a Kubernetes object that represents the
- // backend server to which the metric will be sent.
- // Only Service kind is supported for now.
- //
- // +optional
- // +kubebuilder:validation:MaxItems=1
- // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')"
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')"
- BackendRefs []BackendRef `json:"backendRefs,omitempty"`
// TODO: add support for customizing OpenTelemetry sink in https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/stat_sinks/open_telemetry/v3/open_telemetry.proto#envoy-v3-api-msg-extensions-stat-sinks-open-telemetry-v3-sinkconfig
}
diff --git a/api/v1alpha1/envoyproxy_types.go b/api/v1alpha1/envoyproxy_types.go
index 910c6d1503a..e2ada31c3fc 100644
--- a/api/v1alpha1/envoyproxy_types.go
+++ b/api/v1alpha1/envoyproxy_types.go
@@ -112,6 +112,8 @@ type EnvoyProxySpec struct {
//
// - envoy.filters.http.jwt_authn
//
+ // - envoy.filters.http.stateful_session
+ //
// - envoy.filters.http.ext_proc
//
// - envoy.filters.http.wasm
@@ -172,7 +174,7 @@ type FilterPosition struct {
}
// EnvoyFilter defines the type of Envoy HTTP filter.
-// +kubebuilder:validation:Enum=envoy.filters.http.health_check;envoy.filters.http.fault;envoy.filters.http.cors;envoy.filters.http.ext_authz;envoy.filters.http.basic_auth;envoy.filters.http.oauth2;envoy.filters.http.jwt_authn;envoy.filters.http.ext_proc;envoy.filters.http.wasm;envoy.filters.http.rbac;envoy.filters.http.local_ratelimit;envoy.filters.http.ratelimit
+// +kubebuilder:validation:Enum=envoy.filters.http.health_check;envoy.filters.http.fault;envoy.filters.http.cors;envoy.filters.http.ext_authz;envoy.filters.http.basic_auth;envoy.filters.http.oauth2;envoy.filters.http.jwt_authn;envoy.filters.http.stateful_session;envoy.filters.http.ext_proc;envoy.filters.http.wasm;envoy.filters.http.rbac;envoy.filters.http.local_ratelimit;envoy.filters.http.ratelimit
type EnvoyFilter string
const (
@@ -197,6 +199,9 @@ const (
// EnvoyFilterJWTAuthn defines the Envoy HTTP JWT authentication filter.
EnvoyFilterJWTAuthn EnvoyFilter = "envoy.filters.http.jwt_authn"
+ // EnvoyFilterSessionPersistence defines the Envoy HTTP session persistence filter.
+ EnvoyFilterSessionPersistence EnvoyFilter = "envoy.filters.http.stateful_session"
+
// EnvoyFilterExtProc defines the Envoy HTTP external process filter.
EnvoyFilterExtProc EnvoyFilter = "envoy.filters.http.ext_proc"
diff --git a/api/v1alpha1/ext_auth_types.go b/api/v1alpha1/ext_auth_types.go
index 13de5f9f6ac..2ecb8674aad 100644
--- a/api/v1alpha1/ext_auth_types.go
+++ b/api/v1alpha1/ext_auth_types.go
@@ -5,18 +5,10 @@
package v1alpha1
-import (
- gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
-)
-
// ExtAuth defines the configuration for External Authorization.
//
// +kubebuilder:validation:XValidation:rule="(has(self.grpc) || has(self.http))",message="one of grpc or http must be specified"
// +kubebuilder:validation:XValidation:rule="(has(self.grpc) && !has(self.http)) || (!has(self.grpc) && has(self.http))",message="only one of grpc or http can be specified"
-// +kubebuilder:validation:XValidation:rule="has(self.grpc) ? (!has(self.grpc.backendRef) || !has(self.grpc.backendRef.group) || self.grpc.backendRef.group == \"\") : true", message="group is invalid, only the core API group (specified by omitting the group field or setting it to an empty string) is supported"
-// +kubebuilder:validation:XValidation:rule="has(self.grpc) ? (!has(self.grpc.backendRef) || !has(self.grpc.backendRef.kind) || self.grpc.backendRef.kind == 'Service') : true", message="kind is invalid, only Service (specified by omitting the kind field or setting it to 'Service') is supported"
-// +kubebuilder:validation:XValidation:rule="has(self.http) ? (!has(self.http.backendRef) || !has(self.http.backendRef.group) || self.http.backendRef.group == \"\") : true", message="group is invalid, only the core API group (specified by omitting the group field or setting it to an empty string) is supported"
-// +kubebuilder:validation:XValidation:rule="has(self.http) ? (!has(self.http.backendRef) || !has(self.http.backendRef.kind) || self.http.backendRef.kind == 'Service') : true", message="kind is invalid, only Service (specified by omitting the kind field or setting it to 'Service') is supported"
type ExtAuth struct {
// GRPC defines the gRPC External Authorization service.
// Either GRPCService or HTTPService must be specified,
@@ -56,45 +48,25 @@ type ExtAuth struct {
// The authorization request message is defined in
// https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto
// +kubebuilder:validation:XValidation:message="backendRef or backendRefs needs to be set",rule="has(self.backendRef) || self.backendRefs.size() > 0"
+// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)"
+// +kubebuilder:validation:XValidation:message="Exactly one backendRef can be specified in backendRefs.",rule="has(self.backendRefs) && self.backendRefs.size()==1"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Service and Backend kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service' || f.kind == 'Backend') : true"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core and gateway.envoyproxy.io group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\" || f.group == 'gateway.envoyproxy.io')) : true"
type GRPCExtAuthService struct {
- // BackendRef references a Kubernetes object that represents the
- // backend server to which the authorization request will be sent.
- // Only Service kind is supported for now.
- //
- // Deprecated: Use BackendRefs instead.
- BackendRef *gwapiv1.BackendObjectReference `json:"backendRef,omitempty"`
-
- // BackendRefs references a Kubernetes object that represents the
- // backend server to which the authorization request will be sent.
// Only Service kind is supported for now.
- //
- // +optional
- // +kubebuilder:validation:MaxItems=1
- // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')"
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')"
- BackendRefs []BackendRef `json:"backendRefs,omitempty"`
+ BackendCluster `json:",inline"`
}
// HTTPExtAuthService defines the HTTP External Authorization service
//
// +kubebuilder:validation:XValidation:message="backendRef or backendRefs needs to be set",rule="has(self.backendRef) || self.backendRefs.size() > 0"
+// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)"
+// +kubebuilder:validation:XValidation:message="Exactly one backendRef can be specified in backendRefs.",rule="has(self.backendRefs) && self.backendRefs.size()==1"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Service and Backend kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service' || f.kind == 'Backend') : true"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core and gateway.envoyproxy.io group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\" || f.group == 'gateway.envoyproxy.io')) : true"
type HTTPExtAuthService struct {
- // BackendRef references a Kubernetes object that represents the
- // backend server to which the authorization request will be sent.
// Only Service kind is supported for now.
- //
- // Deprecated: Use BackendRefs instead.
- BackendRef *gwapiv1.BackendObjectReference `json:"backendRef,omitempty"`
-
- // BackendRefs references a Kubernetes object that represents the
- // backend server to which the authorization request will be sent.
- // Only Service kind is supported for now.
- //
- // +optional
- // +kubebuilder:validation:MaxItems=1
- // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')"
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')"
- BackendRefs []BackendRef `json:"backendRefs,omitempty"`
+ BackendCluster `json:",inline"`
// Path is the path of the HTTP External Authorization service.
// If path is specified, the authorization request will be sent to that path,
diff --git a/api/v1alpha1/ext_proc_types.go b/api/v1alpha1/ext_proc_types.go
index 27be5e6318d..9f19d92b48f 100644
--- a/api/v1alpha1/ext_proc_types.go
+++ b/api/v1alpha1/ext_proc_types.go
@@ -46,14 +46,12 @@ type ExtProcProcessingMode struct {
}
// ExtProc defines the configuration for External Processing filter.
+// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)"
+// +kubebuilder:validation:XValidation:message="Exactly one backendRef can be specified in backendRefs.",rule="has(self.backendRefs) && self.backendRefs.size()==1"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Service and Backend kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service' || f.kind == 'Backend') : true"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core and gateway.envoyproxy.io group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\" || f.group == 'gateway.envoyproxy.io')) : true"
type ExtProc struct {
- // BackendRefs defines the configuration of the external processing service
- //
- // +kubebuilder:validation:MinItems=1
- // +kubebuilder:validation:MaxItems=1
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Service and Backend kind.",rule="self.all(f, f.kind == 'Service' || f.kind == 'Backend')"
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core and gateway.envoyproxy.io group.",rule="self.all(f, f.group == '' || f.group == 'gateway.envoyproxy.io')"
- BackendRefs []BackendRef `json:"backendRefs"`
+ BackendCluster `json:",inline"`
// MessageTimeout is the timeout for a response to be returned from the external processor
// Default: 200ms
diff --git a/api/v1alpha1/healthcheck_types.go b/api/v1alpha1/healthcheck_types.go
index cea83d2f5a1..990c95f141a 100644
--- a/api/v1alpha1/healthcheck_types.go
+++ b/api/v1alpha1/healthcheck_types.go
@@ -74,6 +74,7 @@ type PassiveHealthCheck struct {
//
// +kubebuilder:validation:XValidation:rule="self.type == 'HTTP' ? has(self.http) : !has(self.http)",message="If Health Checker type is HTTP, http field needs to be set."
// +kubebuilder:validation:XValidation:rule="self.type == 'TCP' ? has(self.tcp) : !has(self.tcp)",message="If Health Checker type is TCP, tcp field needs to be set."
+// +kubebuilder:validation:XValidation:rule="has(self.grpc) ? self.type == 'GRPC' : true", message="The grpc field can only be set if the Health Checker type is GRPC."
type ActiveHealthCheck struct {
// Timeout defines the time to wait for a health check response.
//
@@ -104,7 +105,7 @@ type ActiveHealthCheck struct {
HealthyThreshold *uint32 `json:"healthyThreshold"`
// Type defines the type of health checker.
- // +kubebuilder:validation:Enum=HTTP;TCP
+ // +kubebuilder:validation:Enum=HTTP;TCP;GRPC
// +unionDiscriminator
Type ActiveHealthCheckerType `json:"type" yaml:"type"`
@@ -117,10 +118,15 @@ type ActiveHealthCheck struct {
// It's required while the health checker type is TCP.
// +optional
TCP *TCPActiveHealthChecker `json:"tcp,omitempty" yaml:"tcp,omitempty"`
+
+ // GRPC defines the configuration of the GRPC health checker.
+ // It's optional, and can only be used if the specified type is GRPC.
+ // +optional
+ GRPC *GRPCActiveHealthChecker `json:"grpc,omitempty" yaml:"grpc,omitempty"`
}
// ActiveHealthCheckerType is the type of health checker.
-// +kubebuilder:validation:Enum=HTTP;TCP
+// +kubebuilder:validation:Enum=HTTP;TCP;GRPC
type ActiveHealthCheckerType string
const (
@@ -128,6 +134,8 @@ const (
ActiveHealthCheckerTypeHTTP ActiveHealthCheckerType = "HTTP"
// ActiveHealthCheckerTypeTCP defines the TCP type of health checking.
ActiveHealthCheckerTypeTCP ActiveHealthCheckerType = "TCP"
+ // ActiveHealthCheckerTypeGRPC defines the GRPC type of health checking.
+ ActiveHealthCheckerTypeGRPC ActiveHealthCheckerType = "GRPC"
)
// HTTPActiveHealthChecker defines the settings of http health check.
@@ -159,6 +167,15 @@ type TCPActiveHealthChecker struct {
Receive *ActiveHealthCheckPayload `json:"receive,omitempty" yaml:"receive,omitempty"`
}
+// GRPCActiveHealthChecker defines the settings of the GRPC health check.
+type GRPCActiveHealthChecker struct {
+ // Service to send in the health check request.
+ // If this is not specified, then the health check request applies to the entire
+ // server and not to a specific service.
+ // +optional
+ Service *string `json:"service,omitempty" yaml:"service,omitempty"`
+}
+
// ActiveHealthCheckPayloadType is the type of the payload.
// +kubebuilder:validation:Enum=Text;Binary
type ActiveHealthCheckPayloadType string
diff --git a/api/v1alpha1/shared_types.go b/api/v1alpha1/shared_types.go
index c151fcd8b17..ec29fb5f292 100644
--- a/api/v1alpha1/shared_types.go
+++ b/api/v1alpha1/shared_types.go
@@ -473,6 +473,39 @@ type BackendRef struct {
// BackendObjectReference references a Kubernetes object that represents the backend.
// Only Service kind is supported for now.
gwapiv1.BackendObjectReference `json:",inline"`
+ // Failover This indicates whether the backend is designated as a failover.
+ // Multiple failover backends can be configured.
+ // It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ // when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ // The overprovisioning factor is set to 1.4, meaning the failover backends will only start receiving traffic when
+ // the health of the active backends falls below 72%.
+ // +optional
+ Failover *bool `json:"failover,omitempty"`
+}
+
+// BackendCluster contains all the configuration required for configuring access
+// to a backend. This can include multiple endpoints, and settings that apply for
+// managing the connection to all these endpoints.
+type BackendCluster struct {
+ // BackendRef references a Kubernetes object that represents the
+ // backend server to which the authorization request will be sent.
+ //
+ // Deprecated: Use BackendRefs instead.
+ // +optional
+ BackendRef *gwapiv1.BackendObjectReference `json:"backendRef,omitempty"`
+
+ // BackendRefs references a Kubernetes object that represents the
+ // backend server to which the authorization request will be sent.
+ //
+ // +kubebuilder:validation:MaxItems=16
+ // +optional
+ BackendRefs []BackendRef `json:"backendRefs,omitempty"`
+
+ // BackendSettings holds configuration for managing the connection
+ // to the backend.
+ //
+ // +optional
+ BackendSettings *ClusterSettings `json:"backendSettings,omitempty"`
}
// CIDR defines a CIDR Address range.
@@ -492,14 +525,16 @@ type HTTP2Settings struct {
// InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
// If not set, the default value is 64 KiB(64*1024).
//
- // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="initialStreamWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\""
+ // +kubebuilder:validation:XIntOrString
+ // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
// +optional
InitialStreamWindowSize *resource.Quantity `json:"initialStreamWindowSize,omitempty"`
// InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
// If not set, the default value is 1 MiB.
//
- // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="initialConnectionWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\""
+ // +kubebuilder:validation:XIntOrString
+ // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
// +optional
InitialConnectionWindowSize *resource.Quantity `json:"initialConnectionWindowSize,omitempty"`
diff --git a/api/v1alpha1/tracing_types.go b/api/v1alpha1/tracing_types.go
index b7be478de15..55fd63ef4e9 100644
--- a/api/v1alpha1/tracing_types.go
+++ b/api/v1alpha1/tracing_types.go
@@ -31,7 +31,11 @@ const (
// TracingProvider defines the tracing provider configuration.
//
// +kubebuilder:validation:XValidation:message="host or backendRefs needs to be set",rule="has(self.host) || self.backendRefs.size() > 0"
+// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)"
+// +kubebuilder:validation:XValidation:message="only supports Service kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service') : true"
+// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\")) : true"
type TracingProvider struct {
+ BackendCluster `json:",inline"`
// Type defines the tracing provider type.
// +kubebuilder:validation:Enum=OpenTelemetry;Zipkin
// +kubebuilder:default=OpenTelemetry
@@ -48,15 +52,6 @@ type TracingProvider struct {
// +kubebuilder:validation:Minimum=0
// +kubebuilder:default=4317
Port int32 `json:"port,omitempty"`
- // BackendRefs references a Kubernetes object that represents the
- // backend server to which the trace will be sent.
- // Only Service kind is supported for now.
- //
- // +optional
- // +kubebuilder:validation:MaxItems=1
- // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')"
- // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')"
- BackendRefs []BackendRef `json:"backendRefs,omitempty"`
// Zipkin defines the Zipkin tracing provider configuration
// +optional
Zipkin *ZipkinTracingProvider `json:"zipkin,omitempty"`
diff --git a/api/v1alpha1/validation/envoygateway_validate_test.go b/api/v1alpha1/validation/envoygateway_validate_test.go
index 004a5ac8298..7bc6bbf3b23 100644
--- a/api/v1alpha1/validation/envoygateway_validate_test.go
+++ b/api/v1alpha1/validation/envoygateway_validate_test.go
@@ -662,7 +662,6 @@ func TestValidateEnvoyGateway(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
err := ValidateEnvoyGateway(tc.eg)
if !tc.expect {
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 24e03df70c9..1680d26cca4 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -23,13 +23,7 @@ import (
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ALSEnvoyProxyAccessLog) DeepCopyInto(out *ALSEnvoyProxyAccessLog) {
*out = *in
- if in.BackendRefs != nil {
- in, out := &in.BackendRefs, &out.BackendRefs
- *out = make([]BackendRef, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
+ in.BackendCluster.DeepCopyInto(&out.BackendCluster)
if in.LogName != nil {
in, out := &in.LogName, &out.LogName
*out = new(string)
@@ -115,6 +109,11 @@ func (in *ActiveHealthCheck) DeepCopyInto(out *ActiveHealthCheck) {
*out = new(TCPActiveHealthChecker)
(*in).DeepCopyInto(*out)
}
+ if in.GRPC != nil {
+ in, out := &in.GRPC, &out.GRPC
+ *out = new(GRPCActiveHealthChecker)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ActiveHealthCheck.
@@ -252,6 +251,38 @@ func (in *Backend) DeepCopyObject() runtime.Object {
return nil
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BackendCluster) DeepCopyInto(out *BackendCluster) {
+ *out = *in
+ if in.BackendRef != nil {
+ in, out := &in.BackendRef, &out.BackendRef
+ *out = new(apisv1.BackendObjectReference)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.BackendRefs != nil {
+ in, out := &in.BackendRefs, &out.BackendRefs
+ *out = make([]BackendRef, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.BackendSettings != nil {
+ in, out := &in.BackendSettings, &out.BackendSettings
+ *out = new(ClusterSettings)
+ (*in).DeepCopyInto(*out)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendCluster.
+func (in *BackendCluster) DeepCopy() *BackendCluster {
+ if in == nil {
+ return nil
+ }
+ out := new(BackendCluster)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BackendConnection) DeepCopyInto(out *BackendConnection) {
*out = *in
@@ -343,6 +374,11 @@ func (in *BackendList) DeepCopyObject() runtime.Object {
func (in *BackendRef) DeepCopyInto(out *BackendRef) {
*out = *in
in.BackendObjectReference.DeepCopyInto(&out.BackendObjectReference)
+ if in.Failover != nil {
+ in, out := &in.Failover, &out.Failover
+ *out = new(bool)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendRef.
@@ -488,41 +524,17 @@ func (in *BackendTrafficPolicyList) DeepCopyObject() runtime.Object {
func (in *BackendTrafficPolicySpec) DeepCopyInto(out *BackendTrafficPolicySpec) {
*out = *in
in.PolicyTargetReferences.DeepCopyInto(&out.PolicyTargetReferences)
+ in.ClusterSettings.DeepCopyInto(&out.ClusterSettings)
if in.RateLimit != nil {
in, out := &in.RateLimit, &out.RateLimit
*out = new(RateLimitSpec)
(*in).DeepCopyInto(*out)
}
- if in.LoadBalancer != nil {
- in, out := &in.LoadBalancer, &out.LoadBalancer
- *out = new(LoadBalancer)
- (*in).DeepCopyInto(*out)
- }
- if in.ProxyProtocol != nil {
- in, out := &in.ProxyProtocol, &out.ProxyProtocol
- *out = new(ProxyProtocol)
- **out = **in
- }
- if in.TCPKeepalive != nil {
- in, out := &in.TCPKeepalive, &out.TCPKeepalive
- *out = new(TCPKeepalive)
- (*in).DeepCopyInto(*out)
- }
- if in.HealthCheck != nil {
- in, out := &in.HealthCheck, &out.HealthCheck
- *out = new(HealthCheck)
- (*in).DeepCopyInto(*out)
- }
if in.FaultInjection != nil {
in, out := &in.FaultInjection, &out.FaultInjection
*out = new(FaultInjection)
(*in).DeepCopyInto(*out)
}
- if in.CircuitBreaker != nil {
- in, out := &in.CircuitBreaker, &out.CircuitBreaker
- *out = new(CircuitBreaker)
- (*in).DeepCopyInto(*out)
- }
if in.Retry != nil {
in, out := &in.Retry, &out.Retry
*out = new(Retry)
@@ -533,11 +545,6 @@ func (in *BackendTrafficPolicySpec) DeepCopyInto(out *BackendTrafficPolicySpec)
*out = new(bool)
**out = **in
}
- if in.Timeout != nil {
- in, out := &in.Timeout, &out.Timeout
- *out = new(Timeout)
- (*in).DeepCopyInto(*out)
- }
if in.Compression != nil {
in, out := &in.Compression, &out.Compression
*out = make([]*Compression, len(*in))
@@ -549,21 +556,6 @@ func (in *BackendTrafficPolicySpec) DeepCopyInto(out *BackendTrafficPolicySpec)
}
}
}
- if in.Connection != nil {
- in, out := &in.Connection, &out.Connection
- *out = new(BackendConnection)
- (*in).DeepCopyInto(*out)
- }
- if in.DNS != nil {
- in, out := &in.DNS, &out.DNS
- *out = new(DNS)
- (*in).DeepCopyInto(*out)
- }
- if in.HTTP2 != nil {
- in, out := &in.HTTP2, &out.HTTP2
- *out = new(HTTP2Settings)
- (*in).DeepCopyInto(*out)
- }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendTrafficPolicySpec.
@@ -950,6 +942,66 @@ func (in *ClientValidationContext) DeepCopy() *ClientValidationContext {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ClusterSettings) DeepCopyInto(out *ClusterSettings) {
+ *out = *in
+ if in.LoadBalancer != nil {
+ in, out := &in.LoadBalancer, &out.LoadBalancer
+ *out = new(LoadBalancer)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.ProxyProtocol != nil {
+ in, out := &in.ProxyProtocol, &out.ProxyProtocol
+ *out = new(ProxyProtocol)
+ **out = **in
+ }
+ if in.TCPKeepalive != nil {
+ in, out := &in.TCPKeepalive, &out.TCPKeepalive
+ *out = new(TCPKeepalive)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.HealthCheck != nil {
+ in, out := &in.HealthCheck, &out.HealthCheck
+ *out = new(HealthCheck)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.CircuitBreaker != nil {
+ in, out := &in.CircuitBreaker, &out.CircuitBreaker
+ *out = new(CircuitBreaker)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.Timeout != nil {
+ in, out := &in.Timeout, &out.Timeout
+ *out = new(Timeout)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.Connection != nil {
+ in, out := &in.Connection, &out.Connection
+ *out = new(BackendConnection)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.DNS != nil {
+ in, out := &in.DNS, &out.DNS
+ *out = new(DNS)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.HTTP2 != nil {
+ in, out := &in.HTTP2, &out.HTTP2
+ *out = new(HTTP2Settings)
+ (*in).DeepCopyInto(*out)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSettings.
+func (in *ClusterSettings) DeepCopy() *ClusterSettings {
+ if in == nil {
+ return nil
+ }
+ out := new(ClusterSettings)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Compression) DeepCopyInto(out *Compression) {
*out = *in
@@ -1980,13 +2032,7 @@ func (in *ExtAuth) DeepCopy() *ExtAuth {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ExtProc) DeepCopyInto(out *ExtProc) {
*out = *in
- if in.BackendRefs != nil {
- in, out := &in.BackendRefs, &out.BackendRefs
- *out = make([]BackendRef, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
+ in.BackendCluster.DeepCopyInto(&out.BackendCluster)
if in.MessageTimeout != nil {
in, out := &in.MessageTimeout, &out.MessageTimeout
*out = new(apisv1.Duration)
@@ -2282,20 +2328,29 @@ func (in *FilterPosition) DeepCopy() *FilterPosition {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *GRPCExtAuthService) DeepCopyInto(out *GRPCExtAuthService) {
+func (in *GRPCActiveHealthChecker) DeepCopyInto(out *GRPCActiveHealthChecker) {
*out = *in
- if in.BackendRef != nil {
- in, out := &in.BackendRef, &out.BackendRef
- *out = new(apisv1.BackendObjectReference)
- (*in).DeepCopyInto(*out)
+ if in.Service != nil {
+ in, out := &in.Service, &out.Service
+ *out = new(string)
+ **out = **in
}
- if in.BackendRefs != nil {
- in, out := &in.BackendRefs, &out.BackendRefs
- *out = make([]BackendRef, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCActiveHealthChecker.
+func (in *GRPCActiveHealthChecker) DeepCopy() *GRPCActiveHealthChecker {
+ if in == nil {
+ return nil
}
+ out := new(GRPCActiveHealthChecker)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GRPCExtAuthService) DeepCopyInto(out *GRPCExtAuthService) {
+ *out = *in
+ in.BackendCluster.DeepCopyInto(&out.BackendCluster)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCExtAuthService.
@@ -2533,18 +2588,7 @@ func (in *HTTPClientTimeout) DeepCopy() *HTTPClientTimeout {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HTTPExtAuthService) DeepCopyInto(out *HTTPExtAuthService) {
*out = *in
- if in.BackendRef != nil {
- in, out := &in.BackendRef, &out.BackendRef
- *out = new(apisv1.BackendObjectReference)
- (*in).DeepCopyInto(*out)
- }
- if in.BackendRefs != nil {
- in, out := &in.BackendRefs, &out.BackendRefs
- *out = make([]BackendRef, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
+ in.BackendCluster.DeepCopyInto(&out.BackendCluster)
if in.Path != nil {
in, out := &in.Path, &out.Path
*out = new(string)
@@ -2680,6 +2724,11 @@ func (in *HeaderSettings) DeepCopyInto(out *HeaderSettings) {
*out = new(bool)
**out = **in
}
+ if in.EarlyRequestHeaders != nil {
+ in, out := &in.EarlyRequestHeaders, &out.EarlyRequestHeaders
+ *out = new(apisv1.HTTPHeaderFilter)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeaderSettings.
@@ -2775,6 +2824,16 @@ func (in *ImageWasmCodeSource) DeepCopy() *ImageWasmCodeSource {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JSONPatchOperation) DeepCopyInto(out *JSONPatchOperation) {
*out = *in
+ if in.Path != nil {
+ in, out := &in.Path, &out.Path
+ *out = new(string)
+ **out = **in
+ }
+ if in.JSONPath != nil {
+ in, out := &in.JSONPath, &out.JSONPath
+ *out = new(string)
+ **out = **in
+ }
if in.From != nil {
in, out := &in.From, &out.From
*out = new(string)
@@ -3512,18 +3571,12 @@ func (in *OIDCProvider) DeepCopy() *OIDCProvider {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *OpenTelemetryEnvoyProxyAccessLog) DeepCopyInto(out *OpenTelemetryEnvoyProxyAccessLog) {
*out = *in
+ in.BackendCluster.DeepCopyInto(&out.BackendCluster)
if in.Host != nil {
in, out := &in.Host, &out.Host
*out = new(string)
**out = **in
}
- if in.BackendRefs != nil {
- in, out := &in.BackendRefs, &out.BackendRefs
- *out = make([]BackendRef, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
if in.Resources != nil {
in, out := &in.Resources, &out.Resources
*out = make(map[string]string, len(*in))
@@ -3927,18 +3980,12 @@ func (in *ProxyMetrics) DeepCopy() *ProxyMetrics {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ProxyOpenTelemetrySink) DeepCopyInto(out *ProxyOpenTelemetrySink) {
*out = *in
+ in.BackendCluster.DeepCopyInto(&out.BackendCluster)
if in.Host != nil {
in, out := &in.Host, &out.Host
*out = new(string)
**out = **in
}
- if in.BackendRefs != nil {
- in, out := &in.BackendRefs, &out.BackendRefs
- *out = make([]BackendRef, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyOpenTelemetrySink.
@@ -4820,18 +4867,12 @@ func (in *Timeout) DeepCopy() *Timeout {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TracingProvider) DeepCopyInto(out *TracingProvider) {
*out = *in
+ in.BackendCluster.DeepCopyInto(&out.BackendCluster)
if in.Host != nil {
in, out := &in.Host, &out.Host
*out = new(string)
**out = **in
}
- if in.BackendRefs != nil {
- in, out := &in.BackendRefs, &out.BackendRefs
- *out = make([]BackendRef, len(*in))
- for i := range *in {
- (*in)[i].DeepCopyInto(&(*out)[i])
- }
- }
if in.Zipkin != nil {
in, out := &in.Zipkin, &out.Zipkin
*out = new(ZipkinTracingProvider)
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 d94bd0fa0d3..a23e656788b 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml
@@ -123,6 +123,9 @@ spec:
description: Connection includes backend connection settings.
properties:
bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
anyOf:
- type: integer
- type: string
@@ -132,13 +135,11 @@ spec:
If unspecified, an implementation defined default is applied (32768 bytes).
For example, 20Mi, 1Gi, 256Ki etc.
Note: that when the suffix is not provided, the value is interpreted as bytes.
- pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
- x-kubernetes-validations:
- - message: BufferLimit must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
- rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$")
- : type(self) == int'
socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
anyOf:
- type: integer
- type: string
@@ -148,12 +149,7 @@ spec:
SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
For example, 20Mi, 1Gi, 256Ki etc.
Note that when the suffix is not provided, the value is interpreted as bytes.
- pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
- x-kubernetes-validations:
- - message: socketBufferLimit must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
- rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$")
- : type(self) == int'
type: object
dns:
description: DNS includes dns resolution settings.
@@ -230,6 +226,18 @@ spec:
active:
description: Active health check configuration
properties:
+ grpc:
+ description: |-
+ GRPC defines the configuration of the GRPC health checker.
+ It's optional, and can only be used if the specified type is GRPC.
+ properties:
+ service:
+ description: |-
+ Service to send in the health check request.
+ If this is not specified, then the health check request applies to the entire
+ server and not to a specific service.
+ type: string
+ type: object
healthyThreshold:
default: 1
description: HealthyThreshold defines the number of healthy
@@ -384,9 +392,11 @@ spec:
- enum:
- HTTP
- TCP
+ - GRPC
- enum:
- HTTP
- TCP
+ - GRPC
description: Type defines the type of health checker.
type: string
unhealthyThreshold:
@@ -406,6 +416,9 @@ spec:
- message: If Health Checker type is TCP, tcp field needs to be
set.
rule: 'self.type == ''TCP'' ? has(self.tcp) : !has(self.tcp)'
+ - message: The grpc field can only be set if the Health Checker
+ type is GRPC.
+ rule: 'has(self.grpc) ? self.type == ''GRPC'' : true'
passive:
description: Passive passive check configuration
properties:
@@ -457,31 +470,27 @@ spec:
description: HTTP2 provides HTTP/2 configuration for backend connections.
properties:
initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
anyOf:
- type: integer
- type: string
description: |-
InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
If not set, the default value is 1 MiB.
- pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
- x-kubernetes-validations:
- - message: initialConnectionWindowSize must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
- rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$")
- : type(self) == int'
initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
anyOf:
- type: integer
- type: string
description: |-
InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
If not set, the default value is 64 KiB(64*1024).
- pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
- x-kubernetes-validations:
- - message: initialStreamWindowSize must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
- rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$")
- : type(self) == int'
maxConcurrentStreams:
description: |-
MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
@@ -501,7 +510,7 @@ spec:
loadBalancer:
description: |-
LoadBalancer policy to apply when routing traffic from the gateway to
- the backend endpoints
+ the backend endpoints. Defaults to `LeastRequest`.
properties:
consistentHash:
description: |-
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml
index 43443bf28cc..5483ff78e64 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml
@@ -98,6 +98,9 @@ spec:
description: Connection includes client connection settings.
properties:
bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
anyOf:
- type: integer
- type: string
@@ -107,12 +110,7 @@ spec:
For example, 20Mi, 1Gi, 256Ki etc.
Note that when the suffix is not provided, the value is interpreted as bytes.
Default: 32768 bytes.
- pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
- x-kubernetes-validations:
- - message: bufferLimit must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
- rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$")
- : type(self) == int'
connectionLimit:
description: ConnectionLimit defines limits related to connections
properties:
@@ -133,6 +131,9 @@ spec:
type: integer
type: object
socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
anyOf:
- type: integer
- type: string
@@ -141,12 +142,7 @@ spec:
SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
For example, 20Mi, 1Gi, 256Ki etc.
Note that when the suffix is not provided, the value is interpreted as bytes.
- pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
- x-kubernetes-validations:
- - message: socketBufferLimit must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
- rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$")
- : type(self) == int'
type: object
enableProxyProtocol:
description: |-
@@ -163,6 +159,148 @@ spec:
DisableRateLimitHeaders configures Envoy Proxy to omit the "X-RateLimit-" response headers
when rate limiting is enabled.
type: boolean
+ earlyRequestHeaders:
+ description: |-
+ EarlyRequestHeaders defines settings for early request header modification, before envoy performs
+ routing, tracing and built-in header manipulation.
+ properties:
+ add:
+ description: |-
+ Add adds the given header(s) (name, value) to the request
+ before the action. It appends to any existing values associated
+ with the header name.
+
+
+ Input:
+ GET /foo HTTP/1.1
+ my-header: foo
+
+
+ Config:
+ add:
+ - name: "my-header"
+ value: "bar,baz"
+
+
+ Output:
+ GET /foo HTTP/1.1
+ my-header: foo,bar,baz
+ items:
+ description: HTTPHeader represents an HTTP Header name and
+ value as defined by RFC 7230.
+ properties:
+ name:
+ description: |-
+ Name is the name of the HTTP Header to be matched. Name matching MUST be
+ case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
+
+
+ If multiple entries specify equivalent header names, the first entry with
+ an equivalent name MUST be considered for a match. Subsequent entries
+ with an equivalent header name MUST be ignored. Due to the
+ case-insensitivity of header names, "foo" and "Foo" are considered
+ equivalent.
+ maxLength: 256
+ minLength: 1
+ pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
+ type: string
+ value:
+ description: Value is the value of HTTP Header to be
+ matched.
+ maxLength: 4096
+ minLength: 1
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ maxItems: 16
+ type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
+ remove:
+ description: |-
+ Remove the given header(s) from the HTTP request before the action. The
+ value of Remove is a list of HTTP header names. Note that the header
+ names are case-insensitive (see
+ https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
+
+
+ Input:
+ GET /foo HTTP/1.1
+ my-header1: foo
+ my-header2: bar
+ my-header3: baz
+
+
+ Config:
+ remove: ["my-header1", "my-header3"]
+
+
+ Output:
+ GET /foo HTTP/1.1
+ my-header2: bar
+ items:
+ type: string
+ maxItems: 16
+ type: array
+ x-kubernetes-list-type: set
+ set:
+ description: |-
+ Set overwrites the request with the given header (name, value)
+ before the action.
+
+
+ Input:
+ GET /foo HTTP/1.1
+ my-header: foo
+
+
+ Config:
+ set:
+ - name: "my-header"
+ value: "bar"
+
+
+ Output:
+ GET /foo HTTP/1.1
+ my-header: bar
+ items:
+ description: HTTPHeader represents an HTTP Header name and
+ value as defined by RFC 7230.
+ properties:
+ name:
+ description: |-
+ Name is the name of the HTTP Header to be matched. Name matching MUST be
+ case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
+
+
+ If multiple entries specify equivalent header names, the first entry with
+ an equivalent name MUST be considered for a match. Subsequent entries
+ with an equivalent header name MUST be ignored. Due to the
+ case-insensitivity of header names, "foo" and "Foo" are considered
+ equivalent.
+ maxLength: 256
+ minLength: 1
+ pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
+ type: string
+ value:
+ description: Value is the value of HTTP Header to be
+ matched.
+ maxLength: 4096
+ minLength: 1
+ type: string
+ required:
+ - name
+ - value
+ type: object
+ maxItems: 16
+ type: array
+ x-kubernetes-list-map-keys:
+ - name
+ x-kubernetes-list-type: map
+ type: object
enableEnvoyHeaders:
description: |-
EnableEnvoyHeaders configures Envoy Proxy to add the "X-Envoy-" headers to requests
@@ -283,31 +421,27 @@ spec:
description: HTTP2 provides HTTP/2 configuration on the listener.
properties:
initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
anyOf:
- type: integer
- type: string
description: |-
InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
If not set, the default value is 1 MiB.
- pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
- x-kubernetes-validations:
- - message: initialConnectionWindowSize must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
- rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$")
- : type(self) == int'
initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
anyOf:
- type: integer
- type: string
description: |-
InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
If not set, the default value is 64 KiB(64*1024).
- pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
- x-kubernetes-validations:
- - message: initialStreamWindowSize must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$"
- rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$")
- : type(self) == int'
maxConcurrentStreams:
description: |-
MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml
index 61827ee1205..2778aa85a0b 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml
@@ -54,13 +54,104 @@ spec:
description: ExtProc defines the configuration for External Processing
filter.
properties:
+ backendRef:
+ description: |-
+ BackendRef references a Kubernetes object that represents the
+ backend server to which the authorization request will be sent.
+
+
+ Deprecated: Use BackendRefs instead.
+ properties:
+ group:
+ default: ""
+ description: |-
+ Group is the group of the referent. For example, "gateway.networking.k8s.io".
+ When unspecified or empty string, core API group is inferred.
+ maxLength: 253
+ pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ kind:
+ default: Service
+ description: |-
+ Kind is the Kubernetes resource kind of the referent. For example
+ "Service".
+
+
+ Defaults to "Service" when not specified.
+
+
+ ExternalName services can refer to CNAME DNS records that may live
+ outside of the cluster and as such are difficult to reason about in
+ terms of conformance. They also may not be safe to forward to (see
+ CVE-2021-25740 for more information). Implementations SHOULD NOT
+ support ExternalName Services.
+
+
+ Support: Core (Services with a type other than ExternalName)
+
+
+ Support: Implementation-specific (Services with type ExternalName)
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
+ type: string
+ name:
+ description: Name is the name of the referent.
+ maxLength: 253
+ minLength: 1
+ type: string
+ namespace:
+ description: |-
+ Namespace is the namespace of the backend. When unspecified, the local
+ namespace is inferred.
+
+
+ Note that when a namespace different than the local namespace is specified,
+ a ReferenceGrant object is required in the referent namespace to allow that
+ namespace's owner to accept the reference. See the ReferenceGrant
+ documentation for details.
+
+
+ Support: Core
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+ type: string
+ port:
+ description: |-
+ Port specifies the destination port number to use for this resource.
+ Port is required when the referent is a Kubernetes Service. In this
+ case, the port number is the service port number, not the target port.
+ For other resources, destination port might be derived from the referent
+ resource or this field.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - name
+ type: object
+ x-kubernetes-validations:
+ - message: Must have port for Service reference
+ rule: '(size(self.group) == 0 && self.kind == ''Service'')
+ ? has(self.port) : true'
backendRefs:
- description: BackendRefs defines the configuration of the external
- processing service
+ description: |-
+ BackendRefs references a Kubernetes object that represents the
+ backend server to which the authorization request will be sent.
items:
description: BackendRef defines how an ObjectReference that
is specific to BackendRef.
properties:
+ failover:
+ description: |-
+ Failover This indicates whether the backend is designated as a failover.
+ Multiple failover backends can be configured.
+ It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ The overprovisioning factor is set to 1.4, meaning the failover backends will only start receiving traffic when
+ the health of the active backends falls below 72%.
+ type: boolean
group:
default: ""
description: |-
@@ -134,15 +225,605 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind == ''Service'')
? has(self.port) : true'
- maxItems: 1
- minItems: 1
+ maxItems: 16
type: array
- x-kubernetes-validations:
- - message: BackendRefs only supports Service and Backend kind.
- rule: self.all(f, f.kind == 'Service' || f.kind == 'Backend')
- - message: BackendRefs only supports Core and gateway.envoyproxy.io
- group.
- rule: self.all(f, f.group == '' || f.group == 'gateway.envoyproxy.io')
+ backendSettings:
+ description: |-
+ BackendSettings holds configuration for managing the connection
+ to the backend.
+ properties:
+ circuitBreaker:
+ description: |-
+ Circuit Breaker settings for the upstream connections and requests.
+ If not set, circuit breakers will be enabled with the default thresholds
+ properties:
+ maxConnections:
+ default: 1024
+ description: The maximum number of connections that
+ Envoy will establish to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRequests:
+ default: 1024
+ description: The maximum number of parallel requests
+ that Envoy will make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRetries:
+ default: 1024
+ description: The maximum number of parallel retries
+ that Envoy will make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxPendingRequests:
+ default: 1024
+ description: The maximum number of pending requests
+ that Envoy will queue to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxRequestsPerConnection:
+ description: |-
+ The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
+ Default: unlimited.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ type: object
+ connection:
+ description: Connection includes backend connection settings.
+ properties:
+ bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
+ BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
+ If unspecified, an implementation defined default is applied (32768 bytes).
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note: that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket
+ to backend.
+ SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ type: object
+ dns:
+ description: DNS includes dns resolution settings.
+ properties:
+ dnsRefreshRate:
+ description: |-
+ DNSRefreshRate specifies the rate at which DNS records should be refreshed.
+ Defaults to 30 seconds.
+ type: string
+ respectDnsTtl:
+ description: |-
+ RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
+ If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
+ Defaults to true.
+ type: boolean
+ type: object
+ healthCheck:
+ description: HealthCheck allows gateway to perform active
+ health checking on backends.
+ properties:
+ active:
+ description: Active health check configuration
+ properties:
+ grpc:
+ description: |-
+ GRPC defines the configuration of the GRPC health checker.
+ It's optional, and can only be used if the specified type is GRPC.
+ properties:
+ service:
+ description: |-
+ Service to send in the health check request.
+ If this is not specified, then the health check request applies to the entire
+ server and not to a specific service.
+ type: string
+ type: object
+ healthyThreshold:
+ default: 1
+ description: HealthyThreshold defines the number
+ of healthy health checks required before a backend
+ host is marked healthy.
+ format: int32
+ minimum: 1
+ type: integer
+ http:
+ description: |-
+ HTTP defines the configuration of http health checker.
+ It's required while the health checker type is HTTP.
+ properties:
+ expectedResponse:
+ description: ExpectedResponse defines a list
+ of HTTP expected responses to match.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of the
+ payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ expectedStatuses:
+ description: |-
+ ExpectedStatuses defines a list of HTTP response statuses considered healthy.
+ Defaults to 200 only
+ items:
+ description: HTTPStatus defines the http status
+ code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ method:
+ description: |-
+ Method defines the HTTP method used for health checking.
+ Defaults to GET
+ type: string
+ path:
+ description: Path defines the HTTP path that
+ will be requested during health checking.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - path
+ type: object
+ interval:
+ default: 3s
+ description: Interval defines the time between active
+ health checks.
+ format: duration
+ type: string
+ tcp:
+ description: |-
+ TCP defines the configuration of tcp health checker.
+ It's required while the health checker type is TCP.
+ properties:
+ receive:
+ description: Receive defines the expected response
+ payload.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of the
+ payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ send:
+ description: Send defines the request payload.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of the
+ payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ type: object
+ timeout:
+ default: 1s
+ description: Timeout defines the time to wait for
+ a health check response.
+ format: duration
+ type: string
+ type:
+ allOf:
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ description: Type defines the type of health checker.
+ type: string
+ unhealthyThreshold:
+ default: 3
+ description: UnhealthyThreshold defines the number
+ of unhealthy health checks required before a backend
+ host is marked unhealthy.
+ format: int32
+ minimum: 1
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If Health Checker type is HTTP, http field
+ needs to be set.
+ rule: 'self.type == ''HTTP'' ? has(self.http) : !has(self.http)'
+ - message: If Health Checker type is TCP, tcp field
+ needs to be set.
+ rule: 'self.type == ''TCP'' ? has(self.tcp) : !has(self.tcp)'
+ - message: The grpc field can only be set if the Health
+ Checker type is GRPC.
+ rule: 'has(self.grpc) ? self.type == ''GRPC'' : true'
+ passive:
+ description: Passive passive check configuration
+ properties:
+ baseEjectionTime:
+ default: 30s
+ description: BaseEjectionTime defines the base duration
+ for which a host will be ejected on consecutive
+ failures.
+ format: duration
+ type: string
+ consecutive5XxErrors:
+ default: 5
+ description: Consecutive5xxErrors sets the number
+ of consecutive 5xx errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveGatewayErrors:
+ default: 0
+ description: ConsecutiveGatewayErrors sets the number
+ of consecutive gateway errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveLocalOriginFailures:
+ default: 5
+ description: |-
+ ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection.
+ Parameter takes effect only when split_external_local_origin_errors is set to true.
+ format: int32
+ type: integer
+ interval:
+ default: 3s
+ description: Interval defines the time between passive
+ health checks.
+ format: duration
+ type: string
+ maxEjectionPercent:
+ default: 10
+ description: MaxEjectionPercent sets the maximum
+ percentage of hosts in a cluster that can be ejected.
+ format: int32
+ type: integer
+ splitExternalLocalOriginErrors:
+ default: false
+ description: SplitExternalLocalOriginErrors enables
+ splitting of errors between external and local
+ origin.
+ type: boolean
+ type: object
+ type: object
+ http2:
+ description: HTTP2 provides HTTP/2 configuration for backend
+ connections.
+ properties:
+ initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
+ If not set, the default value is 1 MiB.
+ x-kubernetes-int-or-string: true
+ initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
+ If not set, the default value is 64 KiB(64*1024).
+ x-kubernetes-int-or-string: true
+ maxConcurrentStreams:
+ description: |-
+ MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
+ If not set, the default value is 100.
+ format: int32
+ maximum: 2147483647
+ minimum: 1
+ type: integer
+ onInvalidMessage:
+ description: |-
+ OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
+ It's recommended for L2 Envoy deployments to set this value to TerminateStream.
+ https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
+ Default: TerminateConnection
+ type: string
+ type: object
+ loadBalancer:
+ description: |-
+ LoadBalancer policy to apply when routing traffic from the gateway to
+ the backend endpoints. Defaults to `LeastRequest`.
+ properties:
+ consistentHash:
+ description: |-
+ ConsistentHash defines the configuration when the load balancer type is
+ set to ConsistentHash
+ properties:
+ cookie:
+ description: Cookie configures the cookie hash policy
+ when the consistent hash type is set to Cookie.
+ properties:
+ attributes:
+ additionalProperties:
+ type: string
+ description: Additional Attributes to set for
+ the generated cookie.
+ type: object
+ name:
+ description: |-
+ Name of the cookie to hash.
+ If this cookie does not exist in the request, Envoy will generate a cookie and set
+ the TTL on the response back to the client based on Layer 4
+ attributes of the backend endpoint, to ensure that these future requests
+ go to the same backend endpoint. Make sure to set the TTL field for this case.
+ type: string
+ ttl:
+ description: |-
+ TTL of the generated cookie if the cookie is not present. This value sets the
+ Max-Age attribute value.
+ type: string
+ required:
+ - name
+ type: object
+ header:
+ description: Header configures the header hash policy
+ when the consistent hash type is set to Header.
+ properties:
+ name:
+ description: Name of the header to hash.
+ type: string
+ required:
+ - name
+ type: object
+ tableSize:
+ default: 65537
+ description: The table size for consistent hashing,
+ must be prime number limited to 5000011.
+ format: int64
+ maximum: 5000011
+ minimum: 2
+ type: integer
+ type:
+ description: |-
+ ConsistentHashType defines the type of input to hash on. Valid Type values are
+ "SourceIP",
+ "Header",
+ "Cookie".
+ enum:
+ - SourceIP
+ - Header
+ - Cookie
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If consistent hash type is header, the header
+ field must be set.
+ rule: 'self.type == ''Header'' ? has(self.header)
+ : !has(self.header)'
+ - message: If consistent hash type is cookie, the cookie
+ field must be set.
+ rule: 'self.type == ''Cookie'' ? has(self.cookie)
+ : !has(self.cookie)'
+ slowStart:
+ description: |-
+ SlowStart defines the configuration related to the slow start load balancer policy.
+ If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently this is only supported for RoundRobin and LeastRequest load balancers
+ properties:
+ window:
+ description: |-
+ Window defines the duration of the warm up period for newly added host.
+ During slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently only supports linear growth of traffic. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig
+ type: string
+ required:
+ - window
+ type: object
+ type:
+ description: |-
+ Type decides the type of Load Balancer policy.
+ Valid LoadBalancerType values are
+ "ConsistentHash",
+ "LeastRequest",
+ "Random",
+ "RoundRobin".
+ enum:
+ - ConsistentHash
+ - LeastRequest
+ - Random
+ - RoundRobin
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If LoadBalancer type is consistentHash, consistentHash
+ field needs to be set.
+ rule: 'self.type == ''ConsistentHash'' ? has(self.consistentHash)
+ : !has(self.consistentHash)'
+ - message: Currently SlowStart is only supported for RoundRobin
+ and LeastRequest load balancers.
+ rule: 'self.type in [''Random'', ''ConsistentHash''] ?
+ !has(self.slowStart) : true '
+ proxyProtocol:
+ description: ProxyProtocol enables the Proxy Protocol when
+ communicating with the backend.
+ properties:
+ version:
+ description: |-
+ Version of ProxyProtol
+ Valid ProxyProtocolVersion values are
+ "V1"
+ "V2"
+ enum:
+ - V1
+ - V2
+ type: string
+ required:
+ - version
+ type: object
+ tcpKeepalive:
+ description: |-
+ TcpKeepalive settings associated with the upstream client connection.
+ Disabled by default.
+ properties:
+ idleTime:
+ description: |-
+ The duration a connection needs to be idle before keep-alive
+ probes start being sent.
+ The duration format is
+ Defaults to `7200s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ interval:
+ description: |-
+ The duration between keep-alive probes.
+ Defaults to `75s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ probes:
+ description: |-
+ The total number of unacknowledged probes to send before deciding
+ the connection is dead.
+ Defaults to 9.
+ format: int32
+ type: integer
+ type: object
+ timeout:
+ description: Timeout settings for the backend connections.
+ properties:
+ http:
+ description: Timeout settings for HTTP.
+ properties:
+ connectionIdleTimeout:
+ description: |-
+ The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
+ Default: 1 hour.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ maxConnectionDuration:
+ description: |-
+ The maximum duration of an HTTP connection.
+ Default: unlimited.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ tcp:
+ description: Timeout settings for TCP.
+ properties:
+ connectTimeout:
+ description: |-
+ The timeout for network connection establishment, including TCP and TLS handshakes.
+ Default: 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ type: object
+ type: object
failOpen:
description: |-
FailOpen defines if requests or responses that cannot be processed due to connectivity to the
@@ -187,9 +868,19 @@ spec:
type: string
type: object
type: object
- required:
- - backendRefs
type: object
+ x-kubernetes-validations:
+ - message: BackendRefs must be used, backendRef is not supported.
+ rule: '!has(self.backendRef)'
+ - message: Exactly one backendRef can be specified in backendRefs.
+ rule: has(self.backendRefs) && self.backendRefs.size()==1
+ - message: BackendRefs only supports Service and Backend kind.
+ rule: 'has(self.backendRefs) ? self.backendRefs.all(f, f.kind
+ == ''Service'' || f.kind == ''Backend'') : true'
+ - message: BackendRefs only supports Core and gateway.envoyproxy.io
+ group.
+ rule: 'has(self.backendRefs) ? (self.backendRefs.all(f, f.group
+ == "" || f.group == ''gateway.envoyproxy.io'')) : true'
maxItems: 16
type: array
targetRef:
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml
index e385b0d4bb0..f57a644066f 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoypatchpolicies.yaml
@@ -71,6 +71,11 @@ spec:
for move or copy operations
Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details.
type: string
+ jsonPath:
+ description: |-
+ JSONPath specifies the locations of the target document/field where the operation will be performed
+ Refer to https://datatracker.ietf.org/doc/rfc9535/ for more details.
+ type: string
op:
description: Op is the type of operation to perform
enum:
@@ -93,7 +98,6 @@ spec:
x-kubernetes-preserve-unknown-fields: true
required:
- op
- - path
type: object
type:
description: Type is the typed URL of the Envoy xDS Resource
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
index 74438fea24c..82865b93d50 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
@@ -251,6 +251,9 @@ spec:
- envoy.filters.http.jwt_authn
+ - envoy.filters.http.stateful_session
+
+
- envoy.filters.http.ext_proc
@@ -286,6 +289,7 @@ spec:
- envoy.filters.http.basic_auth
- envoy.filters.http.oauth2
- envoy.filters.http.jwt_authn
+ - envoy.filters.http.stateful_session
- envoy.filters.http.ext_proc
- envoy.filters.http.wasm
- envoy.filters.http.rbac
@@ -304,6 +308,7 @@ spec:
- envoy.filters.http.basic_auth
- envoy.filters.http.oauth2
- envoy.filters.http.jwt_authn
+ - envoy.filters.http.stateful_session
- envoy.filters.http.ext_proc
- envoy.filters.http.wasm
- envoy.filters.http.rbac
@@ -320,6 +325,7 @@ spec:
- envoy.filters.http.basic_auth
- envoy.filters.http.oauth2
- envoy.filters.http.jwt_authn
+ - envoy.filters.http.stateful_session
- envoy.filters.http.ext_proc
- envoy.filters.http.wasm
- envoy.filters.http.rbac
@@ -10303,14 +10309,104 @@ spec:
description: ALS defines the gRPC Access Log Service
(ALS) sink.
properties:
+ backendRef:
+ description: |-
+ BackendRef references a Kubernetes object that represents the
+ backend server to which the authorization request will be sent.
+
+
+ Deprecated: Use BackendRefs instead.
+ properties:
+ group:
+ default: ""
+ description: |-
+ Group is the group of the referent. For example, "gateway.networking.k8s.io".
+ When unspecified or empty string, core API group is inferred.
+ maxLength: 253
+ pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ kind:
+ default: Service
+ description: |-
+ Kind is the Kubernetes resource kind of the referent. For example
+ "Service".
+
+
+ Defaults to "Service" when not specified.
+
+
+ ExternalName services can refer to CNAME DNS records that may live
+ outside of the cluster and as such are difficult to reason about in
+ terms of conformance. They also may not be safe to forward to (see
+ CVE-2021-25740 for more information). Implementations SHOULD NOT
+ support ExternalName Services.
+
+
+ Support: Core (Services with a type other than ExternalName)
+
+
+ Support: Implementation-specific (Services with type ExternalName)
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
+ type: string
+ name:
+ description: Name is the name of the referent.
+ maxLength: 253
+ minLength: 1
+ type: string
+ namespace:
+ description: |-
+ Namespace is the namespace of the backend. When unspecified, the local
+ namespace is inferred.
+
+
+ Note that when a namespace different than the local namespace is specified,
+ a ReferenceGrant object is required in the referent namespace to allow that
+ namespace's owner to accept the reference. See the ReferenceGrant
+ documentation for details.
+
+
+ Support: Core
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+ type: string
+ port:
+ description: |-
+ Port specifies the destination port number to use for this resource.
+ Port is required when the referent is a Kubernetes Service. In this
+ case, the port number is the service port number, not the target port.
+ For other resources, destination port might be derived from the referent
+ resource or this field.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - name
+ type: object
+ x-kubernetes-validations:
+ - message: Must have port for Service reference
+ rule: '(size(self.group) == 0 && self.kind
+ == ''Service'') ? has(self.port) : true'
backendRefs:
description: |-
- BackendRefs references a Kubernetes object that represents the gRPC service to which
- the access logs will be sent. Currently only Service is supported.
+ BackendRefs references a Kubernetes object that represents the
+ backend server to which the authorization request will be sent.
items:
description: BackendRef defines how an ObjectReference
that is specific to BackendRef.
properties:
+ failover:
+ description: |-
+ Failover This indicates whether the backend is designated as a failover.
+ Multiple failover backends can be configured.
+ It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ The overprovisioning factor is set to 1.4, meaning the failover backends will only start receiving traffic when
+ the health of the active backends falls below 72%.
+ type: boolean
group:
default: ""
description: |-
@@ -10385,16 +10481,661 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind
== ''Service'') ? has(self.port) : true'
- maxItems: 1
- minItems: 1
+ maxItems: 16
type: array
- x-kubernetes-validations:
- - message: BackendRefs only supports Service
- kind.
- rule: self.all(f, f.kind == 'Service')
- - message: BackendRefs only supports Core
- group.
- rule: self.all(f, f.group == '')
+ backendSettings:
+ description: |-
+ BackendSettings holds configuration for managing the connection
+ to the backend.
+ properties:
+ circuitBreaker:
+ description: |-
+ Circuit Breaker settings for the upstream connections and requests.
+ If not set, circuit breakers will be enabled with the default thresholds
+ properties:
+ maxConnections:
+ default: 1024
+ description: The maximum number of
+ connections that Envoy will establish
+ to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRequests:
+ default: 1024
+ description: The maximum number of
+ parallel requests that Envoy will
+ make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRetries:
+ default: 1024
+ description: The maximum number of
+ parallel retries that Envoy will
+ make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxPendingRequests:
+ default: 1024
+ description: The maximum number of
+ pending requests that Envoy will
+ queue to the referenced backend
+ defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxRequestsPerConnection:
+ description: |-
+ The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
+ Default: unlimited.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ type: object
+ connection:
+ description: Connection includes backend
+ connection settings.
+ properties:
+ bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
+ BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
+ If unspecified, an implementation defined default is applied (32768 bytes).
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note: that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket
+ to backend.
+ SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ type: object
+ dns:
+ description: DNS includes dns resolution
+ settings.
+ properties:
+ dnsRefreshRate:
+ description: |-
+ DNSRefreshRate specifies the rate at which DNS records should be refreshed.
+ Defaults to 30 seconds.
+ type: string
+ respectDnsTtl:
+ description: |-
+ RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
+ If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
+ Defaults to true.
+ type: boolean
+ type: object
+ healthCheck:
+ description: HealthCheck allows gateway
+ to perform active health checking on
+ backends.
+ properties:
+ active:
+ description: Active health check configuration
+ properties:
+ grpc:
+ description: |-
+ GRPC defines the configuration of the GRPC health checker.
+ It's optional, and can only be used if the specified type is GRPC.
+ properties:
+ service:
+ description: |-
+ Service to send in the health check request.
+ If this is not specified, then the health check request applies to the entire
+ server and not to a specific service.
+ type: string
+ type: object
+ healthyThreshold:
+ default: 1
+ description: HealthyThreshold
+ defines the number of healthy
+ health checks required before
+ a backend host is marked healthy.
+ format: int32
+ minimum: 1
+ type: integer
+ http:
+ description: |-
+ HTTP defines the configuration of http health checker.
+ It's required while the health checker type is HTTP.
+ properties:
+ expectedResponse:
+ description: ExpectedResponse
+ defines a list of HTTP expected
+ responses to match.
+ properties:
+ binary:
+ description: Binary payload
+ base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload
+ in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines
+ the type of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type
+ is Text, text field needs
+ to be set.
+ rule: 'self.type == ''Text''
+ ? has(self.text) : !has(self.text)'
+ - message: If payload type
+ is Binary, binary field
+ needs to be set.
+ rule: 'self.type == ''Binary''
+ ? has(self.binary) : !has(self.binary)'
+ expectedStatuses:
+ description: |-
+ ExpectedStatuses defines a list of HTTP response statuses considered healthy.
+ Defaults to 200 only
+ items:
+ description: HTTPStatus
+ defines the http status
+ code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ method:
+ description: |-
+ Method defines the HTTP method used for health checking.
+ Defaults to GET
+ type: string
+ path:
+ description: Path defines
+ the HTTP path that will
+ be requested during health
+ checking.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - path
+ type: object
+ interval:
+ default: 3s
+ description: Interval defines
+ the time between active health
+ checks.
+ format: duration
+ type: string
+ tcp:
+ description: |-
+ TCP defines the configuration of tcp health checker.
+ It's required while the health checker type is TCP.
+ properties:
+ receive:
+ description: Receive defines
+ the expected response payload.
+ properties:
+ binary:
+ description: Binary payload
+ base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload
+ in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines
+ the type of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type
+ is Text, text field needs
+ to be set.
+ rule: 'self.type == ''Text''
+ ? has(self.text) : !has(self.text)'
+ - message: If payload type
+ is Binary, binary field
+ needs to be set.
+ rule: 'self.type == ''Binary''
+ ? has(self.binary) : !has(self.binary)'
+ send:
+ description: Send defines
+ the request payload.
+ properties:
+ binary:
+ description: Binary payload
+ base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload
+ in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines
+ the type of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type
+ is Text, text field needs
+ to be set.
+ rule: 'self.type == ''Text''
+ ? has(self.text) : !has(self.text)'
+ - message: If payload type
+ is Binary, binary field
+ needs to be set.
+ rule: 'self.type == ''Binary''
+ ? has(self.binary) : !has(self.binary)'
+ type: object
+ timeout:
+ default: 1s
+ description: Timeout defines the
+ time to wait for a health check
+ response.
+ format: duration
+ type: string
+ type:
+ allOf:
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ description: Type defines the
+ type of health checker.
+ type: string
+ unhealthyThreshold:
+ default: 3
+ description: UnhealthyThreshold
+ defines the number of unhealthy
+ health checks required before
+ a backend host is marked unhealthy.
+ format: int32
+ minimum: 1
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If Health Checker type
+ is HTTP, http field needs to be
+ set.
+ rule: 'self.type == ''HTTP'' ? has(self.http)
+ : !has(self.http)'
+ - message: If Health Checker type
+ is TCP, tcp field needs to be
+ set.
+ rule: 'self.type == ''TCP'' ? has(self.tcp)
+ : !has(self.tcp)'
+ - message: The grpc field can only
+ be set if the Health Checker type
+ is GRPC.
+ rule: 'has(self.grpc) ? self.type
+ == ''GRPC'' : true'
+ passive:
+ description: Passive passive check
+ configuration
+ properties:
+ baseEjectionTime:
+ default: 30s
+ description: BaseEjectionTime
+ defines the base duration for
+ which a host will be ejected
+ on consecutive failures.
+ format: duration
+ type: string
+ consecutive5XxErrors:
+ default: 5
+ description: Consecutive5xxErrors
+ sets the number of consecutive
+ 5xx errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveGatewayErrors:
+ default: 0
+ description: ConsecutiveGatewayErrors
+ sets the number of consecutive
+ gateway errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveLocalOriginFailures:
+ default: 5
+ description: |-
+ ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection.
+ Parameter takes effect only when split_external_local_origin_errors is set to true.
+ format: int32
+ type: integer
+ interval:
+ default: 3s
+ description: Interval defines
+ the time between passive health
+ checks.
+ format: duration
+ type: string
+ maxEjectionPercent:
+ default: 10
+ description: MaxEjectionPercent
+ sets the maximum percentage
+ of hosts in a cluster that can
+ be ejected.
+ format: int32
+ type: integer
+ splitExternalLocalOriginErrors:
+ default: false
+ description: SplitExternalLocalOriginErrors
+ enables splitting of errors
+ between external and local origin.
+ type: boolean
+ type: object
+ type: object
+ http2:
+ description: HTTP2 provides HTTP/2 configuration
+ for backend connections.
+ properties:
+ initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
+ If not set, the default value is 1 MiB.
+ x-kubernetes-int-or-string: true
+ initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
+ If not set, the default value is 64 KiB(64*1024).
+ x-kubernetes-int-or-string: true
+ maxConcurrentStreams:
+ description: |-
+ MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
+ If not set, the default value is 100.
+ format: int32
+ maximum: 2147483647
+ minimum: 1
+ type: integer
+ onInvalidMessage:
+ description: |-
+ OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
+ It's recommended for L2 Envoy deployments to set this value to TerminateStream.
+ https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
+ Default: TerminateConnection
+ type: string
+ type: object
+ loadBalancer:
+ description: |-
+ LoadBalancer policy to apply when routing traffic from the gateway to
+ the backend endpoints. Defaults to `LeastRequest`.
+ properties:
+ consistentHash:
+ description: |-
+ ConsistentHash defines the configuration when the load balancer type is
+ set to ConsistentHash
+ properties:
+ cookie:
+ description: Cookie configures
+ the cookie hash policy when
+ the consistent hash type is
+ set to Cookie.
+ properties:
+ attributes:
+ additionalProperties:
+ type: string
+ description: Additional Attributes
+ to set for the generated
+ cookie.
+ type: object
+ name:
+ description: |-
+ Name of the cookie to hash.
+ If this cookie does not exist in the request, Envoy will generate a cookie and set
+ the TTL on the response back to the client based on Layer 4
+ attributes of the backend endpoint, to ensure that these future requests
+ go to the same backend endpoint. Make sure to set the TTL field for this case.
+ type: string
+ ttl:
+ description: |-
+ TTL of the generated cookie if the cookie is not present. This value sets the
+ Max-Age attribute value.
+ type: string
+ required:
+ - name
+ type: object
+ header:
+ description: Header configures
+ the header hash policy when
+ the consistent hash type is
+ set to Header.
+ properties:
+ name:
+ description: Name of the header
+ to hash.
+ type: string
+ required:
+ - name
+ type: object
+ tableSize:
+ default: 65537
+ description: The table size for
+ consistent hashing, must be
+ prime number limited to 5000011.
+ format: int64
+ maximum: 5000011
+ minimum: 2
+ type: integer
+ type:
+ description: |-
+ ConsistentHashType defines the type of input to hash on. Valid Type values are
+ "SourceIP",
+ "Header",
+ "Cookie".
+ enum:
+ - SourceIP
+ - Header
+ - Cookie
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If consistent hash type
+ is header, the header field must
+ be set.
+ rule: 'self.type == ''Header'' ?
+ has(self.header) : !has(self.header)'
+ - message: If consistent hash type
+ is cookie, the cookie field must
+ be set.
+ rule: 'self.type == ''Cookie'' ?
+ has(self.cookie) : !has(self.cookie)'
+ slowStart:
+ description: |-
+ SlowStart defines the configuration related to the slow start load balancer policy.
+ If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently this is only supported for RoundRobin and LeastRequest load balancers
+ properties:
+ window:
+ description: |-
+ Window defines the duration of the warm up period for newly added host.
+ During slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently only supports linear growth of traffic. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig
+ type: string
+ required:
+ - window
+ type: object
+ type:
+ description: |-
+ Type decides the type of Load Balancer policy.
+ Valid LoadBalancerType values are
+ "ConsistentHash",
+ "LeastRequest",
+ "Random",
+ "RoundRobin".
+ enum:
+ - ConsistentHash
+ - LeastRequest
+ - Random
+ - RoundRobin
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If LoadBalancer type is consistentHash,
+ consistentHash field needs to be set.
+ rule: 'self.type == ''ConsistentHash''
+ ? has(self.consistentHash) : !has(self.consistentHash)'
+ - message: Currently SlowStart is only
+ supported for RoundRobin and LeastRequest
+ load balancers.
+ rule: 'self.type in [''Random'', ''ConsistentHash'']
+ ? !has(self.slowStart) : true '
+ proxyProtocol:
+ description: ProxyProtocol enables the
+ Proxy Protocol when communicating with
+ the backend.
+ properties:
+ version:
+ description: |-
+ Version of ProxyProtol
+ Valid ProxyProtocolVersion values are
+ "V1"
+ "V2"
+ enum:
+ - V1
+ - V2
+ type: string
+ required:
+ - version
+ type: object
+ tcpKeepalive:
+ description: |-
+ TcpKeepalive settings associated with the upstream client connection.
+ Disabled by default.
+ properties:
+ idleTime:
+ description: |-
+ The duration a connection needs to be idle before keep-alive
+ probes start being sent.
+ The duration format is
+ Defaults to `7200s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ interval:
+ description: |-
+ The duration between keep-alive probes.
+ Defaults to `75s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ probes:
+ description: |-
+ The total number of unacknowledged probes to send before deciding
+ the connection is dead.
+ Defaults to 9.
+ format: int32
+ type: integer
+ type: object
+ timeout:
+ description: Timeout settings for the
+ backend connections.
+ properties:
+ http:
+ description: Timeout settings for
+ HTTP.
+ properties:
+ connectionIdleTimeout:
+ description: |-
+ The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
+ Default: 1 hour.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ maxConnectionDuration:
+ description: |-
+ The maximum duration of an HTTP connection.
+ Default: unlimited.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ tcp:
+ description: Timeout settings for
+ TCP.
+ properties:
+ connectTimeout:
+ description: |-
+ The timeout for network connection establishment, including TCP and TLS handshakes.
+ Default: 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ type: object
+ type: object
http:
description: HTTP defines additional configuration
specific to HTTP access logs.
@@ -10436,13 +11177,24 @@ spec:
- TCP
type: string
required:
- - backendRefs
- type
type: object
x-kubernetes-validations:
- message: The http field may only be set when
type is HTTP.
rule: self.type == 'HTTP' || !has(self.http)
+ - message: BackendRefs must be used, backendRef
+ is not supported.
+ rule: '!has(self.backendRef)'
+ - message: must have at least one backend in backendRefs
+ rule: has(self.backendRefs) && self.backendRefs.size()
+ > 0
+ - message: BackendRefs only supports Service kind.
+ rule: 'has(self.backendRefs) ? self.backendRefs.all(f,
+ f.kind == ''Service'') : true'
+ - message: BackendRefs only supports Core group.
+ rule: 'has(self.backendRefs) ? (self.backendRefs.all(f,
+ f.group == "")) : true'
file:
description: File defines the file accesslog sink.
properties:
@@ -10456,15 +11208,104 @@ spec:
description: OpenTelemetry defines the OpenTelemetry
accesslog sink.
properties:
+ backendRef:
+ description: |-
+ BackendRef references a Kubernetes object that represents the
+ backend server to which the authorization request will be sent.
+
+
+ Deprecated: Use BackendRefs instead.
+ properties:
+ group:
+ default: ""
+ description: |-
+ Group is the group of the referent. For example, "gateway.networking.k8s.io".
+ When unspecified or empty string, core API group is inferred.
+ maxLength: 253
+ pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ kind:
+ default: Service
+ description: |-
+ Kind is the Kubernetes resource kind of the referent. For example
+ "Service".
+
+
+ Defaults to "Service" when not specified.
+
+
+ ExternalName services can refer to CNAME DNS records that may live
+ outside of the cluster and as such are difficult to reason about in
+ terms of conformance. They also may not be safe to forward to (see
+ CVE-2021-25740 for more information). Implementations SHOULD NOT
+ support ExternalName Services.
+
+
+ Support: Core (Services with a type other than ExternalName)
+
+
+ Support: Implementation-specific (Services with type ExternalName)
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
+ type: string
+ name:
+ description: Name is the name of the referent.
+ maxLength: 253
+ minLength: 1
+ type: string
+ namespace:
+ description: |-
+ Namespace is the namespace of the backend. When unspecified, the local
+ namespace is inferred.
+
+
+ Note that when a namespace different than the local namespace is specified,
+ a ReferenceGrant object is required in the referent namespace to allow that
+ namespace's owner to accept the reference. See the ReferenceGrant
+ documentation for details.
+
+
+ Support: Core
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+ type: string
+ port:
+ description: |-
+ Port specifies the destination port number to use for this resource.
+ Port is required when the referent is a Kubernetes Service. In this
+ case, the port number is the service port number, not the target port.
+ For other resources, destination port might be derived from the referent
+ resource or this field.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - name
+ type: object
+ x-kubernetes-validations:
+ - message: Must have port for Service reference
+ rule: '(size(self.group) == 0 && self.kind
+ == ''Service'') ? has(self.port) : true'
backendRefs:
description: |-
BackendRefs references a Kubernetes object that represents the
- backend server to which the access log will be sent.
- Only Service kind is supported for now.
+ backend server to which the authorization request will be sent.
items:
description: BackendRef defines how an ObjectReference
that is specific to BackendRef.
properties:
+ failover:
+ description: |-
+ Failover This indicates whether the backend is designated as a failover.
+ Multiple failover backends can be configured.
+ It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ The overprovisioning factor is set to 1.4, meaning the failover backends will only start receiving traffic when
+ the health of the active backends falls below 72%.
+ type: boolean
group:
default: ""
description: |-
@@ -10539,39 +11380,695 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind
== ''Service'') ? has(self.port) : true'
- maxItems: 1
+ maxItems: 16
type: array
- x-kubernetes-validations:
- - message: only support Service kind.
- rule: self.all(f, f.kind == 'Service')
- - message: BackendRefs only supports Core
- group.
- rule: self.all(f, f.group == '')
- host:
- description: |-
- Host define the extension service hostname.
- Deprecated: Use BackendRefs instead.
- type: string
- port:
- default: 4317
- description: |-
- Port defines the port the extension service is exposed on.
- Deprecated: Use BackendRefs instead.
- format: int32
- minimum: 0
- type: integer
- resources:
- additionalProperties:
- type: string
+ backendSettings:
description: |-
- Resources is a set of labels that describe the source of a log entry, including envoy node info.
- It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/).
- type: object
+ BackendSettings holds configuration for managing the connection
+ to the backend.
+ properties:
+ circuitBreaker:
+ description: |-
+ Circuit Breaker settings for the upstream connections and requests.
+ If not set, circuit breakers will be enabled with the default thresholds
+ properties:
+ maxConnections:
+ default: 1024
+ description: The maximum number of
+ connections that Envoy will establish
+ to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRequests:
+ default: 1024
+ description: The maximum number of
+ parallel requests that Envoy will
+ make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRetries:
+ default: 1024
+ description: The maximum number of
+ parallel retries that Envoy will
+ make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxPendingRequests:
+ default: 1024
+ description: The maximum number of
+ pending requests that Envoy will
+ queue to the referenced backend
+ defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxRequestsPerConnection:
+ description: |-
+ The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
+ Default: unlimited.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ type: object
+ connection:
+ description: Connection includes backend
+ connection settings.
+ properties:
+ bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
+ BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
+ If unspecified, an implementation defined default is applied (32768 bytes).
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note: that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket
+ to backend.
+ SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ type: object
+ dns:
+ description: DNS includes dns resolution
+ settings.
+ properties:
+ dnsRefreshRate:
+ description: |-
+ DNSRefreshRate specifies the rate at which DNS records should be refreshed.
+ Defaults to 30 seconds.
+ type: string
+ respectDnsTtl:
+ description: |-
+ RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
+ If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
+ Defaults to true.
+ type: boolean
+ type: object
+ healthCheck:
+ description: HealthCheck allows gateway
+ to perform active health checking on
+ backends.
+ properties:
+ active:
+ description: Active health check configuration
+ properties:
+ grpc:
+ description: |-
+ GRPC defines the configuration of the GRPC health checker.
+ It's optional, and can only be used if the specified type is GRPC.
+ properties:
+ service:
+ description: |-
+ Service to send in the health check request.
+ If this is not specified, then the health check request applies to the entire
+ server and not to a specific service.
+ type: string
+ type: object
+ healthyThreshold:
+ default: 1
+ description: HealthyThreshold
+ defines the number of healthy
+ health checks required before
+ a backend host is marked healthy.
+ format: int32
+ minimum: 1
+ type: integer
+ http:
+ description: |-
+ HTTP defines the configuration of http health checker.
+ It's required while the health checker type is HTTP.
+ properties:
+ expectedResponse:
+ description: ExpectedResponse
+ defines a list of HTTP expected
+ responses to match.
+ properties:
+ binary:
+ description: Binary payload
+ base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload
+ in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines
+ the type of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type
+ is Text, text field needs
+ to be set.
+ rule: 'self.type == ''Text''
+ ? has(self.text) : !has(self.text)'
+ - message: If payload type
+ is Binary, binary field
+ needs to be set.
+ rule: 'self.type == ''Binary''
+ ? has(self.binary) : !has(self.binary)'
+ expectedStatuses:
+ description: |-
+ ExpectedStatuses defines a list of HTTP response statuses considered healthy.
+ Defaults to 200 only
+ items:
+ description: HTTPStatus
+ defines the http status
+ code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ method:
+ description: |-
+ Method defines the HTTP method used for health checking.
+ Defaults to GET
+ type: string
+ path:
+ description: Path defines
+ the HTTP path that will
+ be requested during health
+ checking.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - path
+ type: object
+ interval:
+ default: 3s
+ description: Interval defines
+ the time between active health
+ checks.
+ format: duration
+ type: string
+ tcp:
+ description: |-
+ TCP defines the configuration of tcp health checker.
+ It's required while the health checker type is TCP.
+ properties:
+ receive:
+ description: Receive defines
+ the expected response payload.
+ properties:
+ binary:
+ description: Binary payload
+ base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload
+ in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines
+ the type of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type
+ is Text, text field needs
+ to be set.
+ rule: 'self.type == ''Text''
+ ? has(self.text) : !has(self.text)'
+ - message: If payload type
+ is Binary, binary field
+ needs to be set.
+ rule: 'self.type == ''Binary''
+ ? has(self.binary) : !has(self.binary)'
+ send:
+ description: Send defines
+ the request payload.
+ properties:
+ binary:
+ description: Binary payload
+ base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload
+ in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines
+ the type of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type
+ is Text, text field needs
+ to be set.
+ rule: 'self.type == ''Text''
+ ? has(self.text) : !has(self.text)'
+ - message: If payload type
+ is Binary, binary field
+ needs to be set.
+ rule: 'self.type == ''Binary''
+ ? has(self.binary) : !has(self.binary)'
+ type: object
+ timeout:
+ default: 1s
+ description: Timeout defines the
+ time to wait for a health check
+ response.
+ format: duration
+ type: string
+ type:
+ allOf:
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ description: Type defines the
+ type of health checker.
+ type: string
+ unhealthyThreshold:
+ default: 3
+ description: UnhealthyThreshold
+ defines the number of unhealthy
+ health checks required before
+ a backend host is marked unhealthy.
+ format: int32
+ minimum: 1
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If Health Checker type
+ is HTTP, http field needs to be
+ set.
+ rule: 'self.type == ''HTTP'' ? has(self.http)
+ : !has(self.http)'
+ - message: If Health Checker type
+ is TCP, tcp field needs to be
+ set.
+ rule: 'self.type == ''TCP'' ? has(self.tcp)
+ : !has(self.tcp)'
+ - message: The grpc field can only
+ be set if the Health Checker type
+ is GRPC.
+ rule: 'has(self.grpc) ? self.type
+ == ''GRPC'' : true'
+ passive:
+ description: Passive passive check
+ configuration
+ properties:
+ baseEjectionTime:
+ default: 30s
+ description: BaseEjectionTime
+ defines the base duration for
+ which a host will be ejected
+ on consecutive failures.
+ format: duration
+ type: string
+ consecutive5XxErrors:
+ default: 5
+ description: Consecutive5xxErrors
+ sets the number of consecutive
+ 5xx errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveGatewayErrors:
+ default: 0
+ description: ConsecutiveGatewayErrors
+ sets the number of consecutive
+ gateway errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveLocalOriginFailures:
+ default: 5
+ description: |-
+ ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection.
+ Parameter takes effect only when split_external_local_origin_errors is set to true.
+ format: int32
+ type: integer
+ interval:
+ default: 3s
+ description: Interval defines
+ the time between passive health
+ checks.
+ format: duration
+ type: string
+ maxEjectionPercent:
+ default: 10
+ description: MaxEjectionPercent
+ sets the maximum percentage
+ of hosts in a cluster that can
+ be ejected.
+ format: int32
+ type: integer
+ splitExternalLocalOriginErrors:
+ default: false
+ description: SplitExternalLocalOriginErrors
+ enables splitting of errors
+ between external and local origin.
+ type: boolean
+ type: object
+ type: object
+ http2:
+ description: HTTP2 provides HTTP/2 configuration
+ for backend connections.
+ properties:
+ initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
+ If not set, the default value is 1 MiB.
+ x-kubernetes-int-or-string: true
+ initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
+ If not set, the default value is 64 KiB(64*1024).
+ x-kubernetes-int-or-string: true
+ maxConcurrentStreams:
+ description: |-
+ MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
+ If not set, the default value is 100.
+ format: int32
+ maximum: 2147483647
+ minimum: 1
+ type: integer
+ onInvalidMessage:
+ description: |-
+ OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
+ It's recommended for L2 Envoy deployments to set this value to TerminateStream.
+ https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
+ Default: TerminateConnection
+ type: string
+ type: object
+ loadBalancer:
+ description: |-
+ LoadBalancer policy to apply when routing traffic from the gateway to
+ the backend endpoints. Defaults to `LeastRequest`.
+ properties:
+ consistentHash:
+ description: |-
+ ConsistentHash defines the configuration when the load balancer type is
+ set to ConsistentHash
+ properties:
+ cookie:
+ description: Cookie configures
+ the cookie hash policy when
+ the consistent hash type is
+ set to Cookie.
+ properties:
+ attributes:
+ additionalProperties:
+ type: string
+ description: Additional Attributes
+ to set for the generated
+ cookie.
+ type: object
+ name:
+ description: |-
+ Name of the cookie to hash.
+ If this cookie does not exist in the request, Envoy will generate a cookie and set
+ the TTL on the response back to the client based on Layer 4
+ attributes of the backend endpoint, to ensure that these future requests
+ go to the same backend endpoint. Make sure to set the TTL field for this case.
+ type: string
+ ttl:
+ description: |-
+ TTL of the generated cookie if the cookie is not present. This value sets the
+ Max-Age attribute value.
+ type: string
+ required:
+ - name
+ type: object
+ header:
+ description: Header configures
+ the header hash policy when
+ the consistent hash type is
+ set to Header.
+ properties:
+ name:
+ description: Name of the header
+ to hash.
+ type: string
+ required:
+ - name
+ type: object
+ tableSize:
+ default: 65537
+ description: The table size for
+ consistent hashing, must be
+ prime number limited to 5000011.
+ format: int64
+ maximum: 5000011
+ minimum: 2
+ type: integer
+ type:
+ description: |-
+ ConsistentHashType defines the type of input to hash on. Valid Type values are
+ "SourceIP",
+ "Header",
+ "Cookie".
+ enum:
+ - SourceIP
+ - Header
+ - Cookie
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If consistent hash type
+ is header, the header field must
+ be set.
+ rule: 'self.type == ''Header'' ?
+ has(self.header) : !has(self.header)'
+ - message: If consistent hash type
+ is cookie, the cookie field must
+ be set.
+ rule: 'self.type == ''Cookie'' ?
+ has(self.cookie) : !has(self.cookie)'
+ slowStart:
+ description: |-
+ SlowStart defines the configuration related to the slow start load balancer policy.
+ If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently this is only supported for RoundRobin and LeastRequest load balancers
+ properties:
+ window:
+ description: |-
+ Window defines the duration of the warm up period for newly added host.
+ During slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently only supports linear growth of traffic. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig
+ type: string
+ required:
+ - window
+ type: object
+ type:
+ description: |-
+ Type decides the type of Load Balancer policy.
+ Valid LoadBalancerType values are
+ "ConsistentHash",
+ "LeastRequest",
+ "Random",
+ "RoundRobin".
+ enum:
+ - ConsistentHash
+ - LeastRequest
+ - Random
+ - RoundRobin
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If LoadBalancer type is consistentHash,
+ consistentHash field needs to be set.
+ rule: 'self.type == ''ConsistentHash''
+ ? has(self.consistentHash) : !has(self.consistentHash)'
+ - message: Currently SlowStart is only
+ supported for RoundRobin and LeastRequest
+ load balancers.
+ rule: 'self.type in [''Random'', ''ConsistentHash'']
+ ? !has(self.slowStart) : true '
+ proxyProtocol:
+ description: ProxyProtocol enables the
+ Proxy Protocol when communicating with
+ the backend.
+ properties:
+ version:
+ description: |-
+ Version of ProxyProtol
+ Valid ProxyProtocolVersion values are
+ "V1"
+ "V2"
+ enum:
+ - V1
+ - V2
+ type: string
+ required:
+ - version
+ type: object
+ tcpKeepalive:
+ description: |-
+ TcpKeepalive settings associated with the upstream client connection.
+ Disabled by default.
+ properties:
+ idleTime:
+ description: |-
+ The duration a connection needs to be idle before keep-alive
+ probes start being sent.
+ The duration format is
+ Defaults to `7200s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ interval:
+ description: |-
+ The duration between keep-alive probes.
+ Defaults to `75s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ probes:
+ description: |-
+ The total number of unacknowledged probes to send before deciding
+ the connection is dead.
+ Defaults to 9.
+ format: int32
+ type: integer
+ type: object
+ timeout:
+ description: Timeout settings for the
+ backend connections.
+ properties:
+ http:
+ description: Timeout settings for
+ HTTP.
+ properties:
+ connectionIdleTimeout:
+ description: |-
+ The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
+ Default: 1 hour.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ maxConnectionDuration:
+ description: |-
+ The maximum duration of an HTTP connection.
+ Default: unlimited.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ tcp:
+ description: Timeout settings for
+ TCP.
+ properties:
+ connectTimeout:
+ description: |-
+ The timeout for network connection establishment, including TCP and TLS handshakes.
+ Default: 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ type: object
+ type: object
+ host:
+ description: |-
+ Host define the extension service hostname.
+ Deprecated: Use BackendRefs instead.
+ type: string
+ port:
+ default: 4317
+ description: |-
+ Port defines the port the extension service is exposed on.
+ Deprecated: Use BackendRefs instead.
+ format: int32
+ minimum: 0
+ type: integer
+ resources:
+ additionalProperties:
+ type: string
+ description: |-
+ Resources is a set of labels that describe the source of a log entry, including envoy node info.
+ It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/).
+ type: object
type: object
x-kubernetes-validations:
- message: host or backendRefs needs to be set
rule: has(self.host) || self.backendRefs.size()
> 0
+ - message: BackendRefs must be used, backendRef
+ is not supported.
+ rule: '!has(self.backendRef)'
+ - message: BackendRefs only supports Service kind.
+ rule: 'has(self.backendRefs) ? self.backendRefs.all(f,
+ f.kind == ''Service'') : true'
+ - message: BackendRefs only supports Core group.
+ rule: 'has(self.backendRefs) ? (self.backendRefs.all(f,
+ f.group == "")) : true'
type:
description: Type defines the type of accesslog
sink.
@@ -10688,15 +12185,104 @@ spec:
OpenTelemetry defines the configuration for OpenTelemetry sink.
It's required if the sink type is OpenTelemetry.
properties:
+ backendRef:
+ description: |-
+ BackendRef references a Kubernetes object that represents the
+ backend server to which the authorization request will be sent.
+
+
+ Deprecated: Use BackendRefs instead.
+ properties:
+ group:
+ default: ""
+ description: |-
+ Group is the group of the referent. For example, "gateway.networking.k8s.io".
+ When unspecified or empty string, core API group is inferred.
+ maxLength: 253
+ pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ kind:
+ default: Service
+ description: |-
+ Kind is the Kubernetes resource kind of the referent. For example
+ "Service".
+
+
+ Defaults to "Service" when not specified.
+
+
+ ExternalName services can refer to CNAME DNS records that may live
+ outside of the cluster and as such are difficult to reason about in
+ terms of conformance. They also may not be safe to forward to (see
+ CVE-2021-25740 for more information). Implementations SHOULD NOT
+ support ExternalName Services.
+
+
+ Support: Core (Services with a type other than ExternalName)
+
+
+ Support: Implementation-specific (Services with type ExternalName)
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
+ type: string
+ name:
+ description: Name is the name of the referent.
+ maxLength: 253
+ minLength: 1
+ type: string
+ namespace:
+ description: |-
+ Namespace is the namespace of the backend. When unspecified, the local
+ namespace is inferred.
+
+
+ Note that when a namespace different than the local namespace is specified,
+ a ReferenceGrant object is required in the referent namespace to allow that
+ namespace's owner to accept the reference. See the ReferenceGrant
+ documentation for details.
+
+
+ Support: Core
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+ type: string
+ port:
+ description: |-
+ Port specifies the destination port number to use for this resource.
+ Port is required when the referent is a Kubernetes Service. In this
+ case, the port number is the service port number, not the target port.
+ For other resources, destination port might be derived from the referent
+ resource or this field.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - name
+ type: object
+ x-kubernetes-validations:
+ - message: Must have port for Service reference
+ rule: '(size(self.group) == 0 && self.kind ==
+ ''Service'') ? has(self.port) : true'
backendRefs:
description: |-
BackendRefs references a Kubernetes object that represents the
- backend server to which the metric will be sent.
- Only Service kind is supported for now.
+ backend server to which the authorization request will be sent.
items:
description: BackendRef defines how an ObjectReference
that is specific to BackendRef.
properties:
+ failover:
+ description: |-
+ Failover This indicates whether the backend is designated as a failover.
+ Multiple failover backends can be configured.
+ It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ The overprovisioning factor is set to 1.4, meaning the failover backends will only start receiving traffic when
+ the health of the active backends falls below 72%.
+ type: boolean
group:
default: ""
description: |-
@@ -10770,50 +12356,677 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind ==
''Service'') ? has(self.port) : true'
- maxItems: 1
+ maxItems: 16
type: array
- x-kubernetes-validations:
- - message: only support Service kind.
- rule: self.all(f, f.kind == 'Service')
- - message: BackendRefs only supports Core group.
- rule: self.all(f, f.group == '')
- host:
- description: |-
- Host define the service hostname.
- Deprecated: Use BackendRefs instead.
- type: string
- port:
- default: 4317
+ backendSettings:
description: |-
- Port defines the port the service is exposed on.
- Deprecated: Use BackendRefs instead.
- format: int32
- maximum: 65535
- minimum: 0
- type: integer
- type: object
- x-kubernetes-validations:
- - message: host or backendRefs needs to be set
- rule: has(self.host) || self.backendRefs.size() >
- 0
- type:
- default: OpenTelemetry
- description: |-
- Type defines the metric sink type.
- EG currently only supports OpenTelemetry.
- enum:
- - OpenTelemetry
- type: string
- required:
- - type
- type: object
- x-kubernetes-validations:
- - message: If MetricSink type is OpenTelemetry, openTelemetry
- field needs to be set.
- rule: 'self.type == ''OpenTelemetry'' ? has(self.openTelemetry)
- : !has(self.openTelemetry)'
- type: array
- type: object
+ BackendSettings holds configuration for managing the connection
+ to the backend.
+ properties:
+ circuitBreaker:
+ description: |-
+ Circuit Breaker settings for the upstream connections and requests.
+ If not set, circuit breakers will be enabled with the default thresholds
+ properties:
+ maxConnections:
+ default: 1024
+ description: The maximum number of connections
+ that Envoy will establish to the referenced
+ backend defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRequests:
+ default: 1024
+ description: The maximum number of parallel
+ requests that Envoy will make to the referenced
+ backend defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRetries:
+ default: 1024
+ description: The maximum number of parallel
+ retries that Envoy will make to the referenced
+ backend defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxPendingRequests:
+ default: 1024
+ description: The maximum number of pending
+ requests that Envoy will queue to the
+ referenced backend defined within a xRoute
+ rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxRequestsPerConnection:
+ description: |-
+ The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
+ Default: unlimited.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ type: object
+ connection:
+ description: Connection includes backend connection
+ settings.
+ properties:
+ bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
+ BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
+ If unspecified, an implementation defined default is applied (32768 bytes).
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note: that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket
+ to backend.
+ SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ type: object
+ dns:
+ description: DNS includes dns resolution settings.
+ properties:
+ dnsRefreshRate:
+ description: |-
+ DNSRefreshRate specifies the rate at which DNS records should be refreshed.
+ Defaults to 30 seconds.
+ type: string
+ respectDnsTtl:
+ description: |-
+ RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
+ If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
+ Defaults to true.
+ type: boolean
+ type: object
+ healthCheck:
+ description: HealthCheck allows gateway to perform
+ active health checking on backends.
+ properties:
+ active:
+ description: Active health check configuration
+ properties:
+ grpc:
+ description: |-
+ GRPC defines the configuration of the GRPC health checker.
+ It's optional, and can only be used if the specified type is GRPC.
+ properties:
+ service:
+ description: |-
+ Service to send in the health check request.
+ If this is not specified, then the health check request applies to the entire
+ server and not to a specific service.
+ type: string
+ type: object
+ healthyThreshold:
+ default: 1
+ description: HealthyThreshold defines
+ the number of healthy health checks
+ required before a backend host is
+ marked healthy.
+ format: int32
+ minimum: 1
+ type: integer
+ http:
+ description: |-
+ HTTP defines the configuration of http health checker.
+ It's required while the health checker type is HTTP.
+ properties:
+ expectedResponse:
+ description: ExpectedResponse defines
+ a list of HTTP expected responses
+ to match.
+ properties:
+ binary:
+ description: Binary payload
+ base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in
+ plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the
+ type of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text,
+ text field needs to be set.
+ rule: 'self.type == ''Text'' ?
+ has(self.text) : !has(self.text)'
+ - message: If payload type is Binary,
+ binary field needs to be set.
+ rule: 'self.type == ''Binary''
+ ? has(self.binary) : !has(self.binary)'
+ expectedStatuses:
+ description: |-
+ ExpectedStatuses defines a list of HTTP response statuses considered healthy.
+ Defaults to 200 only
+ items:
+ description: HTTPStatus defines
+ the http status code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ method:
+ description: |-
+ Method defines the HTTP method used for health checking.
+ Defaults to GET
+ type: string
+ path:
+ description: Path defines the HTTP
+ path that will be requested during
+ health checking.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - path
+ type: object
+ interval:
+ default: 3s
+ description: Interval defines the time
+ between active health checks.
+ format: duration
+ type: string
+ tcp:
+ description: |-
+ TCP defines the configuration of tcp health checker.
+ It's required while the health checker type is TCP.
+ properties:
+ receive:
+ description: Receive defines the
+ expected response payload.
+ properties:
+ binary:
+ description: Binary payload
+ base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in
+ plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the
+ type of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text,
+ text field needs to be set.
+ rule: 'self.type == ''Text'' ?
+ has(self.text) : !has(self.text)'
+ - message: If payload type is Binary,
+ binary field needs to be set.
+ rule: 'self.type == ''Binary''
+ ? has(self.binary) : !has(self.binary)'
+ send:
+ description: Send defines the request
+ payload.
+ properties:
+ binary:
+ description: Binary payload
+ base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in
+ plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the
+ type of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text,
+ text field needs to be set.
+ rule: 'self.type == ''Text'' ?
+ has(self.text) : !has(self.text)'
+ - message: If payload type is Binary,
+ binary field needs to be set.
+ rule: 'self.type == ''Binary''
+ ? has(self.binary) : !has(self.binary)'
+ type: object
+ timeout:
+ default: 1s
+ description: Timeout defines the time
+ to wait for a health check response.
+ format: duration
+ type: string
+ type:
+ allOf:
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ description: Type defines the type of
+ health checker.
+ type: string
+ unhealthyThreshold:
+ default: 3
+ description: UnhealthyThreshold defines
+ the number of unhealthy health checks
+ required before a backend host is
+ marked unhealthy.
+ format: int32
+ minimum: 1
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If Health Checker type is HTTP,
+ http field needs to be set.
+ rule: 'self.type == ''HTTP'' ? has(self.http)
+ : !has(self.http)'
+ - message: If Health Checker type is TCP,
+ tcp field needs to be set.
+ rule: 'self.type == ''TCP'' ? has(self.tcp)
+ : !has(self.tcp)'
+ - message: The grpc field can only be set
+ if the Health Checker type is GRPC.
+ rule: 'has(self.grpc) ? self.type == ''GRPC''
+ : true'
+ passive:
+ description: Passive passive check configuration
+ properties:
+ baseEjectionTime:
+ default: 30s
+ description: BaseEjectionTime defines
+ the base duration for which a host
+ will be ejected on consecutive failures.
+ format: duration
+ type: string
+ consecutive5XxErrors:
+ default: 5
+ description: Consecutive5xxErrors sets
+ the number of consecutive 5xx errors
+ triggering ejection.
+ format: int32
+ type: integer
+ consecutiveGatewayErrors:
+ default: 0
+ description: ConsecutiveGatewayErrors
+ sets the number of consecutive gateway
+ errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveLocalOriginFailures:
+ default: 5
+ description: |-
+ ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection.
+ Parameter takes effect only when split_external_local_origin_errors is set to true.
+ format: int32
+ type: integer
+ interval:
+ default: 3s
+ description: Interval defines the time
+ between passive health checks.
+ format: duration
+ type: string
+ maxEjectionPercent:
+ default: 10
+ description: MaxEjectionPercent sets
+ the maximum percentage of hosts in
+ a cluster that can be ejected.
+ format: int32
+ type: integer
+ splitExternalLocalOriginErrors:
+ default: false
+ description: SplitExternalLocalOriginErrors
+ enables splitting of errors between
+ external and local origin.
+ type: boolean
+ type: object
+ type: object
+ http2:
+ description: HTTP2 provides HTTP/2 configuration
+ for backend connections.
+ properties:
+ initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
+ If not set, the default value is 1 MiB.
+ x-kubernetes-int-or-string: true
+ initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
+ If not set, the default value is 64 KiB(64*1024).
+ x-kubernetes-int-or-string: true
+ maxConcurrentStreams:
+ description: |-
+ MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
+ If not set, the default value is 100.
+ format: int32
+ maximum: 2147483647
+ minimum: 1
+ type: integer
+ onInvalidMessage:
+ description: |-
+ OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
+ It's recommended for L2 Envoy deployments to set this value to TerminateStream.
+ https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
+ Default: TerminateConnection
+ type: string
+ type: object
+ loadBalancer:
+ description: |-
+ LoadBalancer policy to apply when routing traffic from the gateway to
+ the backend endpoints. Defaults to `LeastRequest`.
+ properties:
+ consistentHash:
+ description: |-
+ ConsistentHash defines the configuration when the load balancer type is
+ set to ConsistentHash
+ properties:
+ cookie:
+ description: Cookie configures the cookie
+ hash policy when the consistent hash
+ type is set to Cookie.
+ properties:
+ attributes:
+ additionalProperties:
+ type: string
+ description: Additional Attributes
+ to set for the generated cookie.
+ type: object
+ name:
+ description: |-
+ Name of the cookie to hash.
+ If this cookie does not exist in the request, Envoy will generate a cookie and set
+ the TTL on the response back to the client based on Layer 4
+ attributes of the backend endpoint, to ensure that these future requests
+ go to the same backend endpoint. Make sure to set the TTL field for this case.
+ type: string
+ ttl:
+ description: |-
+ TTL of the generated cookie if the cookie is not present. This value sets the
+ Max-Age attribute value.
+ type: string
+ required:
+ - name
+ type: object
+ header:
+ description: Header configures the header
+ hash policy when the consistent hash
+ type is set to Header.
+ properties:
+ name:
+ description: Name of the header
+ to hash.
+ type: string
+ required:
+ - name
+ type: object
+ tableSize:
+ default: 65537
+ description: The table size for consistent
+ hashing, must be prime number limited
+ to 5000011.
+ format: int64
+ maximum: 5000011
+ minimum: 2
+ type: integer
+ type:
+ description: |-
+ ConsistentHashType defines the type of input to hash on. Valid Type values are
+ "SourceIP",
+ "Header",
+ "Cookie".
+ enum:
+ - SourceIP
+ - Header
+ - Cookie
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If consistent hash type is header,
+ the header field must be set.
+ rule: 'self.type == ''Header'' ? has(self.header)
+ : !has(self.header)'
+ - message: If consistent hash type is cookie,
+ the cookie field must be set.
+ rule: 'self.type == ''Cookie'' ? has(self.cookie)
+ : !has(self.cookie)'
+ slowStart:
+ description: |-
+ SlowStart defines the configuration related to the slow start load balancer policy.
+ If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently this is only supported for RoundRobin and LeastRequest load balancers
+ properties:
+ window:
+ description: |-
+ Window defines the duration of the warm up period for newly added host.
+ During slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently only supports linear growth of traffic. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig
+ type: string
+ required:
+ - window
+ type: object
+ type:
+ description: |-
+ Type decides the type of Load Balancer policy.
+ Valid LoadBalancerType values are
+ "ConsistentHash",
+ "LeastRequest",
+ "Random",
+ "RoundRobin".
+ enum:
+ - ConsistentHash
+ - LeastRequest
+ - Random
+ - RoundRobin
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If LoadBalancer type is consistentHash,
+ consistentHash field needs to be set.
+ rule: 'self.type == ''ConsistentHash'' ? has(self.consistentHash)
+ : !has(self.consistentHash)'
+ - message: Currently SlowStart is only supported
+ for RoundRobin and LeastRequest load balancers.
+ rule: 'self.type in [''Random'', ''ConsistentHash'']
+ ? !has(self.slowStart) : true '
+ proxyProtocol:
+ description: ProxyProtocol enables the Proxy
+ Protocol when communicating with the backend.
+ properties:
+ version:
+ description: |-
+ Version of ProxyProtol
+ Valid ProxyProtocolVersion values are
+ "V1"
+ "V2"
+ enum:
+ - V1
+ - V2
+ type: string
+ required:
+ - version
+ type: object
+ tcpKeepalive:
+ description: |-
+ TcpKeepalive settings associated with the upstream client connection.
+ Disabled by default.
+ properties:
+ idleTime:
+ description: |-
+ The duration a connection needs to be idle before keep-alive
+ probes start being sent.
+ The duration format is
+ Defaults to `7200s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ interval:
+ description: |-
+ The duration between keep-alive probes.
+ Defaults to `75s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ probes:
+ description: |-
+ The total number of unacknowledged probes to send before deciding
+ the connection is dead.
+ Defaults to 9.
+ format: int32
+ type: integer
+ type: object
+ timeout:
+ description: Timeout settings for the backend
+ connections.
+ properties:
+ http:
+ description: Timeout settings for HTTP.
+ properties:
+ connectionIdleTimeout:
+ description: |-
+ The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
+ Default: 1 hour.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ maxConnectionDuration:
+ description: |-
+ The maximum duration of an HTTP connection.
+ Default: unlimited.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ tcp:
+ description: Timeout settings for TCP.
+ properties:
+ connectTimeout:
+ description: |-
+ The timeout for network connection establishment, including TCP and TLS handshakes.
+ Default: 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ type: object
+ type: object
+ host:
+ description: |-
+ Host define the service hostname.
+ Deprecated: Use BackendRefs instead.
+ type: string
+ port:
+ default: 4317
+ description: |-
+ Port defines the port the service is exposed on.
+ Deprecated: Use BackendRefs instead.
+ format: int32
+ maximum: 65535
+ minimum: 0
+ type: integer
+ type: object
+ x-kubernetes-validations:
+ - message: host or backendRefs needs to be set
+ rule: has(self.host) || self.backendRefs.size() >
+ 0
+ - message: BackendRefs must be used, backendRef is not
+ supported.
+ rule: '!has(self.backendRef)'
+ - message: only supports Service kind.
+ rule: 'has(self.backendRefs) ? self.backendRefs.all(f,
+ f.kind == ''Service'') : true'
+ - message: BackendRefs only supports Core group.
+ rule: 'has(self.backendRefs) ? (self.backendRefs.all(f,
+ f.group == "")) : true'
+ type:
+ default: OpenTelemetry
+ description: |-
+ Type defines the metric sink type.
+ EG currently only supports OpenTelemetry.
+ enum:
+ - OpenTelemetry
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If MetricSink type is OpenTelemetry, openTelemetry
+ field needs to be set.
+ rule: 'self.type == ''OpenTelemetry'' ? has(self.openTelemetry)
+ : !has(self.openTelemetry)'
+ maxItems: 16
+ type: array
+ type: object
tracing:
description: |-
Tracing defines tracing configuration for managed proxies.
@@ -10884,15 +13097,104 @@ spec:
provider:
description: Provider defines the tracing provider.
properties:
+ backendRef:
+ description: |-
+ BackendRef references a Kubernetes object that represents the
+ backend server to which the authorization request will be sent.
+
+
+ Deprecated: Use BackendRefs instead.
+ properties:
+ group:
+ default: ""
+ description: |-
+ Group is the group of the referent. For example, "gateway.networking.k8s.io".
+ When unspecified or empty string, core API group is inferred.
+ maxLength: 253
+ pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+ type: string
+ kind:
+ default: Service
+ description: |-
+ Kind is the Kubernetes resource kind of the referent. For example
+ "Service".
+
+
+ Defaults to "Service" when not specified.
+
+
+ ExternalName services can refer to CNAME DNS records that may live
+ outside of the cluster and as such are difficult to reason about in
+ terms of conformance. They also may not be safe to forward to (see
+ CVE-2021-25740 for more information). Implementations SHOULD NOT
+ support ExternalName Services.
+
+
+ Support: Core (Services with a type other than ExternalName)
+
+
+ Support: Implementation-specific (Services with type ExternalName)
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
+ type: string
+ name:
+ description: Name is the name of the referent.
+ maxLength: 253
+ minLength: 1
+ type: string
+ namespace:
+ description: |-
+ Namespace is the namespace of the backend. When unspecified, the local
+ namespace is inferred.
+
+
+ Note that when a namespace different than the local namespace is specified,
+ a ReferenceGrant object is required in the referent namespace to allow that
+ namespace's owner to accept the reference. See the ReferenceGrant
+ documentation for details.
+
+
+ Support: Core
+ maxLength: 63
+ minLength: 1
+ pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+ type: string
+ port:
+ description: |-
+ Port specifies the destination port number to use for this resource.
+ Port is required when the referent is a Kubernetes Service. In this
+ case, the port number is the service port number, not the target port.
+ For other resources, destination port might be derived from the referent
+ resource or this field.
+ format: int32
+ maximum: 65535
+ minimum: 1
+ type: integer
+ required:
+ - name
+ type: object
+ x-kubernetes-validations:
+ - message: Must have port for Service reference
+ rule: '(size(self.group) == 0 && self.kind == ''Service'')
+ ? has(self.port) : true'
backendRefs:
description: |-
BackendRefs references a Kubernetes object that represents the
- backend server to which the trace will be sent.
- Only Service kind is supported for now.
+ backend server to which the authorization request will be sent.
items:
description: BackendRef defines how an ObjectReference
that is specific to BackendRef.
properties:
+ failover:
+ description: |-
+ Failover This indicates whether the backend is designated as a failover.
+ Multiple failover backends can be configured.
+ It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ The overprovisioning factor is set to 1.4, meaning the failover backends will only start receiving traffic when
+ the health of the active backends falls below 72%.
+ type: boolean
group:
default: ""
description: |-
@@ -10966,13 +13268,625 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind == ''Service'')
? has(self.port) : true'
- maxItems: 1
+ maxItems: 16
type: array
- x-kubernetes-validations:
- - message: only support Service kind.
- rule: self.all(f, f.kind == 'Service')
- - message: BackendRefs only supports Core group.
- rule: self.all(f, f.group == '')
+ backendSettings:
+ description: |-
+ BackendSettings holds configuration for managing the connection
+ to the backend.
+ properties:
+ circuitBreaker:
+ description: |-
+ Circuit Breaker settings for the upstream connections and requests.
+ If not set, circuit breakers will be enabled with the default thresholds
+ properties:
+ maxConnections:
+ default: 1024
+ description: The maximum number of connections
+ that Envoy will establish to the referenced
+ backend defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRequests:
+ default: 1024
+ description: The maximum number of parallel requests
+ that Envoy will make to the referenced backend
+ defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRetries:
+ default: 1024
+ description: The maximum number of parallel retries
+ that Envoy will make to the referenced backend
+ defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxPendingRequests:
+ default: 1024
+ description: The maximum number of pending requests
+ that Envoy will queue to the referenced backend
+ defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxRequestsPerConnection:
+ description: |-
+ The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
+ Default: unlimited.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ type: object
+ connection:
+ description: Connection includes backend connection
+ settings.
+ properties:
+ bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
+ BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
+ If unspecified, an implementation defined default is applied (32768 bytes).
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note: that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket
+ to backend.
+ SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ type: object
+ dns:
+ description: DNS includes dns resolution settings.
+ properties:
+ dnsRefreshRate:
+ description: |-
+ DNSRefreshRate specifies the rate at which DNS records should be refreshed.
+ Defaults to 30 seconds.
+ type: string
+ respectDnsTtl:
+ description: |-
+ RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
+ If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
+ Defaults to true.
+ type: boolean
+ type: object
+ healthCheck:
+ description: HealthCheck allows gateway to perform
+ active health checking on backends.
+ properties:
+ active:
+ description: Active health check configuration
+ properties:
+ grpc:
+ description: |-
+ GRPC defines the configuration of the GRPC health checker.
+ It's optional, and can only be used if the specified type is GRPC.
+ properties:
+ service:
+ description: |-
+ Service to send in the health check request.
+ If this is not specified, then the health check request applies to the entire
+ server and not to a specific service.
+ type: string
+ type: object
+ healthyThreshold:
+ default: 1
+ description: HealthyThreshold defines the
+ number of healthy health checks required
+ before a backend host is marked healthy.
+ format: int32
+ minimum: 1
+ type: integer
+ http:
+ description: |-
+ HTTP defines the configuration of http health checker.
+ It's required while the health checker type is HTTP.
+ properties:
+ expectedResponse:
+ description: ExpectedResponse defines
+ a list of HTTP expected responses to
+ match.
+ properties:
+ binary:
+ description: Binary payload base64
+ encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain
+ text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type
+ of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text
+ field needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary,
+ binary field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ expectedStatuses:
+ description: |-
+ ExpectedStatuses defines a list of HTTP response statuses considered healthy.
+ Defaults to 200 only
+ items:
+ description: HTTPStatus defines the
+ http status code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ method:
+ description: |-
+ Method defines the HTTP method used for health checking.
+ Defaults to GET
+ type: string
+ path:
+ description: Path defines the HTTP path
+ that will be requested during health
+ checking.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - path
+ type: object
+ interval:
+ default: 3s
+ description: Interval defines the time between
+ active health checks.
+ format: duration
+ type: string
+ tcp:
+ description: |-
+ TCP defines the configuration of tcp health checker.
+ It's required while the health checker type is TCP.
+ properties:
+ receive:
+ description: Receive defines the expected
+ response payload.
+ properties:
+ binary:
+ description: Binary payload base64
+ encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain
+ text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type
+ of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text
+ field needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary,
+ binary field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ send:
+ description: Send defines the request
+ payload.
+ properties:
+ binary:
+ description: Binary payload base64
+ encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain
+ text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type
+ of the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text
+ field needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary,
+ binary field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ type: object
+ timeout:
+ default: 1s
+ description: Timeout defines the time to wait
+ for a health check response.
+ format: duration
+ type: string
+ type:
+ allOf:
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ description: Type defines the type of health
+ checker.
+ type: string
+ unhealthyThreshold:
+ default: 3
+ description: UnhealthyThreshold defines the
+ number of unhealthy health checks required
+ before a backend host is marked unhealthy.
+ format: int32
+ minimum: 1
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If Health Checker type is HTTP, http
+ field needs to be set.
+ rule: 'self.type == ''HTTP'' ? has(self.http)
+ : !has(self.http)'
+ - message: If Health Checker type is TCP, tcp
+ field needs to be set.
+ rule: 'self.type == ''TCP'' ? has(self.tcp)
+ : !has(self.tcp)'
+ - message: The grpc field can only be set if the
+ Health Checker type is GRPC.
+ rule: 'has(self.grpc) ? self.type == ''GRPC''
+ : true'
+ passive:
+ description: Passive passive check configuration
+ properties:
+ baseEjectionTime:
+ default: 30s
+ description: BaseEjectionTime defines the
+ base duration for which a host will be ejected
+ on consecutive failures.
+ format: duration
+ type: string
+ consecutive5XxErrors:
+ default: 5
+ description: Consecutive5xxErrors sets the
+ number of consecutive 5xx errors triggering
+ ejection.
+ format: int32
+ type: integer
+ consecutiveGatewayErrors:
+ default: 0
+ description: ConsecutiveGatewayErrors sets
+ the number of consecutive gateway errors
+ triggering ejection.
+ format: int32
+ type: integer
+ consecutiveLocalOriginFailures:
+ default: 5
+ description: |-
+ ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection.
+ Parameter takes effect only when split_external_local_origin_errors is set to true.
+ format: int32
+ type: integer
+ interval:
+ default: 3s
+ description: Interval defines the time between
+ passive health checks.
+ format: duration
+ type: string
+ maxEjectionPercent:
+ default: 10
+ description: MaxEjectionPercent sets the maximum
+ percentage of hosts in a cluster that can
+ be ejected.
+ format: int32
+ type: integer
+ splitExternalLocalOriginErrors:
+ default: false
+ description: SplitExternalLocalOriginErrors
+ enables splitting of errors between external
+ and local origin.
+ type: boolean
+ type: object
+ type: object
+ http2:
+ description: HTTP2 provides HTTP/2 configuration for
+ backend connections.
+ properties:
+ initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
+ If not set, the default value is 1 MiB.
+ x-kubernetes-int-or-string: true
+ initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
+ If not set, the default value is 64 KiB(64*1024).
+ x-kubernetes-int-or-string: true
+ maxConcurrentStreams:
+ description: |-
+ MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
+ If not set, the default value is 100.
+ format: int32
+ maximum: 2147483647
+ minimum: 1
+ type: integer
+ onInvalidMessage:
+ description: |-
+ OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
+ It's recommended for L2 Envoy deployments to set this value to TerminateStream.
+ https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
+ Default: TerminateConnection
+ type: string
+ type: object
+ loadBalancer:
+ description: |-
+ LoadBalancer policy to apply when routing traffic from the gateway to
+ the backend endpoints. Defaults to `LeastRequest`.
+ properties:
+ consistentHash:
+ description: |-
+ ConsistentHash defines the configuration when the load balancer type is
+ set to ConsistentHash
+ properties:
+ cookie:
+ description: Cookie configures the cookie
+ hash policy when the consistent hash type
+ is set to Cookie.
+ properties:
+ attributes:
+ additionalProperties:
+ type: string
+ description: Additional Attributes to
+ set for the generated cookie.
+ type: object
+ name:
+ description: |-
+ Name of the cookie to hash.
+ If this cookie does not exist in the request, Envoy will generate a cookie and set
+ the TTL on the response back to the client based on Layer 4
+ attributes of the backend endpoint, to ensure that these future requests
+ go to the same backend endpoint. Make sure to set the TTL field for this case.
+ type: string
+ ttl:
+ description: |-
+ TTL of the generated cookie if the cookie is not present. This value sets the
+ Max-Age attribute value.
+ type: string
+ required:
+ - name
+ type: object
+ header:
+ description: Header configures the header
+ hash policy when the consistent hash type
+ is set to Header.
+ properties:
+ name:
+ description: Name of the header to hash.
+ type: string
+ required:
+ - name
+ type: object
+ tableSize:
+ default: 65537
+ description: The table size for consistent
+ hashing, must be prime number limited to
+ 5000011.
+ format: int64
+ maximum: 5000011
+ minimum: 2
+ type: integer
+ type:
+ description: |-
+ ConsistentHashType defines the type of input to hash on. Valid Type values are
+ "SourceIP",
+ "Header",
+ "Cookie".
+ enum:
+ - SourceIP
+ - Header
+ - Cookie
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If consistent hash type is header,
+ the header field must be set.
+ rule: 'self.type == ''Header'' ? has(self.header)
+ : !has(self.header)'
+ - message: If consistent hash type is cookie,
+ the cookie field must be set.
+ rule: 'self.type == ''Cookie'' ? has(self.cookie)
+ : !has(self.cookie)'
+ slowStart:
+ description: |-
+ SlowStart defines the configuration related to the slow start load balancer policy.
+ If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently this is only supported for RoundRobin and LeastRequest load balancers
+ properties:
+ window:
+ description: |-
+ Window defines the duration of the warm up period for newly added host.
+ During slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently only supports linear growth of traffic. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig
+ type: string
+ required:
+ - window
+ type: object
+ type:
+ description: |-
+ Type decides the type of Load Balancer policy.
+ Valid LoadBalancerType values are
+ "ConsistentHash",
+ "LeastRequest",
+ "Random",
+ "RoundRobin".
+ enum:
+ - ConsistentHash
+ - LeastRequest
+ - Random
+ - RoundRobin
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If LoadBalancer type is consistentHash,
+ consistentHash field needs to be set.
+ rule: 'self.type == ''ConsistentHash'' ? has(self.consistentHash)
+ : !has(self.consistentHash)'
+ - message: Currently SlowStart is only supported for
+ RoundRobin and LeastRequest load balancers.
+ rule: 'self.type in [''Random'', ''ConsistentHash'']
+ ? !has(self.slowStart) : true '
+ proxyProtocol:
+ description: ProxyProtocol enables the Proxy Protocol
+ when communicating with the backend.
+ properties:
+ version:
+ description: |-
+ Version of ProxyProtol
+ Valid ProxyProtocolVersion values are
+ "V1"
+ "V2"
+ enum:
+ - V1
+ - V2
+ type: string
+ required:
+ - version
+ type: object
+ tcpKeepalive:
+ description: |-
+ TcpKeepalive settings associated with the upstream client connection.
+ Disabled by default.
+ properties:
+ idleTime:
+ description: |-
+ The duration a connection needs to be idle before keep-alive
+ probes start being sent.
+ The duration format is
+ Defaults to `7200s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ interval:
+ description: |-
+ The duration between keep-alive probes.
+ Defaults to `75s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ probes:
+ description: |-
+ The total number of unacknowledged probes to send before deciding
+ the connection is dead.
+ Defaults to 9.
+ format: int32
+ type: integer
+ type: object
+ timeout:
+ description: Timeout settings for the backend connections.
+ properties:
+ http:
+ description: Timeout settings for HTTP.
+ properties:
+ connectionIdleTimeout:
+ description: |-
+ The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
+ Default: 1 hour.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ maxConnectionDuration:
+ description: |-
+ The maximum duration of an HTTP connection.
+ Default: unlimited.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ tcp:
+ description: Timeout settings for TCP.
+ properties:
+ connectTimeout:
+ description: |-
+ The timeout for network connection establishment, including TCP and TLS handshakes.
+ Default: 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ type: object
+ type: object
host:
description: |-
Host define the provider service hostname.
@@ -11015,6 +13929,14 @@ spec:
x-kubernetes-validations:
- message: host or backendRefs needs to be set
rule: has(self.host) || self.backendRefs.size() > 0
+ - message: BackendRefs must be used, backendRef is not supported.
+ rule: '!has(self.backendRef)'
+ - message: only supports Service kind.
+ rule: 'has(self.backendRefs) ? self.backendRefs.all(f, f.kind
+ == ''Service'') : true'
+ - message: BackendRefs only supports Core group.
+ rule: 'has(self.backendRefs) ? (self.backendRefs.all(f,
+ f.group == "")) : true'
samplingRate:
default: 100
description: |-
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
index 3906b325b3d..da6c3ae25fc 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
@@ -260,7 +260,6 @@ spec:
description: |-
BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
- Only Service kind is supported for now.
Deprecated: Use BackendRefs instead.
@@ -342,11 +341,19 @@ spec:
description: |-
BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
- Only Service kind is supported for now.
items:
description: BackendRef defines how an ObjectReference that
is specific to BackendRef.
properties:
+ failover:
+ description: |-
+ Failover This indicates whether the backend is designated as a failover.
+ Multiple failover backends can be configured.
+ It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ The overprovisioning factor is set to 1.4, meaning the failover backends will only start receiving traffic when
+ the health of the active backends falls below 72%.
+ type: boolean
group:
default: ""
description: |-
@@ -420,17 +427,626 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind == ''Service'')
? has(self.port) : true'
- maxItems: 1
+ maxItems: 16
type: array
- x-kubernetes-validations:
- - message: only support Service kind.
- rule: self.all(f, f.kind == 'Service')
- - message: BackendRefs only supports Core group.
- rule: self.all(f, f.group == '')
+ backendSettings:
+ description: |-
+ BackendSettings holds configuration for managing the connection
+ to the backend.
+ properties:
+ circuitBreaker:
+ description: |-
+ Circuit Breaker settings for the upstream connections and requests.
+ If not set, circuit breakers will be enabled with the default thresholds
+ properties:
+ maxConnections:
+ default: 1024
+ description: The maximum number of connections that
+ Envoy will establish to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRequests:
+ default: 1024
+ description: The maximum number of parallel requests
+ that Envoy will make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRetries:
+ default: 1024
+ description: The maximum number of parallel retries
+ that Envoy will make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxPendingRequests:
+ default: 1024
+ description: The maximum number of pending requests
+ that Envoy will queue to the referenced backend
+ defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxRequestsPerConnection:
+ description: |-
+ The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
+ Default: unlimited.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ type: object
+ connection:
+ description: Connection includes backend connection settings.
+ properties:
+ bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
+ BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
+ If unspecified, an implementation defined default is applied (32768 bytes).
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note: that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket
+ to backend.
+ SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ type: object
+ dns:
+ description: DNS includes dns resolution settings.
+ properties:
+ dnsRefreshRate:
+ description: |-
+ DNSRefreshRate specifies the rate at which DNS records should be refreshed.
+ Defaults to 30 seconds.
+ type: string
+ respectDnsTtl:
+ description: |-
+ RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
+ If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
+ Defaults to true.
+ type: boolean
+ type: object
+ healthCheck:
+ description: HealthCheck allows gateway to perform active
+ health checking on backends.
+ properties:
+ active:
+ description: Active health check configuration
+ properties:
+ grpc:
+ description: |-
+ GRPC defines the configuration of the GRPC health checker.
+ It's optional, and can only be used if the specified type is GRPC.
+ properties:
+ service:
+ description: |-
+ Service to send in the health check request.
+ If this is not specified, then the health check request applies to the entire
+ server and not to a specific service.
+ type: string
+ type: object
+ healthyThreshold:
+ default: 1
+ description: HealthyThreshold defines the number
+ of healthy health checks required before a backend
+ host is marked healthy.
+ format: int32
+ minimum: 1
+ type: integer
+ http:
+ description: |-
+ HTTP defines the configuration of http health checker.
+ It's required while the health checker type is HTTP.
+ properties:
+ expectedResponse:
+ description: ExpectedResponse defines a list
+ of HTTP expected responses to match.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of
+ the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ expectedStatuses:
+ description: |-
+ ExpectedStatuses defines a list of HTTP response statuses considered healthy.
+ Defaults to 200 only
+ items:
+ description: HTTPStatus defines the http
+ status code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ method:
+ description: |-
+ Method defines the HTTP method used for health checking.
+ Defaults to GET
+ type: string
+ path:
+ description: Path defines the HTTP path that
+ will be requested during health checking.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - path
+ type: object
+ interval:
+ default: 3s
+ description: Interval defines the time between
+ active health checks.
+ format: duration
+ type: string
+ tcp:
+ description: |-
+ TCP defines the configuration of tcp health checker.
+ It's required while the health checker type is TCP.
+ properties:
+ receive:
+ description: Receive defines the expected
+ response payload.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of
+ the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ send:
+ description: Send defines the request payload.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of
+ the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ type: object
+ timeout:
+ default: 1s
+ description: Timeout defines the time to wait
+ for a health check response.
+ format: duration
+ type: string
+ type:
+ allOf:
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ description: Type defines the type of health checker.
+ type: string
+ unhealthyThreshold:
+ default: 3
+ description: UnhealthyThreshold defines the number
+ of unhealthy health checks required before a
+ backend host is marked unhealthy.
+ format: int32
+ minimum: 1
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If Health Checker type is HTTP, http field
+ needs to be set.
+ rule: 'self.type == ''HTTP'' ? has(self.http) :
+ !has(self.http)'
+ - message: If Health Checker type is TCP, tcp field
+ needs to be set.
+ rule: 'self.type == ''TCP'' ? has(self.tcp) : !has(self.tcp)'
+ - message: The grpc field can only be set if the Health
+ Checker type is GRPC.
+ rule: 'has(self.grpc) ? self.type == ''GRPC'' :
+ true'
+ passive:
+ description: Passive passive check configuration
+ properties:
+ baseEjectionTime:
+ default: 30s
+ description: BaseEjectionTime defines the base
+ duration for which a host will be ejected on
+ consecutive failures.
+ format: duration
+ type: string
+ consecutive5XxErrors:
+ default: 5
+ description: Consecutive5xxErrors sets the number
+ of consecutive 5xx errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveGatewayErrors:
+ default: 0
+ description: ConsecutiveGatewayErrors sets the
+ number of consecutive gateway errors triggering
+ ejection.
+ format: int32
+ type: integer
+ consecutiveLocalOriginFailures:
+ default: 5
+ description: |-
+ ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection.
+ Parameter takes effect only when split_external_local_origin_errors is set to true.
+ format: int32
+ type: integer
+ interval:
+ default: 3s
+ description: Interval defines the time between
+ passive health checks.
+ format: duration
+ type: string
+ maxEjectionPercent:
+ default: 10
+ description: MaxEjectionPercent sets the maximum
+ percentage of hosts in a cluster that can be
+ ejected.
+ format: int32
+ type: integer
+ splitExternalLocalOriginErrors:
+ default: false
+ description: SplitExternalLocalOriginErrors enables
+ splitting of errors between external and local
+ origin.
+ type: boolean
+ type: object
+ type: object
+ http2:
+ description: HTTP2 provides HTTP/2 configuration for backend
+ connections.
+ properties:
+ initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
+ If not set, the default value is 1 MiB.
+ x-kubernetes-int-or-string: true
+ initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
+ If not set, the default value is 64 KiB(64*1024).
+ x-kubernetes-int-or-string: true
+ maxConcurrentStreams:
+ description: |-
+ MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
+ If not set, the default value is 100.
+ format: int32
+ maximum: 2147483647
+ minimum: 1
+ type: integer
+ onInvalidMessage:
+ description: |-
+ OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
+ It's recommended for L2 Envoy deployments to set this value to TerminateStream.
+ https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
+ Default: TerminateConnection
+ type: string
+ type: object
+ loadBalancer:
+ description: |-
+ LoadBalancer policy to apply when routing traffic from the gateway to
+ the backend endpoints. Defaults to `LeastRequest`.
+ properties:
+ consistentHash:
+ description: |-
+ ConsistentHash defines the configuration when the load balancer type is
+ set to ConsistentHash
+ properties:
+ cookie:
+ description: Cookie configures the cookie hash
+ policy when the consistent hash type is set
+ to Cookie.
+ properties:
+ attributes:
+ additionalProperties:
+ type: string
+ description: Additional Attributes to set
+ for the generated cookie.
+ type: object
+ name:
+ description: |-
+ Name of the cookie to hash.
+ If this cookie does not exist in the request, Envoy will generate a cookie and set
+ the TTL on the response back to the client based on Layer 4
+ attributes of the backend endpoint, to ensure that these future requests
+ go to the same backend endpoint. Make sure to set the TTL field for this case.
+ type: string
+ ttl:
+ description: |-
+ TTL of the generated cookie if the cookie is not present. This value sets the
+ Max-Age attribute value.
+ type: string
+ required:
+ - name
+ type: object
+ header:
+ description: Header configures the header hash
+ policy when the consistent hash type is set
+ to Header.
+ properties:
+ name:
+ description: Name of the header to hash.
+ type: string
+ required:
+ - name
+ type: object
+ tableSize:
+ default: 65537
+ description: The table size for consistent hashing,
+ must be prime number limited to 5000011.
+ format: int64
+ maximum: 5000011
+ minimum: 2
+ type: integer
+ type:
+ description: |-
+ ConsistentHashType defines the type of input to hash on. Valid Type values are
+ "SourceIP",
+ "Header",
+ "Cookie".
+ enum:
+ - SourceIP
+ - Header
+ - Cookie
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If consistent hash type is header, the
+ header field must be set.
+ rule: 'self.type == ''Header'' ? has(self.header)
+ : !has(self.header)'
+ - message: If consistent hash type is cookie, the
+ cookie field must be set.
+ rule: 'self.type == ''Cookie'' ? has(self.cookie)
+ : !has(self.cookie)'
+ slowStart:
+ description: |-
+ SlowStart defines the configuration related to the slow start load balancer policy.
+ If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently this is only supported for RoundRobin and LeastRequest load balancers
+ properties:
+ window:
+ description: |-
+ Window defines the duration of the warm up period for newly added host.
+ During slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently only supports linear growth of traffic. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig
+ type: string
+ required:
+ - window
+ type: object
+ type:
+ description: |-
+ Type decides the type of Load Balancer policy.
+ Valid LoadBalancerType values are
+ "ConsistentHash",
+ "LeastRequest",
+ "Random",
+ "RoundRobin".
+ enum:
+ - ConsistentHash
+ - LeastRequest
+ - Random
+ - RoundRobin
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If LoadBalancer type is consistentHash, consistentHash
+ field needs to be set.
+ rule: 'self.type == ''ConsistentHash'' ? has(self.consistentHash)
+ : !has(self.consistentHash)'
+ - message: Currently SlowStart is only supported for RoundRobin
+ and LeastRequest load balancers.
+ rule: 'self.type in [''Random'', ''ConsistentHash'']
+ ? !has(self.slowStart) : true '
+ proxyProtocol:
+ description: ProxyProtocol enables the Proxy Protocol
+ when communicating with the backend.
+ properties:
+ version:
+ description: |-
+ Version of ProxyProtol
+ Valid ProxyProtocolVersion values are
+ "V1"
+ "V2"
+ enum:
+ - V1
+ - V2
+ type: string
+ required:
+ - version
+ type: object
+ tcpKeepalive:
+ description: |-
+ TcpKeepalive settings associated with the upstream client connection.
+ Disabled by default.
+ properties:
+ idleTime:
+ description: |-
+ The duration a connection needs to be idle before keep-alive
+ probes start being sent.
+ The duration format is
+ Defaults to `7200s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ interval:
+ description: |-
+ The duration between keep-alive probes.
+ Defaults to `75s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ probes:
+ description: |-
+ The total number of unacknowledged probes to send before deciding
+ the connection is dead.
+ Defaults to 9.
+ format: int32
+ type: integer
+ type: object
+ timeout:
+ description: Timeout settings for the backend connections.
+ properties:
+ http:
+ description: Timeout settings for HTTP.
+ properties:
+ connectionIdleTimeout:
+ description: |-
+ The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
+ Default: 1 hour.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ maxConnectionDuration:
+ description: |-
+ The maximum duration of an HTTP connection.
+ Default: unlimited.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ tcp:
+ description: Timeout settings for TCP.
+ properties:
+ connectTimeout:
+ description: |-
+ The timeout for network connection establishment, including TCP and TLS handshakes.
+ Default: 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ type: object
+ type: object
type: object
x-kubernetes-validations:
- message: backendRef or backendRefs needs to be set
rule: has(self.backendRef) || self.backendRefs.size() > 0
+ - message: BackendRefs must be used, backendRef is not supported.
+ rule: '!has(self.backendRef)'
+ - message: Exactly one backendRef can be specified in backendRefs.
+ rule: has(self.backendRefs) && self.backendRefs.size()==1
+ - message: BackendRefs only supports Service and Backend kind.
+ rule: 'has(self.backendRefs) ? self.backendRefs.all(f, f.kind
+ == ''Service'' || f.kind == ''Backend'') : true'
+ - message: BackendRefs only supports Core and gateway.envoyproxy.io
+ group.
+ rule: 'has(self.backendRefs) ? (self.backendRefs.all(f, f.group
+ == "" || f.group == ''gateway.envoyproxy.io'')) : true'
headersToExtAuth:
description: |-
HeadersToExtAuth defines the client request headers that will be included
@@ -456,7 +1072,6 @@ spec:
description: |-
BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
- Only Service kind is supported for now.
Deprecated: Use BackendRefs instead.
@@ -538,11 +1153,19 @@ spec:
description: |-
BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
- Only Service kind is supported for now.
items:
description: BackendRef defines how an ObjectReference that
is specific to BackendRef.
properties:
+ failover:
+ description: |-
+ Failover This indicates whether the backend is designated as a failover.
+ Multiple failover backends can be configured.
+ It is highly recommended to configure active or passive health checks to ensure that failover can be detected
+ when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again.
+ The overprovisioning factor is set to 1.4, meaning the failover backends will only start receiving traffic when
+ the health of the active backends falls below 72%.
+ type: boolean
group:
default: ""
description: |-
@@ -616,13 +1239,611 @@ spec:
- message: Must have port for Service reference
rule: '(size(self.group) == 0 && self.kind == ''Service'')
? has(self.port) : true'
- maxItems: 1
+ maxItems: 16
type: array
- x-kubernetes-validations:
- - message: only support Service kind.
- rule: self.all(f, f.kind == 'Service')
- - message: BackendRefs only supports Core group.
- rule: self.all(f, f.group == '')
+ backendSettings:
+ description: |-
+ BackendSettings holds configuration for managing the connection
+ to the backend.
+ properties:
+ circuitBreaker:
+ description: |-
+ Circuit Breaker settings for the upstream connections and requests.
+ If not set, circuit breakers will be enabled with the default thresholds
+ properties:
+ maxConnections:
+ default: 1024
+ description: The maximum number of connections that
+ Envoy will establish to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRequests:
+ default: 1024
+ description: The maximum number of parallel requests
+ that Envoy will make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxParallelRetries:
+ default: 1024
+ description: The maximum number of parallel retries
+ that Envoy will make to the referenced backend defined
+ within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxPendingRequests:
+ default: 1024
+ description: The maximum number of pending requests
+ that Envoy will queue to the referenced backend
+ defined within a xRoute rule.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ maxRequestsPerConnection:
+ description: |-
+ The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
+ Default: unlimited.
+ format: int64
+ maximum: 4294967295
+ minimum: 0
+ type: integer
+ type: object
+ connection:
+ description: Connection includes backend connection settings.
+ properties:
+ bufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
+ BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
+ If unspecified, an implementation defined default is applied (32768 bytes).
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note: that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ socketBufferLimit:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket
+ to backend.
+ SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space.
+ For example, 20Mi, 1Gi, 256Ki etc.
+ Note that when the suffix is not provided, the value is interpreted as bytes.
+ x-kubernetes-int-or-string: true
+ type: object
+ dns:
+ description: DNS includes dns resolution settings.
+ properties:
+ dnsRefreshRate:
+ description: |-
+ DNSRefreshRate specifies the rate at which DNS records should be refreshed.
+ Defaults to 30 seconds.
+ type: string
+ respectDnsTtl:
+ description: |-
+ RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
+ If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
+ Defaults to true.
+ type: boolean
+ type: object
+ healthCheck:
+ description: HealthCheck allows gateway to perform active
+ health checking on backends.
+ properties:
+ active:
+ description: Active health check configuration
+ properties:
+ grpc:
+ description: |-
+ GRPC defines the configuration of the GRPC health checker.
+ It's optional, and can only be used if the specified type is GRPC.
+ properties:
+ service:
+ description: |-
+ Service to send in the health check request.
+ If this is not specified, then the health check request applies to the entire
+ server and not to a specific service.
+ type: string
+ type: object
+ healthyThreshold:
+ default: 1
+ description: HealthyThreshold defines the number
+ of healthy health checks required before a backend
+ host is marked healthy.
+ format: int32
+ minimum: 1
+ type: integer
+ http:
+ description: |-
+ HTTP defines the configuration of http health checker.
+ It's required while the health checker type is HTTP.
+ properties:
+ expectedResponse:
+ description: ExpectedResponse defines a list
+ of HTTP expected responses to match.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of
+ the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ expectedStatuses:
+ description: |-
+ ExpectedStatuses defines a list of HTTP response statuses considered healthy.
+ Defaults to 200 only
+ items:
+ description: HTTPStatus defines the http
+ status code.
+ exclusiveMaximum: true
+ maximum: 600
+ minimum: 100
+ type: integer
+ type: array
+ method:
+ description: |-
+ Method defines the HTTP method used for health checking.
+ Defaults to GET
+ type: string
+ path:
+ description: Path defines the HTTP path that
+ will be requested during health checking.
+ maxLength: 1024
+ minLength: 1
+ type: string
+ required:
+ - path
+ type: object
+ interval:
+ default: 3s
+ description: Interval defines the time between
+ active health checks.
+ format: duration
+ type: string
+ tcp:
+ description: |-
+ TCP defines the configuration of tcp health checker.
+ It's required while the health checker type is TCP.
+ properties:
+ receive:
+ description: Receive defines the expected
+ response payload.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of
+ the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ send:
+ description: Send defines the request payload.
+ properties:
+ binary:
+ description: Binary payload base64 encoded.
+ format: byte
+ type: string
+ text:
+ description: Text payload in plain text.
+ type: string
+ type:
+ allOf:
+ - enum:
+ - Text
+ - Binary
+ - enum:
+ - Text
+ - Binary
+ description: Type defines the type of
+ the payload.
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If payload type is Text, text field
+ needs to be set.
+ rule: 'self.type == ''Text'' ? has(self.text)
+ : !has(self.text)'
+ - message: If payload type is Binary, binary
+ field needs to be set.
+ rule: 'self.type == ''Binary'' ? has(self.binary)
+ : !has(self.binary)'
+ type: object
+ timeout:
+ default: 1s
+ description: Timeout defines the time to wait
+ for a health check response.
+ format: duration
+ type: string
+ type:
+ allOf:
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ - enum:
+ - HTTP
+ - TCP
+ - GRPC
+ description: Type defines the type of health checker.
+ type: string
+ unhealthyThreshold:
+ default: 3
+ description: UnhealthyThreshold defines the number
+ of unhealthy health checks required before a
+ backend host is marked unhealthy.
+ format: int32
+ minimum: 1
+ type: integer
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If Health Checker type is HTTP, http field
+ needs to be set.
+ rule: 'self.type == ''HTTP'' ? has(self.http) :
+ !has(self.http)'
+ - message: If Health Checker type is TCP, tcp field
+ needs to be set.
+ rule: 'self.type == ''TCP'' ? has(self.tcp) : !has(self.tcp)'
+ - message: The grpc field can only be set if the Health
+ Checker type is GRPC.
+ rule: 'has(self.grpc) ? self.type == ''GRPC'' :
+ true'
+ passive:
+ description: Passive passive check configuration
+ properties:
+ baseEjectionTime:
+ default: 30s
+ description: BaseEjectionTime defines the base
+ duration for which a host will be ejected on
+ consecutive failures.
+ format: duration
+ type: string
+ consecutive5XxErrors:
+ default: 5
+ description: Consecutive5xxErrors sets the number
+ of consecutive 5xx errors triggering ejection.
+ format: int32
+ type: integer
+ consecutiveGatewayErrors:
+ default: 0
+ description: ConsecutiveGatewayErrors sets the
+ number of consecutive gateway errors triggering
+ ejection.
+ format: int32
+ type: integer
+ consecutiveLocalOriginFailures:
+ default: 5
+ description: |-
+ ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection.
+ Parameter takes effect only when split_external_local_origin_errors is set to true.
+ format: int32
+ type: integer
+ interval:
+ default: 3s
+ description: Interval defines the time between
+ passive health checks.
+ format: duration
+ type: string
+ maxEjectionPercent:
+ default: 10
+ description: MaxEjectionPercent sets the maximum
+ percentage of hosts in a cluster that can be
+ ejected.
+ format: int32
+ type: integer
+ splitExternalLocalOriginErrors:
+ default: false
+ description: SplitExternalLocalOriginErrors enables
+ splitting of errors between external and local
+ origin.
+ type: boolean
+ type: object
+ type: object
+ http2:
+ description: HTTP2 provides HTTP/2 configuration for backend
+ connections.
+ properties:
+ initialConnectionWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
+ If not set, the default value is 1 MiB.
+ x-kubernetes-int-or-string: true
+ initialStreamWindowSize:
+ allOf:
+ - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$
+ anyOf:
+ - type: integer
+ - type: string
+ description: |-
+ InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
+ If not set, the default value is 64 KiB(64*1024).
+ x-kubernetes-int-or-string: true
+ maxConcurrentStreams:
+ description: |-
+ MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
+ If not set, the default value is 100.
+ format: int32
+ maximum: 2147483647
+ minimum: 1
+ type: integer
+ onInvalidMessage:
+ description: |-
+ OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
+ It's recommended for L2 Envoy deployments to set this value to TerminateStream.
+ https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
+ Default: TerminateConnection
+ type: string
+ type: object
+ loadBalancer:
+ description: |-
+ LoadBalancer policy to apply when routing traffic from the gateway to
+ the backend endpoints. Defaults to `LeastRequest`.
+ properties:
+ consistentHash:
+ description: |-
+ ConsistentHash defines the configuration when the load balancer type is
+ set to ConsistentHash
+ properties:
+ cookie:
+ description: Cookie configures the cookie hash
+ policy when the consistent hash type is set
+ to Cookie.
+ properties:
+ attributes:
+ additionalProperties:
+ type: string
+ description: Additional Attributes to set
+ for the generated cookie.
+ type: object
+ name:
+ description: |-
+ Name of the cookie to hash.
+ If this cookie does not exist in the request, Envoy will generate a cookie and set
+ the TTL on the response back to the client based on Layer 4
+ attributes of the backend endpoint, to ensure that these future requests
+ go to the same backend endpoint. Make sure to set the TTL field for this case.
+ type: string
+ ttl:
+ description: |-
+ TTL of the generated cookie if the cookie is not present. This value sets the
+ Max-Age attribute value.
+ type: string
+ required:
+ - name
+ type: object
+ header:
+ description: Header configures the header hash
+ policy when the consistent hash type is set
+ to Header.
+ properties:
+ name:
+ description: Name of the header to hash.
+ type: string
+ required:
+ - name
+ type: object
+ tableSize:
+ default: 65537
+ description: The table size for consistent hashing,
+ must be prime number limited to 5000011.
+ format: int64
+ maximum: 5000011
+ minimum: 2
+ type: integer
+ type:
+ description: |-
+ ConsistentHashType defines the type of input to hash on. Valid Type values are
+ "SourceIP",
+ "Header",
+ "Cookie".
+ enum:
+ - SourceIP
+ - Header
+ - Cookie
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If consistent hash type is header, the
+ header field must be set.
+ rule: 'self.type == ''Header'' ? has(self.header)
+ : !has(self.header)'
+ - message: If consistent hash type is cookie, the
+ cookie field must be set.
+ rule: 'self.type == ''Cookie'' ? has(self.cookie)
+ : !has(self.cookie)'
+ slowStart:
+ description: |-
+ SlowStart defines the configuration related to the slow start load balancer policy.
+ If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently this is only supported for RoundRobin and LeastRequest load balancers
+ properties:
+ window:
+ description: |-
+ Window defines the duration of the warm up period for newly added host.
+ During slow start window, traffic sent to the newly added hosts will gradually increase.
+ Currently only supports linear growth of traffic. For additional details,
+ see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig
+ type: string
+ required:
+ - window
+ type: object
+ type:
+ description: |-
+ Type decides the type of Load Balancer policy.
+ Valid LoadBalancerType values are
+ "ConsistentHash",
+ "LeastRequest",
+ "Random",
+ "RoundRobin".
+ enum:
+ - ConsistentHash
+ - LeastRequest
+ - Random
+ - RoundRobin
+ type: string
+ required:
+ - type
+ type: object
+ x-kubernetes-validations:
+ - message: If LoadBalancer type is consistentHash, consistentHash
+ field needs to be set.
+ rule: 'self.type == ''ConsistentHash'' ? has(self.consistentHash)
+ : !has(self.consistentHash)'
+ - message: Currently SlowStart is only supported for RoundRobin
+ and LeastRequest load balancers.
+ rule: 'self.type in [''Random'', ''ConsistentHash'']
+ ? !has(self.slowStart) : true '
+ proxyProtocol:
+ description: ProxyProtocol enables the Proxy Protocol
+ when communicating with the backend.
+ properties:
+ version:
+ description: |-
+ Version of ProxyProtol
+ Valid ProxyProtocolVersion values are
+ "V1"
+ "V2"
+ enum:
+ - V1
+ - V2
+ type: string
+ required:
+ - version
+ type: object
+ tcpKeepalive:
+ description: |-
+ TcpKeepalive settings associated with the upstream client connection.
+ Disabled by default.
+ properties:
+ idleTime:
+ description: |-
+ The duration a connection needs to be idle before keep-alive
+ probes start being sent.
+ The duration format is
+ Defaults to `7200s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ interval:
+ description: |-
+ The duration between keep-alive probes.
+ Defaults to `75s`.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ probes:
+ description: |-
+ The total number of unacknowledged probes to send before deciding
+ the connection is dead.
+ Defaults to 9.
+ format: int32
+ type: integer
+ type: object
+ timeout:
+ description: Timeout settings for the backend connections.
+ properties:
+ http:
+ description: Timeout settings for HTTP.
+ properties:
+ connectionIdleTimeout:
+ description: |-
+ The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.
+ Default: 1 hour.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ maxConnectionDuration:
+ description: |-
+ The maximum duration of an HTTP connection.
+ Default: unlimited.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ tcp:
+ description: Timeout settings for TCP.
+ properties:
+ connectTimeout:
+ description: |-
+ The timeout for network connection establishment, including TCP and TLS handshakes.
+ Default: 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
+ type: string
+ type: object
+ type: object
+ type: object
headersToBackend:
description: |-
HeadersToBackend are the authorization response headers that will be added
@@ -643,6 +1864,17 @@ spec:
x-kubernetes-validations:
- message: backendRef or backendRefs needs to be set
rule: has(self.backendRef) || self.backendRefs.size() > 0
+ - message: BackendRefs must be used, backendRef is not supported.
+ rule: '!has(self.backendRef)'
+ - message: Exactly one backendRef can be specified in backendRefs.
+ rule: has(self.backendRefs) && self.backendRefs.size()==1
+ - message: BackendRefs only supports Service and Backend kind.
+ rule: 'has(self.backendRefs) ? self.backendRefs.all(f, f.kind
+ == ''Service'' || f.kind == ''Backend'') : true'
+ - message: BackendRefs only supports Core and gateway.envoyproxy.io
+ group.
+ rule: 'has(self.backendRefs) ? (self.backendRefs.all(f, f.group
+ == "" || f.group == ''gateway.envoyproxy.io'')) : true'
type: object
x-kubernetes-validations:
- message: one of grpc or http must be specified
@@ -650,24 +1882,6 @@ spec:
- message: only one of grpc or http can be specified
rule: (has(self.grpc) && !has(self.http)) || (!has(self.grpc) &&
has(self.http))
- - message: group is invalid, only the core API group (specified by
- omitting the group field or setting it to an empty string) is
- supported
- rule: 'has(self.grpc) ? (!has(self.grpc.backendRef) || !has(self.grpc.backendRef.group)
- || self.grpc.backendRef.group == "") : true'
- - message: kind is invalid, only Service (specified by omitting the
- kind field or setting it to 'Service') is supported
- rule: 'has(self.grpc) ? (!has(self.grpc.backendRef) || !has(self.grpc.backendRef.kind)
- || self.grpc.backendRef.kind == ''Service'') : true'
- - message: group is invalid, only the core API group (specified by
- omitting the group field or setting it to an empty string) is
- supported
- rule: 'has(self.http) ? (!has(self.http.backendRef) || !has(self.http.backendRef.group)
- || self.http.backendRef.group == "") : true'
- - message: kind is invalid, only Service (specified by omitting the
- kind field or setting it to 'Service') is supported
- rule: 'has(self.http) ? (!has(self.http.backendRef) || !has(self.http.backendRef.kind)
- || self.http.backendRef.kind == ''Service'') : true'
jwt:
description: JWT defines the configuration for JSON Web Token (JWT)
authentication.
diff --git a/examples/extension-server/cmd/extension-server/main.go b/examples/extension-server/cmd/extension-server/main.go
index 33e08ddc914..9df1f4a885c 100644
--- a/examples/extension-server/cmd/extension-server/main.go
+++ b/examples/extension-server/cmd/extension-server/main.go
@@ -13,11 +13,11 @@ import (
"os/signal"
"syscall"
- pb "github.com/envoyproxy/gateway/proto/extension"
+ "github.com/exampleorg/envoygateway-extension/internal/extensionserver"
"github.com/urfave/cli/v2"
"google.golang.org/grpc"
- "github.com/exampleorg/envoygateway-extension/internal/extensionserver"
+ pb "github.com/envoyproxy/gateway/proto/extension"
)
func main() {
diff --git a/examples/extension-server/go.mod b/examples/extension-server/go.mod
index a1c8e2fc44c..df377d5e338 100644
--- a/examples/extension-server/go.mod
+++ b/examples/extension-server/go.mod
@@ -9,7 +9,7 @@ require (
google.golang.org/grpc v1.65.0
google.golang.org/protobuf v1.34.2
k8s.io/apimachinery v0.30.3
- sigs.k8s.io/controller-runtime v0.18.4
+ sigs.k8s.io/controller-runtime v0.18.5
sigs.k8s.io/gateway-api v1.1.0
)
@@ -29,11 +29,11 @@ require (
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
- golang.org/x/net v0.27.0 // indirect
- golang.org/x/sys v0.22.0 // indirect
- golang.org/x/text v0.16.0 // indirect
+ golang.org/x/net v0.28.0 // indirect
+ golang.org/x/sys v0.24.0 // indirect
+ golang.org/x/text v0.17.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20240805194559-2c9e96a0b5d4 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
diff --git a/examples/extension-server/go.sum b/examples/extension-server/go.sum
index e6a6ba81bb1..fc7d8df4b19 100644
--- a/examples/extension-server/go.sum
+++ b/examples/extension-server/go.sum
@@ -76,34 +76,34 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
-golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
+golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
+golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
-golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
+golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
-golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
+golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
+golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
-golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
+golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
+golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0=
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240805194559-2c9e96a0b5d4 h1:OsSGQeIIsyOEOimVxLEIL4rwGcnrjOydQaiA2bOnZUM=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240805194559-2c9e96a0b5d4/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
@@ -126,8 +126,8 @@ k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak=
k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
-sigs.k8s.io/controller-runtime v0.18.4 h1:87+guW1zhvuPLh1PHybKdYFLU0YJp4FhJRmiHvm5BZw=
-sigs.k8s.io/controller-runtime v0.18.4/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg=
+sigs.k8s.io/controller-runtime v0.18.5 h1:nTHio/W+Q4aBlQMgbnC5hZb4IjIidyrizMai9P6n4Rk=
+sigs.k8s.io/controller-runtime v0.18.5/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg=
sigs.k8s.io/gateway-api v1.1.0 h1:DsLDXCi6jR+Xz8/xd0Z1PYl2Pn0TyaFMOPPZIj4inDM=
sigs.k8s.io/gateway-api v1.1.0/go.mod h1:ZH4lHrL2sDi0FHZ9jjneb8kKnGzFWyrTya35sWUTrRs=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
diff --git a/examples/extension-server/internal/extensionserver/server.go b/examples/extension-server/internal/extensionserver/server.go
index a2776a9f966..2c060869b88 100644
--- a/examples/extension-server/internal/extensionserver/server.go
+++ b/examples/extension-server/internal/extensionserver/server.go
@@ -11,15 +11,15 @@ import (
"fmt"
"log/slog"
- pb "github.com/envoyproxy/gateway/proto/extension"
corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
listenerv3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
bav3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/basic_auth/v3"
hcm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
"github.com/envoyproxy/go-control-plane/pkg/wellknown"
+ "github.com/exampleorg/envoygateway-extension/api/v1alpha1"
"google.golang.org/protobuf/types/known/anypb"
- "github.com/exampleorg/envoygateway-extension/api/v1alpha1"
+ pb "github.com/envoyproxy/gateway/proto/extension"
)
type Server struct {
diff --git a/go.mod b/go.mod
index e66adb8a3db..b6a37be1e63 100644
--- a/go.mod
+++ b/go.mod
@@ -5,12 +5,12 @@ go 1.22.5
replace github.com/imdario/mergo => github.com/imdario/mergo v0.3.16
require (
- fortio.org/fortio v1.66.0
+ fortio.org/fortio v1.66.1
fortio.org/log v1.16.0
github.com/Masterminds/semver/v3 v3.2.1
github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
- github.com/docker/cli v27.1.1+incompatible
+ github.com/docker/cli v27.1.2+incompatible
github.com/dominikbraun/graph v0.23.0
github.com/envoyproxy/go-control-plane v0.12.1-0.20240612043845-c54ec4ce422d
github.com/envoyproxy/ratelimit v1.4.1-0.20230427142404-e2a87f41d3a7
@@ -23,11 +23,12 @@ require (
github.com/golang/protobuf v1.5.4
github.com/google/cel-go v0.21.0
github.com/google/go-cmp v0.6.0
- github.com/google/go-containerregistry v0.20.1
+ github.com/google/go-containerregistry v0.20.2
github.com/grafana/tempo v1.5.0
github.com/hashicorp/go-multierror v1.1.1
github.com/miekg/dns v1.1.61
- github.com/prometheus/client_golang v1.19.1
+ github.com/ohler55/ojg v1.24.0
+ github.com/prometheus/client_golang v1.20.0
github.com/prometheus/common v0.55.0
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
@@ -43,12 +44,12 @@ require (
go.opentelemetry.io/otel/sdk/metric v1.28.0
go.opentelemetry.io/proto/otlp v1.3.1
go.uber.org/zap v1.27.0
- golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8
- golang.org/x/sys v0.22.0
+ golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
+ golang.org/x/sys v0.24.0
google.golang.org/grpc v1.65.0
google.golang.org/protobuf v1.34.2
gopkg.in/yaml.v3 v3.0.1
- helm.sh/helm/v3 v3.15.3
+ helm.sh/helm/v3 v3.15.4
k8s.io/api v0.30.3
k8s.io/apiextensions-apiserver v0.30.3
k8s.io/apimachinery v0.30.3
@@ -56,7 +57,7 @@ require (
k8s.io/client-go v0.30.3
k8s.io/kubectl v0.30.3
k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0
- sigs.k8s.io/controller-runtime v0.18.4
+ sigs.k8s.io/controller-runtime v0.18.5
sigs.k8s.io/gateway-api v1.1.0
sigs.k8s.io/mcs-api v0.1.0
sigs.k8s.io/yaml v1.4.0
@@ -64,7 +65,7 @@ require (
require (
github.com/docker/docker v27.1.1+incompatible
- github.com/replicatedhq/troubleshoot v0.98.0
+ github.com/replicatedhq/troubleshoot v0.99.0
)
require (
@@ -75,10 +76,10 @@ require (
cloud.google.com/go/storage v1.40.0 // indirect
dario.cat/mergo v1.0.0 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
- fortio.org/cli v1.7.0 // indirect
+ fortio.org/cli v1.8.0 // indirect
fortio.org/dflag v1.7.2 // indirect
fortio.org/scli v1.15.1 // indirect
- fortio.org/sets v1.1.1 // indirect
+ fortio.org/sets v1.2.0 // indirect
fortio.org/struct2env v0.4.1 // indirect
fortio.org/version v1.0.4 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
@@ -87,7 +88,7 @@ require (
github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/Masterminds/squirrel v1.5.4 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
- github.com/Microsoft/hcsshim v0.12.3 // indirect
+ github.com/Microsoft/hcsshim v0.12.5 // indirect
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/apparentlymart/go-cidr v1.1.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
@@ -95,18 +96,19 @@ require (
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/c9s/goprocinfo v0.0.0-20170724085704-0010a05ce49f // indirect
- github.com/cilium/ebpf v0.11.0 // indirect
+ github.com/cilium/ebpf v0.16.0 // indirect
github.com/containerd/cgroups/v3 v3.0.3 // indirect
- github.com/containerd/containerd v1.7.17 // indirect
+ github.com/containerd/containerd v1.7.20 // indirect
github.com/containerd/errdefs v0.1.0 // indirect
github.com/containerd/log v0.1.0 // indirect
+ github.com/containerd/platforms v0.2.1 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect
- github.com/containers/image/v5 v5.31.1 // indirect
+ github.com/containers/image/v5 v5.32.1 // indirect
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect
- github.com/containers/ocicrypt v1.1.10 // indirect
- github.com/containers/storage v1.54.0 // indirect
+ github.com/containers/ocicrypt v1.2.0 // indirect
+ github.com/containers/storage v1.55.0 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
- github.com/cyphar/filepath-securejoin v0.2.5 // indirect
+ github.com/cyphar/filepath-securejoin v0.3.1 // indirect
github.com/distribution/distribution/v3 v3.0.0-beta.1 // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
@@ -142,7 +144,7 @@ require (
github.com/jackc/pgx/v5 v5.6.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jmoiron/sqlx v1.3.5 // indirect
- github.com/klauspost/compress v1.17.8 // indirect
+ github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect
github.com/kortschak/goroutine v1.1.2 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
@@ -153,7 +155,7 @@ require (
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
- github.com/mattn/go-runewidth v0.0.15 // indirect
+ github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/microsoft/go-mssqldb v1.7.2 // indirect
github.com/mistifyio/go-zfs/v3 v3.0.1 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
@@ -164,9 +166,9 @@ require (
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/locker v1.0.1 // indirect
github.com/moby/patternmatcher v0.6.0 // indirect
- github.com/moby/sys/mountinfo v0.7.1 // indirect
+ github.com/moby/sys/mountinfo v0.7.2 // indirect
github.com/moby/sys/sequential v0.5.0 // indirect
- github.com/moby/sys/user v0.1.0 // indirect
+ github.com/moby/sys/user v0.2.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0 // indirect
github.com/opencontainers/runtime-spec v1.2.0 // indirect
@@ -189,7 +191,7 @@ require (
github.com/spf13/viper v1.19.0 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
- github.com/sylabs/sif/v2 v2.16.0 // indirect
+ github.com/sylabs/sif/v2 v2.18.0 // indirect
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
github.com/tchap/go-patricia/v2 v2.3.1 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
@@ -204,8 +206,8 @@ require (
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
- golang.org/x/crypto v0.25.0 // indirect
- golang.org/x/crypto/x509roots/fallback v0.0.0-20240626151235-a6a393ffd658 // indirect
+ golang.org/x/crypto v0.26.0 // indirect
+ golang.org/x/crypto/x509roots/fallback v0.0.0-20240806160748-b2d3a6a4b4d3 // indirect
google.golang.org/api v0.172.0 // indirect
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
@@ -213,7 +215,7 @@ require (
k8s.io/apiserver v0.30.3 // indirect
k8s.io/kubelet v0.30.3 // indirect
k8s.io/metrics v0.30.3 // indirect
- oras.land/oras-go v1.2.5 // indirect
+ oras.land/oras-go v1.2.6 // indirect
periph.io/x/host/v3 v3.8.2 // indirect
)
@@ -274,17 +276,17 @@ require (
go.opentelemetry.io/otel/trace v1.28.0 // indirect
go.starlark.net v0.0.0-20240520160348-046347dcd104 // indirect
go.uber.org/multierr v1.11.0 // indirect
- golang.org/x/mod v0.19.0 // indirect
- golang.org/x/net v0.27.0
- golang.org/x/oauth2 v0.21.0 // indirect
- golang.org/x/sync v0.7.0 // indirect
- golang.org/x/term v0.22.0 // indirect
- golang.org/x/text v0.16.0 // indirect
+ golang.org/x/mod v0.20.0 // indirect
+ golang.org/x/net v0.28.0
+ golang.org/x/oauth2 v0.22.0 // indirect
+ golang.org/x/sync v0.8.0 // indirect
+ golang.org/x/term v0.23.0 // indirect
+ golang.org/x/text v0.17.0 // indirect
golang.org/x/time v0.5.0 // indirect
- golang.org/x/tools v0.22.0 // indirect
+ golang.org/x/tools v0.23.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20240805194559-2c9e96a0b5d4 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/component-base v0.30.3 // indirect
diff --git a/go.sum b/go.sum
index ed3fe16fab6..42ae9448cf4 100644
--- a/go.sum
+++ b/go.sum
@@ -191,18 +191,18 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
fortio.org/assert v1.2.1 h1:48I39urpeDj65RP1KguF7akCjILNeu6vICiYMEysR7Q=
fortio.org/assert v1.2.1/go.mod h1:039mG+/iYDPO8Ibx8TrNuJCm2T2SuhwRI3uL9nHTTls=
-fortio.org/cli v1.7.0 h1:w+uXZLGi4t3Vn/BvbeMuSw84Z1pvNPG9HqeGfpP68cc=
-fortio.org/cli v1.7.0/go.mod h1:s4vxWz7P7T4cYOWdMF0NA693Nu1gK9OW4KoDj54/Do4=
+fortio.org/cli v1.8.0 h1:Mz1phmUwkQaXESGb1nIWBY+CHli/GYIlhwpktorh9sY=
+fortio.org/cli v1.8.0/go.mod h1:pk/JBE8LcXtNuo5Yj2bLsVbwPaHo8NWdbstSN0cpbFk=
fortio.org/dflag v1.7.2 h1:lUhXFvDlw4CJj/q7hPv/TC+n/wVoQylzQO6bUg5GQa0=
fortio.org/dflag v1.7.2/go.mod h1:6yO/NIgrWfQH195WbHJ3Y45SCx11ffivQjfx2C/FS1U=
-fortio.org/fortio v1.66.0 h1:9F/200qIu136z847bxs/NeAoYdJaQlVofYlppi3qwcw=
-fortio.org/fortio v1.66.0/go.mod h1:eUl5MRscw6CiWAStai8aB3/8unxA9uNzJRXdhKEaq1s=
+fortio.org/fortio v1.66.1 h1:NiVVHUy/DkMoOA/oLJHs0slsTnm/h3ocLbSfvP6NXIc=
+fortio.org/fortio v1.66.1/go.mod h1:3qkJSza2B2PC8TVen78wIupHgnsXvlzUnSvgQfiKfUM=
fortio.org/log v1.16.0 h1:GhU8/9NkYZmEIzvTN/DTMedDAStLJraWUUVUA2EbNDc=
fortio.org/log v1.16.0/go.mod h1:t58Spg9njjymvRioh5F6qKGSupEsnMjXLGWIS1i3khE=
fortio.org/scli v1.15.1 h1:Upza50brpEZwUk8Nn2gdP4BjgqJZY3J+z7KLrrAzPjY=
fortio.org/scli v1.15.1/go.mod h1:9LOD4iPe9u73KeJGYC/Af1oFniOafO7oZ9VvwENMf/c=
-fortio.org/sets v1.1.1 h1:Q7Z1Ft2lpUc1N7bfI8HofIK0QskrOflfYRyKT2LzBng=
-fortio.org/sets v1.1.1/go.mod h1:J2BwIxNOLWsSU7IMZUg541kh3Au4JEKHrghVwXs68tE=
+fortio.org/sets v1.2.0 h1:FBfC7R2xrOJtkcioUbY6WqEzdujuBoZRbSdp1fYF4Kk=
+fortio.org/sets v1.2.0/go.mod h1:J2BwIxNOLWsSU7IMZUg541kh3Au4JEKHrghVwXs68tE=
fortio.org/struct2env v0.4.1 h1:rJludAMO5eBvpWplWEQNqoVDFZr4RWMQX7RUapgZyc0=
fortio.org/struct2env v0.4.1/go.mod h1:lENUe70UwA1zDUCX+8AsO663QCFqYaprk5lnPhjD410=
fortio.org/version v1.0.4 h1:FWUMpJ+hVTNc4RhvvOJzb0xesrlRmG/a+D6bjbQ4+5U=
@@ -252,8 +252,8 @@ github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8
github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
-github.com/Microsoft/hcsshim v0.12.3 h1:LS9NXqXhMoqNCplK1ApmVSfB4UnVLRDWRapB6EIlxE0=
-github.com/Microsoft/hcsshim v0.12.3/go.mod h1:Iyl1WVpZzr+UkzjekHZbV8o5Z9ZkxNGx6CtY2Qg/JVQ=
+github.com/Microsoft/hcsshim v0.12.5 h1:bpTInLlDy/nDRWFVcefDZZ1+U8tS+rz3MxjKgu9boo0=
+github.com/Microsoft/hcsshim v0.12.5/go.mod h1:tIUGego4G1EN5Hb6KC90aDYiUI2dqLSTTOCjVNpOgZ8=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
@@ -310,8 +310,8 @@ github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXH
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
-github.com/cilium/ebpf v0.11.0 h1:V8gS/bTCCjX9uUnkUFUpPsksM8n1lXBAvHcpiFk1X2Y=
-github.com/cilium/ebpf v0.11.0/go.mod h1:WE7CZAnqOL2RouJ4f1uyNhqr2P4CCvXFIqdRDUgWsVs=
+github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok=
+github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
@@ -327,24 +327,26 @@ github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1Ig
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0=
github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0=
-github.com/containerd/containerd v1.7.17 h1:KjNnn0+tAVQHAoaWRjmdak9WlvnFR/8rU1CHHy8Rm2A=
-github.com/containerd/containerd v1.7.17/go.mod h1:vK+hhT4TIv2uejlcDlbVIc8+h/BqtKLIyNrtCZol8lI=
+github.com/containerd/containerd v1.7.20 h1:Sl6jQYk3TRavaU83h66QMbI2Nqg9Jm6qzwX57Vsn1SQ=
+github.com/containerd/containerd v1.7.20/go.mod h1:52GsS5CwquuqPuLncsXwG0t2CiUce+KsNHJZQJvAgR0=
github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM=
github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
+github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
+github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU=
github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk=
-github.com/containers/image/v5 v5.31.1 h1:3x9soI6Biml/GiDLpkSmKrkRSwVGctxu/vONpoUdklA=
-github.com/containers/image/v5 v5.31.1/go.mod h1:5QfOqSackPkSbF7Qxc1DnVNnPJKQ+KWLkfEfDpK590Q=
+github.com/containers/image/v5 v5.32.1 h1:fVa7GxRC4BCPGsfSRs4JY12WyeY26SUYQ0NuANaCFrI=
+github.com/containers/image/v5 v5.32.1/go.mod h1:v1l73VeMugfj/QtKI+jhYbwnwFCFnNGckvbST3rQ5Hk=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
-github.com/containers/ocicrypt v1.1.10 h1:r7UR6o8+lyhkEywetubUUgcKFjOWOaWz8cEBrCPX0ic=
-github.com/containers/ocicrypt v1.1.10/go.mod h1:YfzSSr06PTHQwSTUKqDSjish9BeW1E4HUmreluQcMd8=
-github.com/containers/storage v1.54.0 h1:xwYAlf6n9OnIlURQLLg3FYHbO74fQ/2W2N6EtQEUM4I=
-github.com/containers/storage v1.54.0/go.mod h1:PlMOoinRrBSnhYODLxt4EXl0nmJt+X0kjG0Xdt9fMTw=
+github.com/containers/ocicrypt v1.2.0 h1:X14EgRK3xNFvJEfI5O4Qn4T3E25ANudSOZz/sirVuPM=
+github.com/containers/ocicrypt v1.2.0/go.mod h1:ZNviigQajtdlxIZGibvblVuIFBKIuUI2M0QM12SD31U=
+github.com/containers/storage v1.55.0 h1:wTWZ3YpcQf1F+dSP4KxG9iqDfpQY1otaUXjPpffuhgg=
+github.com/containers/storage v1.55.0/go.mod h1:28cB81IDk+y7ok60Of6u52RbCeBRucbFOeLunhER1RQ=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
@@ -364,8 +366,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
-github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo=
-github.com/cyphar/filepath-securejoin v0.2.5/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
+github.com/cyphar/filepath-securejoin v0.3.1 h1:1V7cHiaW+C+39wEfpH6XlLBQo3j/PciWFrgfCLS8XrE=
+github.com/cyphar/filepath-securejoin v0.3.1/go.mod h1:F7i41x/9cBF7lzCrVsYs9fuzwRZm4NQsGTBdpp6mETc=
github.com/datawire/dlib v1.3.0 h1:KkmyXU1kwm3oPBk1ypR70YbcOlEXWzEbx5RE0iRXTGk=
github.com/datawire/dlib v1.3.0/go.mod h1:NiGDmetmbkBvtznpWSx6C0vA0s0LK9aHna3LJDqjruk=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -380,8 +382,8 @@ github.com/distribution/distribution/v3 v3.0.0-beta.1 h1:X+ELTxPuZ1Xe5MsD3kp2wfG
github.com/distribution/distribution/v3 v3.0.0-beta.1/go.mod h1:O9O8uamhHzWWQVTjuQpyYUVm/ShPHPUDgvQMpHGVBDs=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
-github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE=
-github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+github.com/docker/cli v27.1.2+incompatible h1:nYviRv5Y+YAKx3dFrTvS1ErkyVVunKOhoweCTE1BsnI=
+github.com/docker/cli v27.1.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
@@ -529,6 +531,8 @@ github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
+github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
+github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
github.com/go-redis/redis/v7 v7.4.1 h1:PASvf36gyUpr2zdOUS/9Zqc80GbM+9BDyiJSJDDOrTI=
github.com/go-redis/redis/v7 v7.4.1/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
@@ -618,8 +622,8 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-containerregistry v0.20.1 h1:eTgx9QNYugV4DN5mz4U8hiAGTi1ybXn0TPi4Smd8du0=
-github.com/google/go-containerregistry v0.20.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI=
+github.com/google/go-containerregistry v0.20.2 h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l/DSArMxlbwseo=
+github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEvalZBqs6AoLeWfUy34nQC8=
github.com/google/go-intervals v0.0.2 h1:FGrVEiUnTRKR8yE04qzXYaJMtnIYqobR5QbblK3ixcM=
github.com/google/go-intervals v0.0.2/go.mod h1:MkaR3LNRfeKLPmqgJYs4E66z5InYjmCjbbr4TQlcT6Y=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -759,8 +763,12 @@ github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Cc
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
+github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
+github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
+github.com/jsimonetti/rtnetlink/v2 v2.0.1 h1:xda7qaHDSVOsADNouv7ukSuicKZO7GgVUCXxpaIEIlM=
+github.com/jsimonetti/rtnetlink/v2 v2.0.1/go.mod h1:7MoNYNbb3UaDHtF8udiJo/RH6VsTKP1pqKLUTVCvToE=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@@ -777,8 +785,8 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
-github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
-github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
+github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -834,12 +842,16 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
-github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
-github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
+github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g=
+github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
+github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
+github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
github.com/microsoft/go-mssqldb v1.7.2 h1:CHkFJiObW7ItKTJfHo1QX7QBBD1iV+mn1eOyRP3b/PA=
github.com/microsoft/go-mssqldb v1.7.2/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA=
github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs=
@@ -869,12 +881,12 @@ github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkV
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
-github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g=
-github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
+github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
+github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
-github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg=
-github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU=
+github.com/moby/sys/user v0.2.0 h1:OnpapJsRp25vkhw8TFG6OLJODNh/3rEwRWtJ3kakwRM=
+github.com/moby/sys/user v0.2.0/go.mod h1:RYstrcWOJpVh+6qzUqp2bU3eaRpdiQeKGlKitaH0PM8=
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -899,6 +911,8 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
+github.com/ohler55/ojg v1.24.0 h1:y2AVez6fPTszK/jPhaAYMCAzAoSleConMqSDD5wJKJg=
+github.com/ohler55/ojg v1.24.0/go.mod h1:gQhDVpQLqrmnd2eqGAvJtn+NfKoYJbe/A4Sj3/Vro4o=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
@@ -957,8 +971,8 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
-github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
-github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
+github.com/prometheus/client_golang v1.20.0 h1:jBzTZ7B099Rg24tny+qngoynol8LtVYlA2bqx3vEloI=
+github.com/prometheus/client_golang v1.20.0/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@@ -985,8 +999,8 @@ github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 h1:EfpWLLCyXw8PSM2/XNJLjI3Pb
github.com/redis/go-redis/extra/redisotel/v9 v9.0.5/go.mod h1:WZjPDy7VNzn77AAfnAfVjZNvfJTYfPetfZk5yoSTLaQ=
github.com/redis/go-redis/v9 v9.1.0 h1:137FnGdk+EQdCbye1FW+qOEcY5S+SpY9T0NiuqvtfMY=
github.com/redis/go-redis/v9 v9.1.0/go.mod h1:urWj3He21Dj5k4TK1y59xH8Uj6ATueP8AH1cY3lZl4c=
-github.com/replicatedhq/troubleshoot v0.98.0 h1:+R3rMV84sGr24/OOr9PHYt9NPXsZHB24/8N4IH1rJFI=
-github.com/replicatedhq/troubleshoot v0.98.0/go.mod h1:L+ocOIFN2a65xiXHQT57ythmXXw4mWkWwH4dfZJPJ8g=
+github.com/replicatedhq/troubleshoot v0.99.0 h1:KtsCe/8EL1VPQrokZw3bcKo8HcCTRUMEtUb2+SJ5l1k=
+github.com/replicatedhq/troubleshoot v0.99.0/go.mod h1:5rRx3kCUCX9Adl3ST1mzo57FICjIJMaIrkj3rTrzvv4=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
@@ -1077,8 +1091,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
-github.com/sylabs/sif/v2 v2.16.0 h1:2eqaBaQQsn5DZTzm3QZm0HupZQEjNXfxRnCmtyCihEU=
-github.com/sylabs/sif/v2 v2.16.0/go.mod h1:d5TxgD/mhMUU3kWLmZmWJQ99Wg0asaTP0bq3ezR1xpg=
+github.com/sylabs/sif/v2 v2.18.0 h1:eXugsS1qx7St2Wu/AJ21KnsQiVCpouPlTigABh+6KYI=
+github.com/sylabs/sif/v2 v2.18.0/go.mod h1:GOQj7LIBqp15fjqH5i8ZEbLp8SXJi9S+xbRO+QQAdRo=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes=
@@ -1204,10 +1218,10 @@ golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
-golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
-golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
-golang.org/x/crypto/x509roots/fallback v0.0.0-20240626151235-a6a393ffd658 h1:i7K6wQLN/0oxF7FT3tKkfMCstxoT4VGG36YIB9ZKLzI=
-golang.org/x/crypto/x509roots/fallback v0.0.0-20240626151235-a6a393ffd658/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8=
+golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
+golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
+golang.org/x/crypto/x509roots/fallback v0.0.0-20240806160748-b2d3a6a4b4d3 h1:oWb21rU9Q9XrRwXLB7jHc1rbp6EiiimZZv5MLxpu4T0=
+golang.org/x/crypto/x509roots/fallback v0.0.0-20240806160748-b2d3a6a4b4d3/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -1218,8 +1232,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
-golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
-golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
+golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
+golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -1246,8 +1260,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
-golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
+golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1309,8 +1323,8 @@ golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfS
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
-golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
-golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
+golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
+golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1336,8 +1350,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A=
-golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
-golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
+golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1352,8 +1366,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
-golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
+golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1447,14 +1461,14 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
-golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
+golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
-golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
-golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
+golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU=
+golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1466,8 +1480,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
-golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
+golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
+golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1535,8 +1549,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
-golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
+golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
+golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1712,8 +1726,8 @@ google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUE
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo=
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0=
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240805194559-2c9e96a0b5d4 h1:OsSGQeIIsyOEOimVxLEIL4rwGcnrjOydQaiA2bOnZUM=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20240805194559-2c9e96a0b5d4/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@@ -1811,8 +1825,8 @@ gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
-helm.sh/helm/v3 v3.15.3 h1:HcZDaVFe9uHa6hpsR54mJjYyRy4uz/pc6csg27nxFOc=
-helm.sh/helm/v3 v3.15.3/go.mod h1:FzSIP8jDQaa6WAVg9F+OkKz7J0ZmAga4MABtTbsb9WQ=
+helm.sh/helm/v3 v3.15.4 h1:UFHd6oZ1IN3FsUZ7XNhOQDyQ2QYknBNWRHH57e9cbHY=
+helm.sh/helm/v3 v3.15.4/go.mod h1:phOwlxqGSgppCY/ysWBNRhG3MtnpsttOzxaTK+Mt40E=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -1870,8 +1884,8 @@ k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl
k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak=
k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
-oras.land/oras-go v1.2.5 h1:XpYuAwAb0DfQsunIyMfeET92emK8km3W4yEzZvUbsTo=
-oras.land/oras-go v1.2.5/go.mod h1:PuAwRShRZCsZb7g8Ar3jKKQR/2A/qN+pkYxIOd/FAoo=
+oras.land/oras-go v1.2.6 h1:z8cmxQXBU8yZ4mkytWqXfo6tZcamPwjsuxYU81xJ8Lk=
+oras.land/oras-go v1.2.6/go.mod h1:OVPc1PegSEe/K8YiLfosrlqlqTN9PUyFvOw5Y9gwrT8=
periph.io/x/host/v3 v3.8.2 h1:ayKUDzgUCN0g8+/xM9GTkWaOBhSLVcVHGTfjAOi8OsQ=
periph.io/x/host/v3 v3.8.2/go.mod h1:yFL76AesNHR68PboofSWYaQTKmvPXsQH2Apvp/ls/K4=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
@@ -1879,8 +1893,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0=
sigs.k8s.io/controller-runtime v0.6.1/go.mod h1:XRYBPdbf5XJu9kpS84VJiZ7h/u1hF3gEORz0efEja7A=
-sigs.k8s.io/controller-runtime v0.18.4 h1:87+guW1zhvuPLh1PHybKdYFLU0YJp4FhJRmiHvm5BZw=
-sigs.k8s.io/controller-runtime v0.18.4/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg=
+sigs.k8s.io/controller-runtime v0.18.5 h1:nTHio/W+Q4aBlQMgbnC5hZb4IjIidyrizMai9P6n4Rk=
+sigs.k8s.io/controller-runtime v0.18.5/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg=
sigs.k8s.io/controller-tools v0.3.0/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI=
sigs.k8s.io/gateway-api v1.1.0 h1:DsLDXCi6jR+Xz8/xd0Z1PYl2Pn0TyaFMOPPZIj4inDM=
sigs.k8s.io/gateway-api v1.1.0/go.mod h1:ZH4lHrL2sDi0FHZ9jjneb8kKnGzFWyrTya35sWUTrRs=
diff --git a/internal/cmd/egctl/config.go b/internal/cmd/egctl/config.go
index 13a0f6bed21..501146676e0 100644
--- a/internal/cmd/egctl/config.go
+++ b/internal/cmd/egctl/config.go
@@ -79,7 +79,6 @@ func retrieveConfigDump(args []string, includeEds bool, configType envoyConfigTy
var wg sync.WaitGroup
wg.Add(len(pods))
for _, pod := range pods {
- pod := pod
go func() {
fw, err := portForwarder(cli, pod, adminPort)
if err != nil {
@@ -170,7 +169,6 @@ func fetchRunningEnvoyPods(c kube.CLIClient, nn types.NamespacedName, labelSelec
podsNamespacedNames := []types.NamespacedName{}
for _, pod := range pods {
- pod := pod
podNsName := utils.NamespacedName(&pod)
if pod.Status.Phase != "Running" {
return podsNamespacedNames, fmt.Errorf("pod %s is not running", podNsName)
diff --git a/internal/cmd/egctl/translate.go b/internal/cmd/egctl/translate.go
index 2bf4cda177f..ceb4e9deee3 100644
--- a/internal/cmd/egctl/translate.go
+++ b/internal/cmd/egctl/translate.go
@@ -63,47 +63,48 @@ func newTranslateCommand() *cobra.Command {
addMissingResources bool
outTypes []string
dnsDomain string
+ namespace string
)
translateCommand := &cobra.Command{
Use: "translate",
Short: "Translate Configuration from an input type to an output type",
Example: ` # Translate Gateway API Resources into All xDS Resources.
- egctl experimental translate --from gateway-api --to xds --file
+ egctl experimental translate --from gateway-api --to xds --file -n
# Translate Gateway API Resources into All xDS Resources in JSON output.
- egctl experimental translate --from gateway-api --to xds --type all --output json --file
+ egctl experimental translate --from gateway-api --to xds --type all --output json --file -n
# Translate Gateway API Resources into All xDS Resources in YAML output.
- egctl experimental translate --from gateway-api --to xds --type all --output yaml --file
+ egctl experimental translate --from gateway-api --to xds --type all --output yaml --file -n
# Translate Gateway API Resources into Bootstrap xDS Resources.
- egctl experimental translate --from gateway-api --to xds --type bootstrap --file
+ egctl experimental translate --from gateway-api --to xds --type bootstrap --file -n
# Translate Gateway API Resources into Cluster xDS Resources.
- egctl experimental translate --from gateway-api --to xds --type cluster --file
+ egctl experimental translate --from gateway-api --to xds --type cluster --file -n
# Translate Gateway API Resources into Listener xDS Resources.
- egctl experimental translate --from gateway-api --to xds --type listener --file
+ egctl experimental translate --from gateway-api --to xds --type listener --file -n
# Translate Gateway API Resources into Route xDS Resources.
- egctl experimental translate --from gateway-api --to xds --type route --file
+ egctl experimental translate --from gateway-api --to xds --type route --file -n
# Translate Gateway API Resources into Cluster xDS Resources with short syntax.
- egctl x translate --from gateway-api --to xds -t cluster -o yaml -f
+ egctl x translate --from gateway-api --to xds -t cluster -o yaml -f -n
# Translate Gateway API Resources into All xDS Resources with dummy resources added.
- egctl x translate --from gateway-api --to xds -t cluster --add-missing-resources -f
+ egctl x translate --from gateway-api --to xds -t cluster --add-missing-resources -f -n
# Translate Gateway API Resources into All xDS Resources in YAML output,
# also print the Gateway API Resources with updated status in the same output.
- egctl experimental translate --from gateway-api --to gateway-api,xds --type all --output yaml --file
+ egctl experimental translate --from gateway-api --to gateway-api,xds --type all --output yaml --file -n
# Translate Gateway API Resources into IR in YAML output,
egctl experimental translate --from gateway-api --to ir --output yaml --file
`,
RunE: func(cmd *cobra.Command, args []string) error {
- return translate(cmd.OutOrStdout(), inFile, inType, outTypes, output, resourceType, addMissingResources, dnsDomain)
+ return translate(cmd.OutOrStdout(), inFile, inType, outTypes, output, resourceType, addMissingResources, namespace, dnsDomain)
},
}
@@ -117,6 +118,8 @@ func newTranslateCommand() *cobra.Command {
translateCommand.PersistentFlags().StringVarP(&resourceType, "type", "t", string(AllEnvoyConfigType), getValidResourceTypesStr())
translateCommand.PersistentFlags().BoolVarP(&addMissingResources, "add-missing-resources", "", false, "Provides dummy resources if missed")
translateCommand.PersistentFlags().StringVarP(&dnsDomain, "dns-domain", "", "cluster.local", "DNS domain used by k8s services, default is cluster.local")
+ translateCommand.PersistentFlags().StringVarP(&namespace, "namespace", "n", "envoy-gateway-system", "Namespace where envoy gateway is installed.")
+
return translateCommand
}
@@ -220,7 +223,7 @@ func validate(inFile, inType string, outTypes []string, resourceType string) err
return nil
}
-func translate(w io.Writer, inFile, inType string, outTypes []string, output, resourceType string, addMissingResources bool, dnsDomain string) error {
+func translate(w io.Writer, inFile, inType string, outTypes []string, output, resourceType string, addMissingResources bool, namespace, dnsDomain string) error {
if err := validate(inFile, inType, outTypes, resourceType); err != nil {
return err
}
@@ -247,7 +250,7 @@ func translate(w io.Writer, inFile, inType string, outTypes []string, output, re
}
}
if outType == xdsType {
- res, err := translateGatewayAPIToXds(dnsDomain, resourceType, resources)
+ res, err := translateGatewayAPIToXds(namespace, dnsDomain, resourceType, resources)
if err != nil {
return err
}
@@ -333,7 +336,7 @@ func translateGatewayAPIToGatewayAPI(resources *gatewayapi.Resources) (gatewayap
return gRes.Resources, nil
}
-func translateGatewayAPIToXds(dnsDomain string, resourceType string, resources *gatewayapi.Resources) (map[string]any, error) {
+func translateGatewayAPIToXds(namespace, dnsDomain string, resourceType string, resources *gatewayapi.Resources) (map[string]any, error) {
if resources.GatewayClass == nil {
return nil, fmt.Errorf("the GatewayClass resource is required")
}
@@ -363,7 +366,7 @@ func translateGatewayAPIToXds(dnsDomain string, resourceType string, resources *
xTranslator := &translator.Translator{
// Set some default settings for translation
GlobalRateLimit: &translator.GlobalRateLimitSettings{
- ServiceURL: ratelimit.GetServiceURL("envoy-gateway", dnsDomain),
+ ServiceURL: ratelimit.GetServiceURL(namespace, dnsDomain),
},
}
if resources.EnvoyProxyForGatewayClass != nil {
diff --git a/internal/cmd/egctl/translate_test.go b/internal/cmd/egctl/translate_test.go
index 43fac41ebdd..9207c8bb75b 100644
--- a/internal/cmd/egctl/translate_test.go
+++ b/internal/cmd/egctl/translate_test.go
@@ -292,8 +292,6 @@ func TestTranslate(t *testing.T) {
flag.Parse()
for _, tc := range testCases {
- tc := tc
-
t.Run(tc.name+"|"+tc.resourceType, func(t *testing.T) {
b := bytes.NewBufferString("")
root := newTranslateCommand()
diff --git a/internal/cmd/egctl/version.go b/internal/cmd/egctl/version.go
index 5cab0035358..7492effeee6 100644
--- a/internal/cmd/egctl/version.go
+++ b/internal/cmd/egctl/version.go
@@ -99,7 +99,6 @@ func versions(w io.Writer, containerName, output string, remote bool) error {
}
for _, pod := range pods.Items {
- pod := pod
if pod.Status.Phase != "Running" {
fmt.Fprintf(w, "WARN: pod %s/%s is not running, skipping it.", pod.Namespace, pod.Name)
diff --git a/internal/cmd/server_test.go b/internal/cmd/server_test.go
index dffe10670c9..4ce4178dbfd 100644
--- a/internal/cmd/server_test.go
+++ b/internal/cmd/server_test.go
@@ -52,7 +52,6 @@ func TestGetConfigValidate(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
file, err := os.CreateTemp("", "config")
require.NoError(t, err)
diff --git a/internal/envoygateway/config/config_test.go b/internal/envoygateway/config/config_test.go
index 2b3f461f762..59bba129434 100644
--- a/internal/envoygateway/config/config_test.go
+++ b/internal/envoygateway/config/config_test.go
@@ -63,7 +63,6 @@ func TestValidate(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
err := tc.cfg.Validate()
if !tc.expect {
diff --git a/internal/envoygateway/config/decoder_test.go b/internal/envoygateway/config/decoder_test.go
index 67520f2e5dd..5bbbb959ed7 100644
--- a/internal/envoygateway/config/decoder_test.go
+++ b/internal/envoygateway/config/decoder_test.go
@@ -347,7 +347,6 @@ func TestDecode(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.in, func(t *testing.T) {
eg, err := Decode(tc.in)
if tc.expect {
diff --git a/internal/extension/registry/extension_manager_test.go b/internal/extension/registry/extension_manager_test.go
index f64160ed5ca..a6cd9751d2e 100644
--- a/internal/extension/registry/extension_manager_test.go
+++ b/internal/extension/registry/extension_manager_test.go
@@ -65,7 +65,6 @@ func TestGetExtensionServerAddress(t *testing.T) {
}
for _, tc := range tests {
- tc := tc
t.Run(tc.Name, func(t *testing.T) {
out := getExtensionServerAddress(tc.Service)
require.Equal(t, tc.Expected, out)
diff --git a/internal/gatewayapi/backendtrafficpolicy.go b/internal/gatewayapi/backendtrafficpolicy.go
index 120918a8f6a..466f889167a 100644
--- a/internal/gatewayapi/backendtrafficpolicy.go
+++ b/internal/gatewayapi/backendtrafficpolicy.go
@@ -9,10 +9,8 @@ import (
"errors"
"fmt"
"math"
- "math/big"
"sort"
"strings"
- "time"
perr "github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -307,60 +305,42 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
errs = errors.Join(errs, err)
}
}
- if policy.Spec.LoadBalancer != nil {
- if lb, err = t.buildLoadBalancer(policy); err != nil {
- err = perr.WithMessage(err, "LoadBalancer")
- errs = errors.Join(errs, err)
- }
+ if lb, err = buildLoadBalancer(policy.Spec.ClusterSettings); err != nil {
+ err = perr.WithMessage(err, "LoadBalancer")
+ errs = errors.Join(errs, err)
}
- if policy.Spec.ProxyProtocol != nil {
- pp = t.buildProxyProtocol(policy)
- }
- if policy.Spec.HealthCheck != nil {
- hc = t.buildHealthCheck(policy)
- }
- if policy.Spec.CircuitBreaker != nil {
- if cb, err = t.buildCircuitBreaker(policy); err != nil {
- err = perr.WithMessage(err, "CircuitBreaker")
- errs = errors.Join(errs, err)
- }
+ pp = buildProxyProtocol(policy.Spec.ClusterSettings)
+ hc = buildHealthCheck(policy.Spec.ClusterSettings)
+ if cb, err = buildCircuitBreaker(policy.Spec.ClusterSettings); err != nil {
+ err = perr.WithMessage(err, "CircuitBreaker")
+ errs = errors.Join(errs, err)
}
if policy.Spec.FaultInjection != nil {
fi = t.buildFaultInjection(policy)
}
- if policy.Spec.TCPKeepalive != nil {
- if ka, err = t.buildTCPKeepAlive(policy); err != nil {
- err = perr.WithMessage(err, "TCPKeepalive")
- errs = errors.Join(errs, err)
- }
+ if ka, err = buildTCPKeepAlive(policy.Spec.ClusterSettings); err != nil {
+ err = perr.WithMessage(err, "TCPKeepalive")
+ errs = errors.Join(errs, err)
}
if policy.Spec.Retry != nil {
rt = t.buildRetry(policy)
}
- if policy.Spec.Timeout != nil {
- if to, err = t.buildTimeout(policy, nil); err != nil {
- err = perr.WithMessage(err, "Timeout")
- errs = errors.Join(errs, err)
- }
+ if to, err = buildTimeout(policy.Spec.ClusterSettings, nil); err != nil {
+ err = perr.WithMessage(err, "Timeout")
+ errs = errors.Join(errs, err)
}
- if policy.Spec.Connection != nil {
- if bc, err = t.buildBackendConnection(policy); err != nil {
- err = perr.WithMessage(err, "BackendConnection")
- errs = errors.Join(errs, err)
- }
+ if bc, err = buildBackendConnection(policy.Spec.ClusterSettings); err != nil {
+ err = perr.WithMessage(err, "BackendConnection")
+ errs = errors.Join(errs, err)
}
- if policy.Spec.HTTP2 != nil {
- if h2, err = buildIRHTTP2Settings(policy.Spec.HTTP2); err != nil {
- err = perr.WithMessage(err, "HTTP2")
- errs = errors.Join(errs, err)
- }
+ if h2, err = buildIRHTTP2Settings(policy.Spec.HTTP2); err != nil {
+ err = perr.WithMessage(err, "HTTP2")
+ errs = errors.Join(errs, err)
}
- if policy.Spec.DNS != nil {
- ds = t.translateDNS(policy)
- }
+ ds = translateDNS(policy.Spec.ClusterSettings)
// Early return if got any errors
if errs != nil {
@@ -414,17 +394,15 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
Retry: rt,
BackendConnection: bc,
HTTP2: h2,
+ DNS: ds,
}
- r.DNS = ds
// Update the Host field in HealthCheck, now that we have access to the Route Hostname.
r.Traffic.HealthCheck.SetHTTPHostIfAbsent(r.Hostname)
// Some timeout setting originate from the route.
- if policy.Spec.Timeout != nil {
- if to, err = t.buildTimeout(policy, r); err == nil {
- r.Traffic.Timeout = to
- }
+ if to, err = buildTimeout(policy.Spec.ClusterSettings, r); err == nil {
+ r.Traffic.Timeout = to
}
if policy.Spec.UseClientProtocol != nil {
@@ -461,52 +439,36 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back
errs = errors.Join(errs, err)
}
}
- if policy.Spec.LoadBalancer != nil {
- if lb, err = t.buildLoadBalancer(policy); err != nil {
- err = perr.WithMessage(err, "LoadBalancer")
- errs = errors.Join(errs, err)
- }
- }
- if policy.Spec.ProxyProtocol != nil {
- pp = t.buildProxyProtocol(policy)
+ if lb, err = buildLoadBalancer(policy.Spec.ClusterSettings); err != nil {
+ err = perr.WithMessage(err, "LoadBalancer")
+ errs = errors.Join(errs, err)
}
- if policy.Spec.HealthCheck != nil {
- hc = t.buildHealthCheck(policy)
- }
- if policy.Spec.CircuitBreaker != nil {
- if cb, err = t.buildCircuitBreaker(policy); err != nil {
- err = perr.WithMessage(err, "CircuitBreaker")
- errs = errors.Join(errs, err)
- }
+ pp = buildProxyProtocol(policy.Spec.ClusterSettings)
+ hc = buildHealthCheck(policy.Spec.ClusterSettings)
+ if cb, err = buildCircuitBreaker(policy.Spec.ClusterSettings); err != nil {
+ err = perr.WithMessage(err, "CircuitBreaker")
+ errs = errors.Join(errs, err)
}
if policy.Spec.FaultInjection != nil {
fi = t.buildFaultInjection(policy)
}
- if policy.Spec.TCPKeepalive != nil {
- if ka, err = t.buildTCPKeepAlive(policy); err != nil {
- err = perr.WithMessage(err, "TCPKeepalive")
- errs = errors.Join(errs, err)
- }
+ if ka, err = buildTCPKeepAlive(policy.Spec.ClusterSettings); err != nil {
+ err = perr.WithMessage(err, "TCPKeepalive")
+ errs = errors.Join(errs, err)
}
if policy.Spec.Retry != nil {
rt = t.buildRetry(policy)
}
- if policy.Spec.Timeout != nil {
- if ct, err = t.buildTimeout(policy, nil); err != nil {
- err = perr.WithMessage(err, "Timeout")
- errs = errors.Join(errs, err)
- }
+ if ct, err = buildTimeout(policy.Spec.ClusterSettings, nil); err != nil {
+ err = perr.WithMessage(err, "Timeout")
+ errs = errors.Join(errs, err)
}
- if policy.Spec.HTTP2 != nil {
- if h2, err = buildIRHTTP2Settings(policy.Spec.HTTP2); err != nil {
- err = perr.WithMessage(err, "HTTP2")
- errs = errors.Join(errs, err)
- }
+ if h2, err = buildIRHTTP2Settings(policy.Spec.HTTP2); err != nil {
+ err = perr.WithMessage(err, "HTTP2")
+ errs = errors.Join(errs, err)
}
- if policy.Spec.DNS != nil {
- ds = t.translateDNS(policy)
- }
+ ds = translateDNS(policy.Spec.ClusterSettings)
// Early return if got any errors
if errs != nil {
@@ -529,26 +491,15 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back
}
for _, r := range tcp.Routes {
- // policy(targeting xRoute) has already set it, so we skip it.
- if r.LoadBalancer != nil || r.ProxyProtocol != nil ||
- r.HealthCheck != nil || r.CircuitBreaker != nil ||
- r.TCPKeepalive != nil || r.Timeout != nil {
- continue
- }
-
- r.LoadBalancer = lb
- r.ProxyProtocol = pp
- r.HealthCheck = hc
- r.CircuitBreaker = cb
- r.TCPKeepalive = ka
-
- if r.Timeout == nil {
- r.Timeout = ct
- }
-
- if r.DNS == nil {
- r.DNS = ds
- }
+ // only set attributes which weren't already set by a more
+ // specific policy
+ setIfNil(&r.LoadBalancer, lb)
+ setIfNil(&r.ProxyProtocol, pp)
+ setIfNil(&r.HealthCheck, hc)
+ setIfNil(&r.CircuitBreaker, cb)
+ setIfNil(&r.TCPKeepalive, ka)
+ setIfNil(&r.Timeout, ct)
+ setIfNil(&r.DNS, ds)
}
}
@@ -564,19 +515,11 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back
route := udp.Route
- // policy(targeting xRoute) has already set it, so we skip it.
- if route.LoadBalancer != nil || route.Timeout != nil {
- continue
- }
-
- route.LoadBalancer = lb
- if route.Timeout == nil {
- route.Timeout = ct
- }
-
- if route.DNS == nil {
- route.DNS = ds
- }
+ // only set attributes which weren't already set by a more
+ // specific policy
+ setIfNil(&route.LoadBalancer, lb)
+ setIfNil(&route.Timeout, ct)
+ setIfNil(&route.DNS, ds)
}
for _, http := range x.HTTP {
@@ -604,25 +547,18 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back
TCPKeepalive: ka,
Retry: rt,
HTTP2: h2,
- }
-
- if r.DNS == nil {
- r.DNS = ds
+ DNS: ds,
}
// Update the Host field in HealthCheck, now that we have access to the Route Hostname.
r.Traffic.HealthCheck.SetHTTPHostIfAbsent(r.Hostname)
- if policy.Spec.Timeout != nil {
- if ct, err = t.buildTimeout(policy, r); err == nil {
- r.Traffic.Timeout = ct
- }
+ if ct, err = buildTimeout(policy.Spec.ClusterSettings, r); err == nil {
+ r.Traffic.Timeout = ct
}
if policy.Spec.UseClientProtocol != nil {
- if r.UseClientProtocol == nil {
- r.UseClientProtocol = policy.Spec.UseClientProtocol
- }
+ setIfNil(&r.UseClientProtocol, policy.Spec.UseClientProtocol)
}
}
}
@@ -653,7 +589,7 @@ func (t *Translator) buildLocalRateLimit(policy *egv1a1.BackendTrafficPolicy) (*
// limit. If no such rule is found, EG uses a default limit of uint32 max.
var defaultLimit *ir.RateLimitValue
for _, rule := range local.Rules {
- if rule.ClientSelectors == nil || len(rule.ClientSelectors) == 0 {
+ if len(rule.ClientSelectors) == 0 {
if defaultLimit != nil {
return nil, fmt.Errorf("local rateLimit can not have more than one rule without clientSelectors")
}
@@ -815,222 +751,6 @@ func buildRateLimitRule(rule egv1a1.RateLimitRule) (*ir.RateLimitRule, error) {
return irRule, nil
}
-func (t *Translator) buildLoadBalancer(policy *egv1a1.BackendTrafficPolicy) (*ir.LoadBalancer, error) {
- var lb *ir.LoadBalancer
- switch policy.Spec.LoadBalancer.Type {
- case egv1a1.ConsistentHashLoadBalancerType:
- consistentHash, err := t.buildConsistentHashLoadBalancer(policy)
- if err != nil {
- return nil, perr.WithMessage(err, "ConsistentHash")
- }
-
- lb = &ir.LoadBalancer{
- ConsistentHash: consistentHash,
- }
- case egv1a1.LeastRequestLoadBalancerType:
- lb = &ir.LoadBalancer{}
- if policy.Spec.LoadBalancer.SlowStart != nil {
- if policy.Spec.LoadBalancer.SlowStart.Window != nil {
- lb.LeastRequest = &ir.LeastRequest{
- SlowStart: &ir.SlowStart{
- Window: policy.Spec.LoadBalancer.SlowStart.Window,
- },
- }
- }
- }
- case egv1a1.RandomLoadBalancerType:
- lb = &ir.LoadBalancer{
- Random: &ir.Random{},
- }
- case egv1a1.RoundRobinLoadBalancerType:
- lb = &ir.LoadBalancer{
- RoundRobin: &ir.RoundRobin{
- SlowStart: &ir.SlowStart{},
- },
- }
- if policy.Spec.LoadBalancer.SlowStart != nil {
- if policy.Spec.LoadBalancer.SlowStart.Window != nil {
- lb.RoundRobin = &ir.RoundRobin{
- SlowStart: &ir.SlowStart{
- Window: policy.Spec.LoadBalancer.SlowStart.Window,
- },
- }
- }
- }
- }
-
- return lb, nil
-}
-
-func (t *Translator) buildConsistentHashLoadBalancer(policy *egv1a1.BackendTrafficPolicy) (*ir.ConsistentHash, error) {
- consistentHash := &ir.ConsistentHash{}
-
- if policy.Spec.LoadBalancer.ConsistentHash.TableSize != nil {
- tableSize := policy.Spec.LoadBalancer.ConsistentHash.TableSize
-
- if *tableSize > MaxConsistentHashTableSize || !big.NewInt(int64(*tableSize)).ProbablyPrime(0) {
- return nil, fmt.Errorf("invalid TableSize value %d", *tableSize)
- }
-
- consistentHash.TableSize = tableSize
- }
-
- switch policy.Spec.LoadBalancer.ConsistentHash.Type {
- case egv1a1.SourceIPConsistentHashType:
- consistentHash.SourceIP = ptr.To(true)
- case egv1a1.HeaderConsistentHashType:
- consistentHash.Header = &ir.Header{
- Name: policy.Spec.LoadBalancer.ConsistentHash.Header.Name,
- }
- case egv1a1.CookieConsistentHashType:
- consistentHash.Cookie = policy.Spec.LoadBalancer.ConsistentHash.Cookie
- }
-
- return consistentHash, nil
-}
-
-func (t *Translator) translateDNS(policy *egv1a1.BackendTrafficPolicy) *ir.DNS {
- ds := &ir.DNS{}
- if policy.Spec.DNS.RespectDNSTTL != nil {
- ds.RespectDNSTTL = policy.Spec.DNS.RespectDNSTTL
- }
- if policy.Spec.DNS.DNSRefreshRate != nil {
- ds.DNSRefreshRate = policy.Spec.DNS.DNSRefreshRate
- }
- return ds
-}
-
-func (t *Translator) buildProxyProtocol(policy *egv1a1.BackendTrafficPolicy) *ir.ProxyProtocol {
- var pp *ir.ProxyProtocol
- switch policy.Spec.ProxyProtocol.Version {
- case egv1a1.ProxyProtocolVersionV1:
- pp = &ir.ProxyProtocol{
- Version: ir.ProxyProtocolVersionV1,
- }
- case egv1a1.ProxyProtocolVersionV2:
- pp = &ir.ProxyProtocol{
- Version: ir.ProxyProtocolVersionV2,
- }
- }
-
- return pp
-}
-
-func (t *Translator) buildHealthCheck(policy *egv1a1.BackendTrafficPolicy) *ir.HealthCheck {
- if policy.Spec.HealthCheck == nil {
- return nil
- }
-
- irhc := &ir.HealthCheck{}
- if policy.Spec.HealthCheck.Passive != nil {
- irhc.Passive = t.buildPassiveHealthCheck(policy)
- }
-
- if policy.Spec.HealthCheck.Active != nil {
- irhc.Active = t.buildActiveHealthCheck(policy)
- }
-
- return irhc
-}
-
-func (t *Translator) buildPassiveHealthCheck(policy *egv1a1.BackendTrafficPolicy) *ir.OutlierDetection {
- if policy.Spec.HealthCheck == nil || policy.Spec.HealthCheck.Passive == nil {
- return nil
- }
-
- hc := policy.Spec.HealthCheck.Passive
- irOD := &ir.OutlierDetection{
- Interval: hc.Interval,
- SplitExternalLocalOriginErrors: hc.SplitExternalLocalOriginErrors,
- ConsecutiveLocalOriginFailures: hc.ConsecutiveLocalOriginFailures,
- ConsecutiveGatewayErrors: hc.ConsecutiveGatewayErrors,
- Consecutive5xxErrors: hc.Consecutive5xxErrors,
- BaseEjectionTime: hc.BaseEjectionTime,
- MaxEjectionPercent: hc.MaxEjectionPercent,
- }
- return irOD
-}
-
-func (t *Translator) buildActiveHealthCheck(policy *egv1a1.BackendTrafficPolicy) *ir.ActiveHealthCheck {
- if policy.Spec.HealthCheck == nil || policy.Spec.HealthCheck.Active == nil {
- return nil
- }
-
- hc := policy.Spec.HealthCheck.Active
- irHC := &ir.ActiveHealthCheck{
- Timeout: hc.Timeout,
- Interval: hc.Interval,
- UnhealthyThreshold: hc.UnhealthyThreshold,
- HealthyThreshold: hc.HealthyThreshold,
- }
- switch hc.Type {
- case egv1a1.ActiveHealthCheckerTypeHTTP:
- irHC.HTTP = t.buildHTTPActiveHealthChecker(hc.HTTP)
- case egv1a1.ActiveHealthCheckerTypeTCP:
- irHC.TCP = t.buildTCPActiveHealthChecker(hc.TCP)
- }
-
- return irHC
-}
-
-func (t *Translator) buildHTTPActiveHealthChecker(h *egv1a1.HTTPActiveHealthChecker) *ir.HTTPHealthChecker {
- if h == nil {
- return nil
- }
-
- irHTTP := &ir.HTTPHealthChecker{
- Path: h.Path,
- Method: h.Method,
- }
- if irHTTP.Method != nil {
- *irHTTP.Method = strings.ToUpper(*irHTTP.Method)
- }
-
- // deduplicate http statuses
- statusSet := sets.NewInt()
- for _, r := range h.ExpectedStatuses {
- statusSet.Insert(int(r))
- }
- irStatuses := make([]ir.HTTPStatus, 0, statusSet.Len())
-
- for _, r := range statusSet.List() {
- irStatuses = append(irStatuses, ir.HTTPStatus(r))
- }
- irHTTP.ExpectedStatuses = irStatuses
-
- irHTTP.ExpectedResponse = translateActiveHealthCheckPayload(h.ExpectedResponse)
- return irHTTP
-}
-
-func (t *Translator) buildTCPActiveHealthChecker(h *egv1a1.TCPActiveHealthChecker) *ir.TCPHealthChecker {
- if h == nil {
- return nil
- }
-
- irTCP := &ir.TCPHealthChecker{
- Send: translateActiveHealthCheckPayload(h.Send),
- Receive: translateActiveHealthCheckPayload(h.Receive),
- }
- return irTCP
-}
-
-func translateActiveHealthCheckPayload(p *egv1a1.ActiveHealthCheckPayload) *ir.HealthCheckPayload {
- if p == nil {
- return nil
- }
-
- irPayload := &ir.HealthCheckPayload{}
- switch p.Type {
- case egv1a1.ActiveHealthCheckPayloadTypeText:
- irPayload.Text = p.Text
- case egv1a1.ActiveHealthCheckPayloadTypeBinary:
- irPayload.Binary = make([]byte, len(p.Binary))
- copy(irPayload.Binary, p.Binary)
- }
-
- return irPayload
-}
-
func ratelimitUnitToDuration(unit egv1a1.RateLimitUnit) int64 {
var seconds int64
@@ -1047,144 +767,6 @@ func ratelimitUnitToDuration(unit egv1a1.RateLimitUnit) int64 {
return seconds
}
-func (t *Translator) buildCircuitBreaker(policy *egv1a1.BackendTrafficPolicy) (*ir.CircuitBreaker, error) {
- var cb *ir.CircuitBreaker
- pcb := policy.Spec.CircuitBreaker
-
- if pcb != nil {
- cb = &ir.CircuitBreaker{}
-
- if pcb.MaxConnections != nil {
- if ui32, ok := int64ToUint32(*pcb.MaxConnections); ok {
- cb.MaxConnections = &ui32
- } else {
- return nil, fmt.Errorf("invalid MaxConnections value %d", *pcb.MaxConnections)
- }
- }
-
- if pcb.MaxParallelRequests != nil {
- if ui32, ok := int64ToUint32(*pcb.MaxParallelRequests); ok {
- cb.MaxParallelRequests = &ui32
- } else {
- return nil, fmt.Errorf("invalid MaxParallelRequests value %d", *pcb.MaxParallelRequests)
- }
- }
-
- if pcb.MaxPendingRequests != nil {
- if ui32, ok := int64ToUint32(*pcb.MaxPendingRequests); ok {
- cb.MaxPendingRequests = &ui32
- } else {
- return nil, fmt.Errorf("invalid MaxPendingRequests value %d", *pcb.MaxPendingRequests)
- }
- }
-
- if pcb.MaxParallelRetries != nil {
- if ui32, ok := int64ToUint32(*pcb.MaxParallelRetries); ok {
- cb.MaxParallelRetries = &ui32
- } else {
- return nil, fmt.Errorf("invalid MaxParallelRetries value %d", *pcb.MaxParallelRetries)
- }
- }
-
- if pcb.MaxRequestsPerConnection != nil {
- if ui32, ok := int64ToUint32(*pcb.MaxRequestsPerConnection); ok {
- cb.MaxRequestsPerConnection = &ui32
- } else {
- return nil, fmt.Errorf("invalid MaxRequestsPerConnection value %d", *pcb.MaxRequestsPerConnection)
- }
- }
-
- }
-
- return cb, nil
-}
-
-func (t *Translator) buildTimeout(policy *egv1a1.BackendTrafficPolicy, r *ir.HTTPRoute) (*ir.Timeout, error) {
- var (
- tto *ir.TCPTimeout
- hto *ir.HTTPTimeout
- terr bool
- errs error
- )
-
- pto := policy.Spec.Timeout
-
- if pto.TCP != nil && pto.TCP.ConnectTimeout != nil {
- d, err := time.ParseDuration(string(*pto.TCP.ConnectTimeout))
- if err != nil {
- terr = true
- errs = errors.Join(errs, fmt.Errorf("invalid ConnectTimeout value %s", *pto.TCP.ConnectTimeout))
- } else {
- tto = &ir.TCPTimeout{
- ConnectTimeout: ptr.To(metav1.Duration{Duration: d}),
- }
- }
- }
-
- if pto.HTTP != nil {
- var cit *metav1.Duration
- var mcd *metav1.Duration
-
- if pto.HTTP.ConnectionIdleTimeout != nil {
- d, err := time.ParseDuration(string(*pto.HTTP.ConnectionIdleTimeout))
- if err != nil {
- terr = true
- errs = errors.Join(errs, fmt.Errorf("invalid ConnectionIdleTimeout value %s", *pto.HTTP.ConnectionIdleTimeout))
- } else {
- cit = ptr.To(metav1.Duration{Duration: d})
- }
- }
-
- if pto.HTTP.MaxConnectionDuration != nil {
- d, err := time.ParseDuration(string(*pto.HTTP.MaxConnectionDuration))
- if err != nil {
- terr = true
- errs = errors.Join(errs, fmt.Errorf("invalid MaxConnectionDuration value %s", *pto.HTTP.MaxConnectionDuration))
- } else {
- mcd = ptr.To(metav1.Duration{Duration: d})
- }
- }
-
- hto = &ir.HTTPTimeout{
- ConnectionIdleTimeout: cit,
- MaxConnectionDuration: mcd,
- }
- }
-
- // http request timeout is translated during the gateway-api route resource translation
- // merge route timeout setting with backendtrafficpolicy timeout settings
- if terr {
- if r != nil && r.Traffic != nil && r.Traffic.Timeout != nil {
- return r.Traffic.Timeout.DeepCopy(), errs
- }
- } else {
- // http request timeout is translated during the gateway-api route resource translation
- // merge route timeout setting with backendtrafficpolicy timeout settings
- if r != nil &&
- r.Traffic != nil &&
- r.Traffic.Timeout != nil &&
- r.Traffic.Timeout.HTTP != nil &&
- r.Traffic.Timeout.HTTP.RequestTimeout != nil {
- if hto == nil {
- hto = &ir.HTTPTimeout{
- RequestTimeout: r.Traffic.Timeout.HTTP.RequestTimeout,
- }
- } else {
- hto.RequestTimeout = r.Traffic.Timeout.HTTP.RequestTimeout
- }
- }
-
- if hto != nil || tto != nil {
- return &ir.Timeout{
- TCP: tto,
- HTTP: hto,
- }, nil
- }
- }
-
- return nil, errs
-}
-
func int64ToUint32(in int64) (uint32, bool) {
if in >= 0 && in <= math.MaxUint32 {
return uint32(in), true
@@ -1192,31 +774,6 @@ func int64ToUint32(in int64) (uint32, bool) {
return 0, false
}
-func (t *Translator) buildBackendConnection(policy *egv1a1.BackendTrafficPolicy) (*ir.BackendConnection, error) {
- var (
- bcIR = &ir.BackendConnection{}
- bc = &egv1a1.BackendConnection{}
- )
-
- if policy.Spec.Connection != nil {
- bc = policy.Spec.Connection
-
- if bc.BufferLimit != nil {
- bf, ok := bc.BufferLimit.AsInt64()
- if !ok {
- return nil, fmt.Errorf("invalid BufferLimit value %s", bc.BufferLimit.String())
- }
- if bf < 0 || bf > math.MaxUint32 {
- return nil, fmt.Errorf("BufferLimit value %s is out of range", bc.BufferLimit.String())
- }
-
- bcIR.BufferLimitBytes = ptr.To(uint32(bf))
- }
- }
-
- return bcIR, nil
-}
-
func (t *Translator) buildFaultInjection(policy *egv1a1.BackendTrafficPolicy) *ir.FaultInjection {
var fi *ir.FaultInjection
if policy.Spec.FaultInjection != nil {
@@ -1244,36 +801,6 @@ func (t *Translator) buildFaultInjection(policy *egv1a1.BackendTrafficPolicy) *i
return fi
}
-func (t *Translator) buildTCPKeepAlive(policy *egv1a1.BackendTrafficPolicy) (*ir.TCPKeepalive, error) {
- var ka *ir.TCPKeepalive
- if policy.Spec.TCPKeepalive != nil {
- pka := policy.Spec.TCPKeepalive
- ka = &ir.TCPKeepalive{}
-
- if pka.Probes != nil {
- ka.Probes = pka.Probes
- }
-
- if pka.IdleTime != nil {
- d, err := time.ParseDuration(string(*pka.IdleTime))
- if err != nil {
- return nil, fmt.Errorf("invalid IdleTime value %s", *pka.IdleTime)
- }
- ka.IdleTime = ptr.To(uint32(d.Seconds()))
- }
-
- if pka.Interval != nil {
- d, err := time.ParseDuration(string(*pka.Interval))
- if err != nil {
- return nil, fmt.Errorf("invalid Interval value %s", *pka.Interval)
- }
- ka.Interval = ptr.To(uint32(d.Seconds()))
- }
-
- }
- return ka, nil
-}
-
func (t *Translator) buildRetry(policy *egv1a1.BackendTrafficPolicy) *ir.Retry {
var rt *ir.Retry
if policy.Spec.Retry != nil {
diff --git a/internal/gatewayapi/backendtrafficpolicy_test.go b/internal/gatewayapi/backendtrafficpolicy_test.go
index d40d1e68c76..ebf721fb07d 100644
--- a/internal/gatewayapi/backendtrafficpolicy_test.go
+++ b/internal/gatewayapi/backendtrafficpolicy_test.go
@@ -46,7 +46,6 @@ func TestInt64ToUint32(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.Name, func(t *testing.T) {
out, success := int64ToUint32(tc.In)
require.Equal(t, tc.Out, out)
diff --git a/internal/gatewayapi/clienttrafficpolicy.go b/internal/gatewayapi/clienttrafficpolicy.go
index 1d7e8e89a84..44d813c255c 100644
--- a/internal/gatewayapi/clienttrafficpolicy.go
+++ b/internal/gatewayapi/clienttrafficpolicy.go
@@ -18,6 +18,7 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/utils/ptr"
+ gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
@@ -417,7 +418,7 @@ func (t *Translator) translateClientTrafficPolicyForListener(policy *egv1a1.Clie
}
// Translate Proxy Protocol
- enableProxyProtocol = buildProxyProtocol(policy.Spec.EnableProxyProtocol)
+ enableProxyProtocol = ptr.Deref(policy.Spec.EnableProxyProtocol, false)
// Translate Client Timeout Settings
timeout, err = buildClientTimeout(policy.Spec.Timeout)
@@ -432,7 +433,10 @@ func (t *Translator) translateClientTrafficPolicyForListener(policy *egv1a1.Clie
translateClientIPDetection(policy.Spec.ClientIPDetection, httpIR)
// Translate Header Settings
- translateListenerHeaderSettings(policy.Spec.Headers, httpIR)
+ if err = translateListenerHeaderSettings(policy.Spec.Headers, httpIR); err != nil {
+ err = perr.WithMessage(err, "Headers")
+ errs = errors.Join(errs, err)
+ }
// Translate Path Settings
translatePathSettings(policy.Spec.Path, httpIR)
@@ -604,14 +608,6 @@ func buildClientTimeout(clientTimeout *egv1a1.ClientTimeout) (*ir.ClientTimeout,
return irClientTimeout, nil
}
-func buildProxyProtocol(enableProxyProtocol *bool) bool {
- if enableProxyProtocol != nil && *enableProxyProtocol {
- return true
- }
-
- return false
-}
-
func translateClientIPDetection(clientIPDetection *egv1a1.ClientIPDetectionSettings, httpIR *ir.HTTPListener) {
// Return early if not set
if clientIPDetection == nil {
@@ -621,9 +617,9 @@ func translateClientIPDetection(clientIPDetection *egv1a1.ClientIPDetectionSetti
httpIR.ClientIPDetection = (*ir.ClientIPDetectionSettings)(clientIPDetection)
}
-func translateListenerHeaderSettings(headerSettings *egv1a1.HeaderSettings, httpIR *ir.HTTPListener) {
+func translateListenerHeaderSettings(headerSettings *egv1a1.HeaderSettings, httpIR *ir.HTTPListener) error {
if headerSettings == nil {
- return
+ return nil
}
httpIR.Headers = &ir.HeaderSettings{
EnableEnvoyHeaders: ptr.Deref(headerSettings.EnableEnvoyHeaders, false),
@@ -642,6 +638,16 @@ func translateListenerHeaderSettings(headerSettings *egv1a1.HeaderSettings, http
httpIR.Headers.XForwardedClientCert.CertDetailsToAdd = headerSettings.XForwardedClientCert.CertDetailsToAdd
}
}
+
+ if headerSettings.EarlyRequestHeaders != nil {
+ headersToAdd, headersToRemove, err := translateEarlyRequestHeaders(headerSettings.EarlyRequestHeaders)
+ if err != nil {
+ return err
+ }
+ httpIR.Headers.EarlyAddRequestHeaders = headersToAdd
+ httpIR.Headers.EarlyRemoveRequestHeaders = headersToRemove
+ }
+ return nil
}
func translateHTTP1Settings(http1Settings *egv1a1.HTTP1Settings, httpIR *ir.HTTPListener) error {
@@ -877,3 +883,130 @@ func buildConnection(connection *egv1a1.ClientConnection) (*ir.ClientConnection,
return irConnection, nil
}
+
+func translateEarlyRequestHeaders(headerModifier *gwapiv1.HTTPHeaderFilter) ([]ir.AddHeader, []string, error) {
+ // Make sure the header modifier config actually exists
+ if headerModifier == nil {
+ return nil, nil, nil
+ }
+ var errs error
+ emptyFilterConfig := true // keep track of whether the provided config is empty or not
+
+ var AddRequestHeaders []ir.AddHeader
+ var RemoveRequestHeaders []string
+
+ // Add request headers
+ if headersToAdd := headerModifier.Add; headersToAdd != nil {
+ if len(headersToAdd) > 0 {
+ emptyFilterConfig = false
+ }
+ for _, addHeader := range headersToAdd {
+ emptyFilterConfig = false
+ if addHeader.Name == "" {
+ errs = errors.Join(errs, fmt.Errorf("EarlyRequestHeaders cannot add a header with an empty name"))
+ // try to process the rest of the headers and produce a valid config.
+ continue
+ }
+ // Per Gateway API specification on HTTPHeaderName, : and / are invalid characters in header names
+ if strings.ContainsAny(string(addHeader.Name), "/:") {
+ errs = errors.Join(errs, fmt.Errorf("EarlyRequestHeaders Filter cannot set headers with a '/' or ':' character in them. Header: %q", string(addHeader.Name)))
+ continue
+ }
+ // Check if the header is a duplicate
+ headerKey := string(addHeader.Name)
+ canAddHeader := true
+ for _, h := range AddRequestHeaders {
+ if strings.EqualFold(h.Name, headerKey) {
+ canAddHeader = false
+ break
+ }
+ }
+
+ if !canAddHeader {
+ continue
+ }
+
+ newHeader := ir.AddHeader{
+ Name: headerKey,
+ Append: true,
+ Value: strings.Split(addHeader.Value, ","),
+ }
+
+ AddRequestHeaders = append(AddRequestHeaders, newHeader)
+ }
+ }
+
+ // Set headers
+ if headersToSet := headerModifier.Set; headersToSet != nil {
+ if len(headersToSet) > 0 {
+ emptyFilterConfig = false
+ }
+ for _, setHeader := range headersToSet {
+
+ if setHeader.Name == "" {
+ errs = errors.Join(errs, fmt.Errorf("EarlyRequestHeaders cannot set a header with an empty name"))
+ continue
+ }
+ // Per Gateway API specification on HTTPHeaderName, : and / are invalid characters in header names
+ if strings.ContainsAny(string(setHeader.Name), "/:") {
+ errs = errors.Join(errs, fmt.Errorf("EarlyRequestHeaders cannot set headers with a '/' or ':' character in them. Header: '%s'", string(setHeader.Name)))
+ continue
+ }
+
+ // Check if the header to be set has already been configured
+ headerKey := string(setHeader.Name)
+ canAddHeader := true
+ for _, h := range AddRequestHeaders {
+ if strings.EqualFold(h.Name, headerKey) {
+ canAddHeader = false
+ break
+ }
+ }
+ if !canAddHeader {
+ continue
+ }
+ newHeader := ir.AddHeader{
+ Name: string(setHeader.Name),
+ Append: false,
+ Value: strings.Split(setHeader.Value, ","),
+ }
+
+ AddRequestHeaders = append(AddRequestHeaders, newHeader)
+ }
+ }
+
+ // Remove request headers
+ // As far as Envoy is concerned, it is ok to configure a header to be added/set and also in the list of
+ // headers to remove. It will remove the original header if present and then add/set the header after.
+ if headersToRemove := headerModifier.Remove; headersToRemove != nil {
+ if len(headersToRemove) > 0 {
+ emptyFilterConfig = false
+ }
+ for _, removedHeader := range headersToRemove {
+ if removedHeader == "" {
+ errs = errors.Join(errs, fmt.Errorf("EarlyRequestHeaders cannot remove a header with an empty name"))
+ continue
+ }
+
+ canRemHeader := true
+ for _, h := range RemoveRequestHeaders {
+ if strings.EqualFold(h, removedHeader) {
+ canRemHeader = false
+ break
+ }
+ }
+ if !canRemHeader {
+ continue
+ }
+
+ RemoveRequestHeaders = append(RemoveRequestHeaders, removedHeader)
+ }
+ }
+
+ // Update the status if the filter failed to configure any valid headers to add/remove
+ if len(AddRequestHeaders) == 0 && len(RemoveRequestHeaders) == 0 && !emptyFilterConfig {
+ errs = errors.Join(errs, fmt.Errorf("EarlyRequestHeaders did not provide valid configuration to add/set/remove any headers"))
+ }
+
+ return AddRequestHeaders, RemoveRequestHeaders, errs
+}
diff --git a/internal/gatewayapi/clustersettings.go b/internal/gatewayapi/clustersettings.go
new file mode 100644
index 00000000000..1d5c1a3d6f8
--- /dev/null
+++ b/internal/gatewayapi/clustersettings.go
@@ -0,0 +1,504 @@
+// 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 gatewayapi
+
+import (
+ "errors"
+ "fmt"
+ "math"
+ "math/big"
+ "strings"
+ "time"
+
+ perr "github.com/pkg/errors"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/util/sets"
+ "k8s.io/utils/ptr"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/ir"
+)
+
+func translateTrafficFeatures(policy *egv1a1.ClusterSettings) (*ir.TrafficFeatures, error) {
+ if policy == nil {
+ return nil, nil
+ }
+ ret := &ir.TrafficFeatures{}
+
+ if timeout, err := buildTimeout(*policy, nil); err != nil {
+ return nil, err
+ } else {
+ ret.Timeout = timeout
+ }
+
+ if bc, err := buildBackendConnection(*policy); err != nil {
+ return nil, err
+ } else {
+ ret.BackendConnection = bc
+ }
+
+ if ka, err := buildTCPKeepAlive(*policy); err != nil {
+ return nil, err
+ } else {
+ ret.TCPKeepalive = ka
+ }
+
+ if cb, err := buildCircuitBreaker(*policy); err != nil {
+ return nil, err
+ } else {
+ ret.CircuitBreaker = cb
+ }
+
+ if lb, err := buildLoadBalancer(*policy); err != nil {
+ return nil, err
+ } else {
+ ret.LoadBalancer = lb
+ }
+
+ ret.ProxyProtocol = buildProxyProtocol(*policy)
+
+ ret.HealthCheck = buildHealthCheck(*policy)
+
+ ret.DNS = translateDNS(*policy)
+
+ if h2, err := buildIRHTTP2Settings(policy.HTTP2); err != nil {
+ return nil, err
+ } else {
+ ret.HTTP2 = h2
+ }
+
+ // If nothing was set in any of the above calls, return nil instead of an empty
+ // container
+ var empty ir.TrafficFeatures
+ if empty == *ret {
+ ret = nil
+ }
+
+ return ret, nil
+}
+
+func buildTimeout(policy egv1a1.ClusterSettings, r *ir.HTTPRoute) (*ir.Timeout, error) {
+ if policy.Timeout == nil {
+ return nil, nil
+ }
+ var (
+ tto *ir.TCPTimeout
+ hto *ir.HTTPTimeout
+ terr bool
+ errs error
+ )
+
+ pto := policy.Timeout
+
+ if pto.TCP != nil && pto.TCP.ConnectTimeout != nil {
+ d, err := time.ParseDuration(string(*pto.TCP.ConnectTimeout))
+ if err != nil {
+ terr = true
+ errs = errors.Join(errs, fmt.Errorf("invalid ConnectTimeout value %s", *pto.TCP.ConnectTimeout))
+ } else {
+ tto = &ir.TCPTimeout{
+ ConnectTimeout: ptr.To(metav1.Duration{Duration: d}),
+ }
+ }
+ }
+
+ if pto.HTTP != nil {
+ var cit *metav1.Duration
+ var mcd *metav1.Duration
+
+ if pto.HTTP.ConnectionIdleTimeout != nil {
+ d, err := time.ParseDuration(string(*pto.HTTP.ConnectionIdleTimeout))
+ if err != nil {
+ terr = true
+ errs = errors.Join(errs, fmt.Errorf("invalid ConnectionIdleTimeout value %s", *pto.HTTP.ConnectionIdleTimeout))
+ } else {
+ cit = ptr.To(metav1.Duration{Duration: d})
+ }
+ }
+
+ if pto.HTTP.MaxConnectionDuration != nil {
+ d, err := time.ParseDuration(string(*pto.HTTP.MaxConnectionDuration))
+ if err != nil {
+ terr = true
+ errs = errors.Join(errs, fmt.Errorf("invalid MaxConnectionDuration value %s", *pto.HTTP.MaxConnectionDuration))
+ } else {
+ mcd = ptr.To(metav1.Duration{Duration: d})
+ }
+ }
+
+ hto = &ir.HTTPTimeout{
+ ConnectionIdleTimeout: cit,
+ MaxConnectionDuration: mcd,
+ }
+ }
+
+ // http request timeout is translated during the gateway-api route resource translation
+ // merge route timeout setting with backendtrafficpolicy timeout settings
+ if terr {
+ if r != nil && r.Traffic != nil && r.Traffic.Timeout != nil {
+ return r.Traffic.Timeout.DeepCopy(), errs
+ }
+ } else {
+ // http request timeout is translated during the gateway-api route resource translation
+ // merge route timeout setting with backendtrafficpolicy timeout settings
+ if r != nil &&
+ r.Traffic != nil &&
+ r.Traffic.Timeout != nil &&
+ r.Traffic.Timeout.HTTP != nil &&
+ r.Traffic.Timeout.HTTP.RequestTimeout != nil {
+ if hto == nil {
+ hto = &ir.HTTPTimeout{
+ RequestTimeout: r.Traffic.Timeout.HTTP.RequestTimeout,
+ }
+ } else {
+ hto.RequestTimeout = r.Traffic.Timeout.HTTP.RequestTimeout
+ }
+ }
+
+ if hto != nil || tto != nil {
+ return &ir.Timeout{
+ TCP: tto,
+ HTTP: hto,
+ }, nil
+ }
+ }
+
+ return nil, errs
+}
+
+func buildBackendConnection(policy egv1a1.ClusterSettings) (*ir.BackendConnection, error) {
+ if policy.Connection == nil {
+ return nil, nil
+ }
+ var (
+ bcIR = &ir.BackendConnection{}
+ bc = &egv1a1.BackendConnection{}
+ )
+
+ if policy.Connection != nil {
+ bc = policy.Connection
+
+ if bc.BufferLimit != nil {
+ bf, ok := bc.BufferLimit.AsInt64()
+ if !ok {
+ return nil, fmt.Errorf("invalid BufferLimit value %s", bc.BufferLimit.String())
+ }
+ if bf < 0 || bf > math.MaxUint32 {
+ return nil, fmt.Errorf("BufferLimit value %s is out of range", bc.BufferLimit.String())
+ }
+
+ bcIR.BufferLimitBytes = ptr.To(uint32(bf))
+ }
+ }
+
+ return bcIR, nil
+}
+
+func buildTCPKeepAlive(policy egv1a1.ClusterSettings) (*ir.TCPKeepalive, error) {
+ if policy.TCPKeepalive == nil {
+ return nil, nil
+ }
+
+ pka := policy.TCPKeepalive
+ ka := &ir.TCPKeepalive{}
+
+ if pka.Probes != nil {
+ ka.Probes = pka.Probes
+ }
+
+ if pka.IdleTime != nil {
+ d, err := time.ParseDuration(string(*pka.IdleTime))
+ if err != nil {
+ return nil, fmt.Errorf("invalid IdleTime value %s", *pka.IdleTime)
+ }
+ ka.IdleTime = ptr.To(uint32(d.Seconds()))
+ }
+
+ if pka.Interval != nil {
+ d, err := time.ParseDuration(string(*pka.Interval))
+ if err != nil {
+ return nil, fmt.Errorf("invalid Interval value %s", *pka.Interval)
+ }
+ ka.Interval = ptr.To(uint32(d.Seconds()))
+ }
+ return ka, nil
+}
+
+func buildCircuitBreaker(policy egv1a1.ClusterSettings) (*ir.CircuitBreaker, error) {
+ if policy.CircuitBreaker == nil {
+ return nil, nil
+ }
+
+ var cb *ir.CircuitBreaker
+ pcb := policy.CircuitBreaker
+
+ if pcb != nil {
+ cb = &ir.CircuitBreaker{}
+
+ if pcb.MaxConnections != nil {
+ if ui32, ok := int64ToUint32(*pcb.MaxConnections); ok {
+ cb.MaxConnections = &ui32
+ } else {
+ return nil, fmt.Errorf("invalid MaxConnections value %d", *pcb.MaxConnections)
+ }
+ }
+
+ if pcb.MaxParallelRequests != nil {
+ if ui32, ok := int64ToUint32(*pcb.MaxParallelRequests); ok {
+ cb.MaxParallelRequests = &ui32
+ } else {
+ return nil, fmt.Errorf("invalid MaxParallelRequests value %d", *pcb.MaxParallelRequests)
+ }
+ }
+
+ if pcb.MaxPendingRequests != nil {
+ if ui32, ok := int64ToUint32(*pcb.MaxPendingRequests); ok {
+ cb.MaxPendingRequests = &ui32
+ } else {
+ return nil, fmt.Errorf("invalid MaxPendingRequests value %d", *pcb.MaxPendingRequests)
+ }
+ }
+
+ if pcb.MaxParallelRetries != nil {
+ if ui32, ok := int64ToUint32(*pcb.MaxParallelRetries); ok {
+ cb.MaxParallelRetries = &ui32
+ } else {
+ return nil, fmt.Errorf("invalid MaxParallelRetries value %d", *pcb.MaxParallelRetries)
+ }
+ }
+
+ if pcb.MaxRequestsPerConnection != nil {
+ if ui32, ok := int64ToUint32(*pcb.MaxRequestsPerConnection); ok {
+ cb.MaxRequestsPerConnection = &ui32
+ } else {
+ return nil, fmt.Errorf("invalid MaxRequestsPerConnection value %d", *pcb.MaxRequestsPerConnection)
+ }
+ }
+
+ }
+
+ return cb, nil
+}
+
+func buildLoadBalancer(policy egv1a1.ClusterSettings) (*ir.LoadBalancer, error) {
+ if policy.LoadBalancer == nil {
+ return nil, nil
+ }
+ var lb *ir.LoadBalancer
+ switch policy.LoadBalancer.Type {
+ case egv1a1.ConsistentHashLoadBalancerType:
+ consistentHash, err := buildConsistentHashLoadBalancer(*policy.LoadBalancer)
+ if err != nil {
+ return nil, perr.WithMessage(err, "ConsistentHash")
+ }
+
+ lb = &ir.LoadBalancer{
+ ConsistentHash: consistentHash,
+ }
+ case egv1a1.LeastRequestLoadBalancerType:
+ lb = &ir.LoadBalancer{}
+ if policy.LoadBalancer.SlowStart != nil {
+ if policy.LoadBalancer.SlowStart.Window != nil {
+ lb.LeastRequest = &ir.LeastRequest{
+ SlowStart: &ir.SlowStart{
+ Window: policy.LoadBalancer.SlowStart.Window,
+ },
+ }
+ }
+ }
+ case egv1a1.RandomLoadBalancerType:
+ lb = &ir.LoadBalancer{
+ Random: &ir.Random{},
+ }
+ case egv1a1.RoundRobinLoadBalancerType:
+ lb = &ir.LoadBalancer{
+ RoundRobin: &ir.RoundRobin{
+ SlowStart: &ir.SlowStart{},
+ },
+ }
+ if policy.LoadBalancer.SlowStart != nil {
+ if policy.LoadBalancer.SlowStart.Window != nil {
+ lb.RoundRobin = &ir.RoundRobin{
+ SlowStart: &ir.SlowStart{
+ Window: policy.LoadBalancer.SlowStart.Window,
+ },
+ }
+ }
+ }
+ }
+
+ return lb, nil
+}
+
+func buildConsistentHashLoadBalancer(policy egv1a1.LoadBalancer) (*ir.ConsistentHash, error) {
+ consistentHash := &ir.ConsistentHash{}
+
+ if policy.ConsistentHash.TableSize != nil {
+ tableSize := policy.ConsistentHash.TableSize
+
+ if *tableSize > MaxConsistentHashTableSize || !big.NewInt(int64(*tableSize)).ProbablyPrime(0) {
+ return nil, fmt.Errorf("invalid TableSize value %d", *tableSize)
+ }
+
+ consistentHash.TableSize = tableSize
+ }
+
+ switch policy.ConsistentHash.Type {
+ case egv1a1.SourceIPConsistentHashType:
+ consistentHash.SourceIP = ptr.To(true)
+ case egv1a1.HeaderConsistentHashType:
+ consistentHash.Header = &ir.Header{
+ Name: policy.ConsistentHash.Header.Name,
+ }
+ case egv1a1.CookieConsistentHashType:
+ consistentHash.Cookie = policy.ConsistentHash.Cookie
+ }
+
+ return consistentHash, nil
+}
+
+func buildProxyProtocol(policy egv1a1.ClusterSettings) *ir.ProxyProtocol {
+ if policy.ProxyProtocol == nil {
+ return nil
+ }
+ var pp *ir.ProxyProtocol
+ switch policy.ProxyProtocol.Version {
+ case egv1a1.ProxyProtocolVersionV1:
+ pp = &ir.ProxyProtocol{
+ Version: ir.ProxyProtocolVersionV1,
+ }
+ case egv1a1.ProxyProtocolVersionV2:
+ pp = &ir.ProxyProtocol{
+ Version: ir.ProxyProtocolVersionV2,
+ }
+ }
+
+ return pp
+}
+
+func buildHealthCheck(policy egv1a1.ClusterSettings) *ir.HealthCheck {
+ if policy.HealthCheck == nil {
+ return nil
+ }
+
+ irhc := &ir.HealthCheck{}
+ irhc.Passive = buildPassiveHealthCheck(*policy.HealthCheck)
+ irhc.Active = buildActiveHealthCheck(*policy.HealthCheck)
+
+ return irhc
+}
+
+func buildPassiveHealthCheck(policy egv1a1.HealthCheck) *ir.OutlierDetection {
+ if policy.Passive == nil {
+ return nil
+ }
+
+ hc := policy.Passive
+ irOD := &ir.OutlierDetection{
+ Interval: hc.Interval,
+ SplitExternalLocalOriginErrors: hc.SplitExternalLocalOriginErrors,
+ ConsecutiveLocalOriginFailures: hc.ConsecutiveLocalOriginFailures,
+ ConsecutiveGatewayErrors: hc.ConsecutiveGatewayErrors,
+ Consecutive5xxErrors: hc.Consecutive5xxErrors,
+ BaseEjectionTime: hc.BaseEjectionTime,
+ MaxEjectionPercent: hc.MaxEjectionPercent,
+ }
+ return irOD
+}
+
+func buildActiveHealthCheck(policy egv1a1.HealthCheck) *ir.ActiveHealthCheck {
+ if policy.Active == nil {
+ return nil
+ }
+
+ hc := policy.Active
+ irHC := &ir.ActiveHealthCheck{
+ Timeout: hc.Timeout,
+ Interval: hc.Interval,
+ UnhealthyThreshold: hc.UnhealthyThreshold,
+ HealthyThreshold: hc.HealthyThreshold,
+ }
+ switch hc.Type {
+ case egv1a1.ActiveHealthCheckerTypeHTTP:
+ irHC.HTTP = buildHTTPActiveHealthChecker(hc.HTTP)
+ case egv1a1.ActiveHealthCheckerTypeTCP:
+ irHC.TCP = buildTCPActiveHealthChecker(hc.TCP)
+ case egv1a1.ActiveHealthCheckerTypeGRPC:
+ irHC.GRPC = &ir.GRPCHealthChecker{
+ Service: ptr.Deref(hc.GRPC, egv1a1.GRPCActiveHealthChecker{}).Service,
+ }
+ }
+
+ return irHC
+}
+
+func buildHTTPActiveHealthChecker(h *egv1a1.HTTPActiveHealthChecker) *ir.HTTPHealthChecker {
+ if h == nil {
+ return nil
+ }
+
+ irHTTP := &ir.HTTPHealthChecker{
+ Path: h.Path,
+ Method: h.Method,
+ }
+ if irHTTP.Method != nil {
+ *irHTTP.Method = strings.ToUpper(*irHTTP.Method)
+ }
+
+ // deduplicate http statuses
+ statusSet := sets.NewInt()
+ for _, r := range h.ExpectedStatuses {
+ statusSet.Insert(int(r))
+ }
+ irStatuses := make([]ir.HTTPStatus, 0, statusSet.Len())
+
+ for _, r := range statusSet.List() {
+ irStatuses = append(irStatuses, ir.HTTPStatus(r))
+ }
+ irHTTP.ExpectedStatuses = irStatuses
+
+ irHTTP.ExpectedResponse = translateActiveHealthCheckPayload(h.ExpectedResponse)
+ return irHTTP
+}
+
+func buildTCPActiveHealthChecker(h *egv1a1.TCPActiveHealthChecker) *ir.TCPHealthChecker {
+ if h == nil {
+ return nil
+ }
+
+ irTCP := &ir.TCPHealthChecker{
+ Send: translateActiveHealthCheckPayload(h.Send),
+ Receive: translateActiveHealthCheckPayload(h.Receive),
+ }
+ return irTCP
+}
+
+func translateActiveHealthCheckPayload(p *egv1a1.ActiveHealthCheckPayload) *ir.HealthCheckPayload {
+ if p == nil {
+ return nil
+ }
+
+ irPayload := &ir.HealthCheckPayload{}
+ switch p.Type {
+ case egv1a1.ActiveHealthCheckPayloadTypeText:
+ irPayload.Text = p.Text
+ case egv1a1.ActiveHealthCheckPayloadTypeBinary:
+ irPayload.Binary = make([]byte, len(p.Binary))
+ copy(irPayload.Binary, p.Binary)
+ }
+
+ return irPayload
+}
+
+func translateDNS(policy egv1a1.ClusterSettings) *ir.DNS {
+ if policy.DNS == nil {
+ return nil
+ }
+ return &ir.DNS{
+ RespectDNSTTL: policy.DNS.RespectDNSTTL,
+ DNSRefreshRate: policy.DNS.DNSRefreshRate,
+ }
+}
diff --git a/internal/gatewayapi/conformance/suite.go b/internal/gatewayapi/conformance/suite.go
index 4637e023779..4fafa008983 100644
--- a/internal/gatewayapi/conformance/suite.go
+++ b/internal/gatewayapi/conformance/suite.go
@@ -15,7 +15,6 @@ import (
// SkipTests is a list of tests that are skipped in the conformance suite.
var SkipTests = []suite.ConformanceTest{
tests.GatewayStaticAddresses,
- tests.GatewayHTTPListenerIsolation, // https://github.com/envoyproxy/gateway/issues/3352
}
func skipTestsShortNames(skipTests []suite.ConformanceTest) []string {
diff --git a/internal/gatewayapi/envoyextensionpolicy.go b/internal/gatewayapi/envoyextensionpolicy.go
index 5f871a6f8c0..5cbe148db2c 100644
--- a/internal/gatewayapi/envoyextensionpolicy.go
+++ b/internal/gatewayapi/envoyextensionpolicy.go
@@ -439,7 +439,7 @@ func (t *Translator) buildExtProc(
}
ds, err = t.processExtServiceDestination(
- &extProc.BackendRefs[i].BackendObjectReference,
+ &extProc.BackendRefs[i],
policyNamespacedName,
egv1a1.KindEnvoyExtensionPolicy,
ir.GRPC,
@@ -471,9 +471,15 @@ func (t *Translator) buildExtProc(
NamespaceDerefOr(extProc.BackendRefs[0].Namespace, policyNamespacedName.Namespace))
}
+ traffic, err := translateTrafficFeatures(extProc.BackendCluster.BackendSettings)
+ if err != nil {
+ return nil, err
+ }
+
extProcIR := &ir.ExtProc{
Name: name,
Destination: rd,
+ Traffic: traffic,
Authority: authority,
}
diff --git a/internal/gatewayapi/envoypatchpolicy.go b/internal/gatewayapi/envoypatchpolicy.go
index 9ea9102ac76..5d2480f5d23 100644
--- a/internal/gatewayapi/envoypatchpolicy.go
+++ b/internal/gatewayapi/envoypatchpolicy.go
@@ -114,6 +114,7 @@ func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.Envo
irPatch.Name = patch.Name
irPatch.Operation.Op = string(patch.Operation.Op)
irPatch.Operation.Path = patch.Operation.Path
+ irPatch.Operation.JSONPath = patch.Operation.JSONPath
irPatch.Operation.From = patch.Operation.From
irPatch.Operation.Value = patch.Operation.Value
diff --git a/internal/gatewayapi/ext_service.go b/internal/gatewayapi/ext_service.go
index d0c50e5f97e..65cf4c2cce8 100644
--- a/internal/gatewayapi/ext_service.go
+++ b/internal/gatewayapi/ext_service.go
@@ -21,7 +21,7 @@ import (
// TODO: zhaohuabing combine this function with the one in the route translator
func (t *Translator) processExtServiceDestination(
- backendRef *gwapiv1.BackendObjectReference,
+ backendRef *egv1a1.BackendRef,
policyNamespacedName types.NamespacedName,
policyKind string,
protocol ir.AppProtocol,
@@ -37,12 +37,12 @@ func (t *Translator) processExtServiceDestination(
switch KindDerefOr(backendRef.Kind, KindService) {
case KindService:
- ds = t.processServiceDestinationSetting(*backendRef, backendNamespace, protocol, resources, envoyProxy)
+ ds = t.processServiceDestinationSetting(backendRef.BackendObjectReference, backendNamespace, protocol, resources, envoyProxy)
case egv1a1.KindBackend:
if !t.BackendEnabled {
return nil, fmt.Errorf("resource %s of type Backend cannot be used since Backend is disabled in Envoy Gateway configuration", string(backendRef.Name))
}
- ds = t.processBackendDestinationSetting(*backendRef, backendNamespace, resources)
+ ds = t.processBackendDestinationSetting(backendRef.BackendObjectReference, backendNamespace, resources)
ds.Protocol = protocol
}
@@ -58,7 +58,7 @@ func (t *Translator) processExtServiceDestination(
}
backendTLS = t.applyBackendTLSSetting(
- *backendRef,
+ backendRef.BackendObjectReference,
backendNamespace,
// Gateway is not the appropriate parent reference here because the owner
// of the BackendRef is the policy, and there is no hierarchy
@@ -78,7 +78,12 @@ func (t *Translator) processExtServiceDestination(
// TODO: support weighted non-xRoute backends
ds.Weight = ptr.To(uint32(1))
-
+ if backendRef.Failover != nil {
+ // set only the secondary priority, the backend defaults to a primary priority if unset.
+ if ptr.Deref(backendRef.Failover, false) {
+ ds.Priority = ptr.To(uint32(1))
+ }
+ }
return ds, nil
}
diff --git a/internal/gatewayapi/filters.go b/internal/gatewayapi/filters.go
index b3d2ddb4074..aecc2e81131 100644
--- a/internal/gatewayapi/filters.go
+++ b/internal/gatewayapi/filters.go
@@ -445,7 +445,7 @@ func (t *Translator) processRequestHeaderModifierFilter(
newHeader := ir.AddHeader{
Name: headerKey,
Append: true,
- Value: addHeader.Value,
+ Value: strings.Split(addHeader.Value, ","),
}
filterContext.AddRequestHeaders = append(filterContext.AddRequestHeaders, newHeader)
@@ -500,7 +500,7 @@ func (t *Translator) processRequestHeaderModifierFilter(
newHeader := ir.AddHeader{
Name: string(setHeader.Name),
Append: false,
- Value: setHeader.Value,
+ Value: strings.Split(setHeader.Value, ","),
}
filterContext.AddRequestHeaders = append(filterContext.AddRequestHeaders, newHeader)
@@ -617,7 +617,7 @@ func (t *Translator) processResponseHeaderModifierFilter(
newHeader := ir.AddHeader{
Name: headerKey,
Append: true,
- Value: addHeader.Value,
+ Value: strings.Split(addHeader.Value, ","),
}
filterContext.AddResponseHeaders = append(filterContext.AddResponseHeaders, newHeader)
@@ -672,7 +672,7 @@ func (t *Translator) processResponseHeaderModifierFilter(
newHeader := ir.AddHeader{
Name: string(setHeader.Name),
Append: false,
- Value: setHeader.Value,
+ Value: strings.Split(setHeader.Value, ","),
}
filterContext.AddResponseHeaders = append(filterContext.AddResponseHeaders, newHeader)
diff --git a/internal/gatewayapi/helpers.go b/internal/gatewayapi/helpers.go
index 22c81032ebb..52df40f4736 100644
--- a/internal/gatewayapi/helpers.go
+++ b/internal/gatewayapi/helpers.go
@@ -262,12 +262,12 @@ func servicePortToContainerPort(servicePort int32, envoyProxy *egv1a1.EnvoyProxy
return servicePort
}
-// computeHosts returns a list of the intersecting hostnames between the route
-// and the listener.
-func computeHosts(routeHostnames []string, listenerHostname *gwapiv1.Hostname) []string {
+// computeHosts returns a list of intersecting listener hostnames and route hostnames
+// that don't intersect with other listener hostnames.
+func computeHosts(routeHostnames []string, listenerContext *ListenerContext) []string {
var listenerHostnameVal string
- if listenerHostname != nil {
- listenerHostnameVal = string(*listenerHostname)
+ if listenerContext != nil && listenerContext.Hostname != nil {
+ listenerHostnameVal = string(*listenerContext.Hostname)
}
// No route hostnames specified: use the listener hostname if specified,
@@ -280,8 +280,9 @@ func computeHosts(routeHostnames []string, listenerHostname *gwapiv1.Hostname) [
return []string{"*"}
}
- var hostnames []string
+ hostnamesSet := sets.NewString()
+ // Find intersecting hostnames
for i := range routeHostnames {
routeHostname := routeHostnames[i]
@@ -290,28 +291,47 @@ func computeHosts(routeHostnames []string, listenerHostname *gwapiv1.Hostname) [
switch {
// No listener hostname: use the route hostname.
case len(listenerHostnameVal) == 0:
- hostnames = append(hostnames, routeHostname)
+ hostnamesSet.Insert(routeHostname)
// Listener hostname matches the route hostname: use it.
case listenerHostnameVal == routeHostname:
- hostnames = append(hostnames, routeHostname)
+ hostnamesSet.Insert(routeHostname)
// Listener has a wildcard hostname: check if the route hostname matches.
case strings.HasPrefix(listenerHostnameVal, "*"):
if hostnameMatchesWildcardHostname(routeHostname, listenerHostnameVal) {
- hostnames = append(hostnames, routeHostname)
+ hostnamesSet.Insert(routeHostname)
}
// Route has a wildcard hostname: check if the listener hostname matches.
case strings.HasPrefix(routeHostname, "*"):
if hostnameMatchesWildcardHostname(listenerHostnameVal, routeHostname) {
- hostnames = append(hostnames, listenerHostnameVal)
+ hostnamesSet.Insert(listenerHostnameVal)
}
}
}
- return hostnames
+ // Filter out route hostnames that intersect with other listener hostnames
+ var listeners []*ListenerContext
+ if listenerContext != nil && listenerContext.gateway != nil {
+ listeners = listenerContext.gateway.listeners
+ }
+
+ for _, listener := range listeners {
+ if listenerContext == listener {
+ continue
+ }
+ if listenerContext != nil && listenerContext.Port != listener.Port {
+ continue
+ }
+ if listener.Hostname == nil {
+ continue
+ }
+ hostnamesSet.Delete(string(*listener.Hostname))
+ }
+
+ return hostnamesSet.List()
}
// hostnameMatchesWildcardHostname returns true if hostname has the non-wildcard
@@ -560,3 +580,10 @@ func getPolicyTargetRefs[T client.Object](policy egv1a1.PolicyTargetReferences,
return ret
}
+
+// Sets *target to value if and only if *target is nil
+func setIfNil[T any](target **T, value *T) {
+ if *target == nil {
+ *target = value
+ }
+}
diff --git a/internal/gatewayapi/helpers_test.go b/internal/gatewayapi/helpers_test.go
index a6469715f4d..5698867c3ca 100644
--- a/internal/gatewayapi/helpers_test.go
+++ b/internal/gatewayapi/helpers_test.go
@@ -97,7 +97,6 @@ func TestValidateGRPCFilterRef(t *testing.T) {
},
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
err := ValidateGRPCRouteFilter(tc.filter, schema.GroupKind{Group: "example.io", Kind: "Foo"})
if tc.expected {
@@ -189,7 +188,6 @@ func TestValidateHTTPFilterRef(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
err := ValidateHTTPRouteFilter(tc.filter, schema.GroupKind{Group: "example.io", Kind: "Foo"})
if tc.expected {
@@ -479,7 +477,6 @@ func TestGetPolicyTargetRefs(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
results := getPolicyTargetRefs(tc.policy, tc.targets)
require.ElementsMatch(t, results, tc.results)
diff --git a/internal/gatewayapi/http.go b/internal/gatewayapi/http.go
index 95b0cd6310e..e54b3f761d7 100644
--- a/internal/gatewayapi/http.go
+++ b/internal/gatewayapi/http.go
@@ -23,6 +23,9 @@ const (
)
func buildIRHTTP2Settings(http2Settings *egv1a1.HTTP2Settings) (*ir.HTTP2Settings, error) {
+ if http2Settings == nil {
+ return nil, nil
+ }
var (
http2 = &ir.HTTP2Settings{}
errs error
diff --git a/internal/gatewayapi/listener.go b/internal/gatewayapi/listener.go
index adbd302b957..b63645a85e1 100644
--- a/internal/gatewayapi/listener.go
+++ b/internal/gatewayapi/listener.go
@@ -313,7 +313,7 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
}
// TODO: how to get authority from the backendRefs?
- ds, err := t.processBackendRefs(sink.ALS.BackendRefs, envoyproxy.Namespace, resources, envoyproxy)
+ ds, traffic, err := t.processBackendRefs(sink.ALS.BackendCluster, envoyproxy.Namespace, resources, envoyproxy)
if err != nil {
return nil, err
}
@@ -324,6 +324,7 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
Name: fmt.Sprintf("accesslog_als_%d_%d", i, j), // TODO: rename this, so that we can share backend with tracing?
Settings: ds,
},
+ Traffic: traffic,
Type: sink.ALS.Type,
CELMatches: validExprs,
}
@@ -350,20 +351,20 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources *
continue
}
- // TODO: remove support for Host/Port in v1.2
- al := &ir.OpenTelemetryAccessLog{
- CELMatches: validExprs,
- Resources: sink.OpenTelemetry.Resources,
- }
-
// TODO: how to get authority from the backendRefs?
- ds, err := t.processBackendRefs(sink.OpenTelemetry.BackendRefs, envoyproxy.Namespace, resources, envoyproxy)
+ ds, traffic, err := t.processBackendRefs(sink.OpenTelemetry.BackendCluster, envoyproxy.Namespace, resources, envoyproxy)
if err != nil {
return nil, err
}
- al.Destination = ir.RouteDestination{
- Name: fmt.Sprintf("accesslog_otel_%d_%d", i, j), // TODO: rename this, so that we can share backend with tracing?
- Settings: ds,
+ // TODO: remove support for Host/Port in v1.2
+ al := &ir.OpenTelemetryAccessLog{
+ CELMatches: validExprs,
+ Resources: sink.OpenTelemetry.Resources,
+ Destination: ir.RouteDestination{
+ Name: fmt.Sprintf("accesslog_otel_%d_%d", i, j), // TODO: rename this, so that we can share backend with tracing?
+ Settings: ds,
+ },
+ Traffic: traffic,
}
if len(ds) == 0 {
@@ -401,7 +402,7 @@ func (t *Translator) processTracing(gw *gwapiv1.Gateway, envoyproxy *egv1a1.Envo
tracing := envoyproxy.Spec.Telemetry.Tracing
// TODO: how to get authority from the backendRefs?
- ds, err := t.processBackendRefs(tracing.Provider.BackendRefs, envoyproxy.Namespace, resources, envoyproxy)
+ ds, traffic, err := t.processBackendRefs(tracing.Provider.BackendCluster, envoyproxy.Namespace, resources, envoyproxy)
if err != nil {
return nil, err
}
@@ -440,6 +441,7 @@ func (t *Translator) processTracing(gw *gwapiv1.Gateway, envoyproxy *egv1a1.Envo
Settings: ds,
},
Provider: tracing.Provider,
+ Traffic: traffic,
}, nil
}
@@ -455,7 +457,7 @@ func (t *Translator) processMetrics(envoyproxy *egv1a1.EnvoyProxy, resources *Re
continue
}
- _, err := t.processBackendRefs(sink.OpenTelemetry.BackendRefs, envoyproxy.Namespace, resources, envoyproxy)
+ _, _, err := t.processBackendRefs(sink.OpenTelemetry.BackendCluster, envoyproxy.Namespace, resources, envoyproxy)
if err != nil {
return nil, err
}
@@ -467,25 +469,29 @@ func (t *Translator) processMetrics(envoyproxy *egv1a1.EnvoyProxy, resources *Re
}, nil
}
-func (t *Translator) processBackendRefs(backendRefs []egv1a1.BackendRef, namespace string, resources *Resources, envoyProxy *egv1a1.EnvoyProxy) ([]*ir.DestinationSetting, error) {
- result := make([]*ir.DestinationSetting, 0, len(backendRefs))
- for _, ref := range backendRefs {
+func (t *Translator) processBackendRefs(backendCluster egv1a1.BackendCluster, namespace string, resources *Resources, envoyProxy *egv1a1.EnvoyProxy) ([]*ir.DestinationSetting, *ir.TrafficFeatures, error) {
+ traffic, err := translateTrafficFeatures(backendCluster.BackendSettings)
+ if err != nil {
+ return nil, nil, err
+ }
+ result := make([]*ir.DestinationSetting, 0, len(backendCluster.BackendRefs))
+ for _, ref := range backendCluster.BackendRefs {
ns := NamespaceDerefOr(ref.Namespace, namespace)
kind := KindDerefOr(ref.Kind, KindService)
if kind != KindService {
- return nil, errors.New("only service kind is supported for backendRefs")
+ return nil, nil, errors.New("only service kind is supported for backendRefs")
}
if err := validateBackendService(ref.BackendObjectReference, resources, ns, corev1.ProtocolTCP); err != nil {
- return nil, err
+ return nil, nil, err
}
ds := t.processServiceDestinationSetting(ref.BackendObjectReference, ns, ir.TCP, resources, envoyProxy)
result = append(result, ds)
}
if len(result) == 0 {
- return nil, nil
+ return nil, traffic, nil
}
- return result, nil
+ return result, traffic, nil
}
func destinationSettingFromHostAndPort(host string, port uint32) []*ir.DestinationSetting {
diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go
index 336e931cfce..9325621468e 100644
--- a/internal/gatewayapi/route.go
+++ b/internal/gatewayapi/route.go
@@ -196,7 +196,6 @@ func (t *Translator) processHTTPRouteRules(httpRoute *HTTPRouteContext, parentRe
dstAddrTypeMap := make(map[ir.DestinationAddressType]int)
for _, backendRef := range rule.BackendRefs {
- backendRef := backendRef
ds := t.processDestination(backendRef, parentRef, httpRoute, resources)
if !t.IsEnvoyServiceRouting(envoyProxy) && ds != nil && len(ds.Endpoints) > 0 && ds.AddressType != nil {
@@ -314,12 +313,60 @@ func (t *Translator) processHTTPRouteRule(httpRoute *HTTPRouteContext, ruleIdx i
ruleRoutes = append(ruleRoutes, irRoute)
}
+ var sessionPersistence *ir.SessionPersistence
+ if rule.SessionPersistence != nil {
+ if rule.SessionPersistence.IdleTimeout != nil {
+ return nil, fmt.Errorf("idle timeout is not supported in envoy gateway")
+ }
+
+ var sessionName string
+ if rule.SessionPersistence.SessionName == nil {
+ // SessionName is optional on the gateway-api, but envoy requires it
+ // so we generate the one here.
+
+ // We generate a unique session name per route.
+ // `/` isn't allowed in the header key, so we just replace it with `-`.
+ sessionName = strings.ReplaceAll(irRouteDestinationName(httpRoute, ruleIdx), "/", "-")
+ } else {
+ sessionName = *rule.SessionPersistence.SessionName
+ }
+
+ switch {
+ case rule.SessionPersistence.Type == nil || // Cookie-based session persistence is default.
+ *rule.SessionPersistence.Type == gwapiv1.CookieBasedSessionPersistence:
+ sessionPersistence = &ir.SessionPersistence{
+ Cookie: &ir.CookieBasedSessionPersistence{
+ Name: sessionName,
+ },
+ }
+ if rule.SessionPersistence.AbsoluteTimeout != nil &&
+ rule.SessionPersistence.CookieConfig != nil && rule.SessionPersistence.CookieConfig.LifetimeType != nil &&
+ *rule.SessionPersistence.CookieConfig.LifetimeType == gwapiv1.PermanentCookieLifetimeType {
+ ttl, err := time.ParseDuration(string(*rule.SessionPersistence.AbsoluteTimeout))
+ if err != nil {
+ return nil, err
+ }
+ sessionPersistence.Cookie.TTL = &metav1.Duration{Duration: ttl}
+ }
+ case *rule.SessionPersistence.Type == gwapiv1.HeaderBasedSessionPersistence:
+ sessionPersistence = &ir.SessionPersistence{
+ Header: &ir.HeaderBasedSessionPersistence{
+ Name: sessionName,
+ },
+ }
+ default:
+ // Unknown session persistence type is specified.
+ return nil, fmt.Errorf("unknown session persistence type %s", *rule.SessionPersistence.Type)
+ }
+ }
+
// A rule is matched if any one of its matches
// is satisfied (i.e. a logical "OR"), so generate
// a unique Xds IR HTTPRoute per match.
for matchIdx, match := range rule.Matches {
irRoute := &ir.HTTPRoute{
- Name: irRouteName(httpRoute, ruleIdx, matchIdx),
+ Name: irRouteName(httpRoute, ruleIdx, matchIdx),
+ SessionPersistence: sessionPersistence,
}
processTimeout(irRoute, rule)
@@ -504,7 +551,6 @@ func (t *Translator) processGRPCRouteRules(grpcRoute *GRPCRouteContext, parentRe
}
for _, backendRef := range rule.BackendRefs {
- backendRef := backendRef
ds := t.processDestination(backendRef, parentRef, grpcRoute, resources)
if ds == nil {
continue
@@ -651,7 +697,7 @@ func (t *Translator) processHTTPRouteParentRefListener(route RouteContext, route
var hasHostnameIntersection bool
for _, listener := range parentRef.listeners {
- hosts := computeHosts(GetHostnames(route), listener.Hostname)
+ hosts := computeHosts(GetHostnames(route), listener)
if len(hosts) == 0 {
continue
}
@@ -699,6 +745,7 @@ func (t *Translator) processHTTPRouteParentRefListener(route RouteContext, route
Mirrors: routeRoute.Mirrors,
ExtensionRefs: routeRoute.ExtensionRefs,
IsHTTP2: routeRoute.IsHTTP2,
+ SessionPersistence: routeRoute.SessionPersistence,
}
if routeRoute.Traffic != nil {
hostRoute.Traffic = &ir.TrafficFeatures{
@@ -784,7 +831,6 @@ func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resour
// compute backends
for _, rule := range tlsRoute.Spec.Rules {
for _, backendRef := range rule.BackendRefs {
- backendRef := backendRef
ds := t.processDestination(backendRef, parentRef, tlsRoute, resources)
if ds != nil {
destSettings = append(destSettings, ds)
@@ -818,7 +864,7 @@ func (t *Translator) processTLSRouteParentRefs(tlsRoute *TLSRouteContext, resour
var hasHostnameIntersection bool
for _, listener := range parentRef.listeners {
- hosts := computeHosts(GetHostnames(tlsRoute), listener.Hostname)
+ hosts := computeHosts(GetHostnames(tlsRoute), listener)
if len(hosts) == 0 {
continue
}
@@ -1058,7 +1104,6 @@ func (t *Translator) processTCPRouteParentRefs(tcpRoute *TCPRouteContext, resour
}
for _, backendRef := range tcpRoute.Spec.Rules[0].BackendRefs {
- backendRef := backendRef
ds := t.processDestination(backendRef, parentRef, tcpRoute, resources)
if ds == nil {
continue
diff --git a/internal/gatewayapi/runner/runner.go b/internal/gatewayapi/runner/runner.go
index 8b9b57fc839..c9bdead8236 100644
--- a/internal/gatewayapi/runner/runner.go
+++ b/internal/gatewayapi/runner/runner.go
@@ -227,7 +227,6 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) {
// their target is not found (not relevant)
for _, backendTLSPolicy := range result.BackendTLSPolicies {
- backendTLSPolicy := backendTLSPolicy
key := utils.NamespacedName(backendTLSPolicy)
if !(reflect.ValueOf(backendTLSPolicy.Status).IsZero()) {
r.ProviderResources.BackendTLSPolicyStatuses.Store(key, &backendTLSPolicy.Status)
@@ -257,7 +256,6 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) {
delete(statusesToDelete.SecurityPolicyStatusKeys, key)
}
for _, envoyExtensionPolicy := range result.EnvoyExtensionPolicies {
- envoyExtensionPolicy := envoyExtensionPolicy
key := utils.NamespacedName(envoyExtensionPolicy)
if !(reflect.ValueOf(envoyExtensionPolicy.Status).IsZero()) {
r.ProviderResources.EnvoyExtensionPolicyStatuses.Store(key, &envoyExtensionPolicy.Status)
@@ -265,7 +263,6 @@ func (r *Runner) subscribeAndTranslate(ctx context.Context) {
delete(statusesToDelete.EnvoyExtensionPolicyStatusKeys, key)
}
for _, extServerPolicy := range result.ExtensionServerPolicies {
- extServerPolicy := extServerPolicy
key := message.NamespacedNameAndGVK{
NamespacedName: utils.NamespacedName(&extServerPolicy),
GroupVersionKind: extServerPolicy.GroupVersionKind(),
diff --git a/internal/gatewayapi/runner/runner_test.go b/internal/gatewayapi/runner/runner_test.go
index 5f3bc2a6544..502a96950fa 100644
--- a/internal/gatewayapi/runner/runner_test.go
+++ b/internal/gatewayapi/runner/runner_test.go
@@ -105,7 +105,6 @@ func TestGetIRKeysToDelete(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
assert.ElementsMatch(t, tc.delKeys, getIRKeysToDelete(tc.curKeys, tc.newKeys))
})
diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go
index d071e4ffdda..9940dbabefc 100644
--- a/internal/gatewayapi/securitypolicy.go
+++ b/internal/gatewayapi/securitypolicy.go
@@ -523,7 +523,6 @@ func (t *Translator) buildCORS(cors *egv1a1.CORS) *ir.CORS {
var allowOrigins []*ir.StringMatch
for _, origin := range cors.AllowOrigins {
- origin := origin
if isWildcard(string(origin)) {
regexStr := wildcard2regex(string(origin))
allowOrigins = append(allowOrigins, &ir.StringMatch{
@@ -813,6 +812,8 @@ func (t *Translator) buildExtAuth(policy *egv1a1.SecurityPolicy, resources *Reso
ds *ir.DestinationSetting
authority string
err error
+ traffic *ir.TrafficFeatures
+ failover *bool
)
switch {
@@ -824,14 +825,22 @@ func (t *Translator) buildExtAuth(policy *egv1a1.SecurityPolicy, resources *Reso
backendRef = http.BackendRef
if len(http.BackendRefs) != 0 {
backendRef = egv1a1.ToBackendObjectReference(http.BackendRefs[0])
+ failover = http.BackendRefs[0].Failover
}
protocol = ir.HTTP
+ if traffic, err = translateTrafficFeatures(http.BackendSettings); err != nil {
+ return nil, err
+ }
case grpc != nil:
backendRef = grpc.BackendRef
if len(grpc.BackendRefs) != 0 {
backendRef = egv1a1.ToBackendObjectReference(grpc.BackendRefs[0])
+ failover = grpc.BackendRefs[0].Failover
}
protocol = ir.GRPC
+ if traffic, err = translateTrafficFeatures(grpc.BackendSettings); err != nil {
+ return nil, err
+ }
// These are sanity checks, they should never happen because the API server
// should have caught them
default: // http == nil && grpc == nil:
@@ -841,14 +850,11 @@ func (t *Translator) buildExtAuth(policy *egv1a1.SecurityPolicy, resources *Reso
if err = t.validateExtServiceBackendReference(backendRef, policy.Namespace, policy.Kind, resources); err != nil {
return nil, err
}
- authority = fmt.Sprintf("%s.%s:%d",
- backendRef.Name,
- NamespaceDerefOr(backendRef.Namespace, policy.Namespace),
- *backendRef.Port)
+ authority = backendRefAuthority(resources, backendRef, policy)
pnn := utils.NamespacedName(policy)
if ds, err = t.processExtServiceDestination(
- backendRef,
+ &egv1a1.BackendRef{BackendObjectReference: *backendRef, Failover: failover},
pnn,
KindSecurityPolicy,
protocol,
@@ -866,6 +872,7 @@ func (t *Translator) buildExtAuth(policy *egv1a1.SecurityPolicy, resources *Reso
Name: irConfigName(policy),
HeadersToExtAuth: policy.Spec.ExtAuth.HeadersToExtAuth,
FailOpen: policy.Spec.ExtAuth.FailOpen,
+ Traffic: traffic,
}
if http != nil {
@@ -884,6 +891,31 @@ func (t *Translator) buildExtAuth(policy *egv1a1.SecurityPolicy, resources *Reso
return extAuth, nil
}
+func backendRefAuthority(resources *Resources, backendRef *gwapiv1.BackendObjectReference, policy *egv1a1.SecurityPolicy) string {
+ if backendRef == nil {
+ return ""
+ }
+
+ backendNamespace := NamespaceDerefOr(backendRef.Namespace, policy.Namespace)
+ backendKind := KindDerefOr(backendRef.Kind, KindService)
+ if backendKind == egv1a1.KindBackend {
+ backend := resources.GetBackend(backendNamespace, string(backendRef.Name))
+ if backend != nil {
+ // TODO: exists multi FQDN endpoints?
+ for _, ep := range backend.Spec.Endpoints {
+ if ep.FQDN != nil {
+ return fmt.Sprintf("%s:%d", ep.FQDN.Hostname, ep.FQDN.Port)
+ }
+ }
+ }
+ }
+
+ return fmt.Sprintf("%s.%s:%d",
+ backendRef.Name,
+ backendNamespace,
+ *backendRef.Port)
+}
+
func irExtServiceDestinationName(policy *egv1a1.SecurityPolicy, backendRef *gwapiv1.BackendObjectReference) string {
nn := types.NamespacedName{
Name: string(backendRef.Name),
diff --git a/internal/gatewayapi/status/gateway_test.go b/internal/gatewayapi/status/gateway_test.go
index 0be99b7d4bf..8c87c16190a 100644
--- a/internal/gatewayapi/status/gateway_test.go
+++ b/internal/gatewayapi/status/gateway_test.go
@@ -250,7 +250,6 @@ func TestUpdateGatewayProgrammedCondition(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
gtw := &gwapiv1.Gateway{}
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-dns-settings.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-dns-settings.out.yaml
index 89d9902328f..12bbf12dbe7 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-dns-settings.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-dns-settings.out.yaml
@@ -342,9 +342,6 @@ xdsIR:
port: 8080
protocol: HTTP
weight: 1
- dns:
- dnsRefreshRate: 10s
- respectDnsTtl: true
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
@@ -356,7 +353,10 @@ xdsIR:
distinct: false
name: ""
prefix: /v3
- traffic: {}
+ traffic:
+ dns:
+ dnsRefreshRate: 10s
+ respectDnsTtl: true
envoy-gateway/gateway-2:
accessLog:
text:
@@ -386,9 +386,6 @@ xdsIR:
port: 8080
protocol: HTTP
weight: 1
- dns:
- dnsRefreshRate: 5s
- respectDnsTtl: false
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
@@ -400,7 +397,10 @@ xdsIR:
distinct: false
name: ""
prefix: /v2
- traffic: {}
+ traffic:
+ dns:
+ dnsRefreshRate: 5s
+ respectDnsTtl: false
- destination:
name: httproute/default/httproute-1/rule/0
settings:
@@ -410,9 +410,6 @@ xdsIR:
port: 8080
protocol: HTTP
weight: 1
- dns:
- dnsRefreshRate: 1s
- respectDnsTtl: true
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
@@ -424,4 +421,7 @@ xdsIR:
distinct: false
name: ""
prefix: /
- traffic: {}
+ traffic:
+ dns:
+ dnsRefreshRate: 1s
+ respectDnsTtl: true
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.in.yaml
index 5cb832646b3..0ea537711d9 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.in.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.in.yaml
@@ -42,6 +42,34 @@ grpcRoutes:
- backendRefs:
- name: service-1
port: 8080
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ namespace: default
+ name: grpcroute-3
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-3
+ port: 8080
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ namespace: default
+ name: grpcroute-2
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-2
+ port: 8080
httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
@@ -233,3 +261,40 @@ backendTrafficPolicies:
consecutiveGatewayErrors: 0
consecutiveLocalOriginFailures: 5
splitExternalLocalOriginErrors: false
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: default
+ name: policy-for-grpc-route
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: GRPCRoute
+ name: grpcroute-2
+ healthCheck:
+ active:
+ timeout: 1s
+ interval: 3s
+ unhealthyThreshold: 3
+ healthyThreshold: 1
+ type: GRPC
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: default
+ name: policy-for-grpc-route-3
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: GRPCRoute
+ name: grpcroute-3
+ healthCheck:
+ active:
+ timeout: 1s
+ interval: 3s
+ unhealthyThreshold: 3
+ healthyThreshold: 1
+ type: GRPC
+ grpc:
+ service: foo-service
+
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml
index 447a7df485e..4d1cc89bc55 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml
@@ -145,6 +145,74 @@ backendTrafficPolicies:
status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-grpc-route
+ namespace: default
+ spec:
+ healthCheck:
+ active:
+ healthyThreshold: 1
+ interval: 3s
+ timeout: 1s
+ type: GRPC
+ unhealthyThreshold: 3
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: GRPCRoute
+ name: grpcroute-2
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-grpc-route-3
+ namespace: default
+ spec:
+ healthCheck:
+ active:
+ grpc:
+ service: foo-service
+ healthyThreshold: 1
+ interval: 3s
+ timeout: 1s
+ type: GRPC
+ unhealthyThreshold: 3
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: GRPCRoute
+ name: grpcroute-3
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
@@ -193,6 +261,12 @@ backendTrafficPolicies:
reason: Accepted
status: "True"
type: Accepted
+ - lastTransitionTime: null
+ message: 'This policy is being overridden by other backendTrafficPolicies
+ for these routes: [default/grpcroute-2 default/grpcroute-3]'
+ reason: Overridden
+ status: "True"
+ type: Overridden
controllerName: gateway.envoyproxy.io/gatewayclass-controller
gateways:
- apiVersion: gateway.networking.k8s.io/v1
@@ -212,7 +286,7 @@ gateways:
protocol: HTTP
status:
listeners:
- - attachedRoutes: 1
+ - attachedRoutes: 3
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
@@ -309,6 +383,72 @@ grpcRoutes:
name: gateway-1
namespace: envoy-gateway
sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ creationTimestamp: null
+ name: grpcroute-3
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-3
+ port: 8080
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ creationTimestamp: null
+ name: grpcroute-2
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-2
+ port: 8080
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
@@ -516,6 +656,55 @@ xdsIR:
interval: 2s
maxEjectionPercent: 100
splitExternalLocalOriginErrors: false
+ - destination:
+ name: grpcroute/default/grpcroute-3/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: GRPC
+ weight: 1
+ hostname: '*'
+ isHTTP2: true
+ metadata:
+ kind: GRPCRoute
+ name: grpcroute-3
+ namespace: default
+ name: grpcroute/default/grpcroute-3/rule/0/match/-1/*
+ traffic:
+ healthCheck:
+ active:
+ grpc:
+ service: foo-service
+ healthyThreshold: 1
+ interval: 3s
+ timeout: 1s
+ unhealthyThreshold: 3
+ - destination:
+ name: grpcroute/default/grpcroute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: GRPC
+ weight: 1
+ hostname: '*'
+ isHTTP2: true
+ metadata:
+ kind: GRPCRoute
+ name: grpcroute-2
+ namespace: default
+ name: grpcroute/default/grpcroute-2/rule/0/match/-1/*
+ traffic:
+ healthCheck:
+ active:
+ grpc: {}
+ healthyThreshold: 1
+ interval: 3s
+ timeout: 1s
+ unhealthyThreshold: 3
envoy-gateway/gateway-2:
accessLog:
text:
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-headers-error.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-headers-error.in.yaml
new file mode 100644
index 00000000000..3b2331bba7f
--- /dev/null
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-headers-error.in.yaml
@@ -0,0 +1,43 @@
+clientTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: ClientTrafficPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: target-gateway-1
+ spec:
+ headers:
+ enableEnvoyHeaders: true
+ withUnderscoresAction: Allow
+ preserveXRequestID: true
+ earlyRequestHeaders:
+ add:
+ - name: ""
+ value: "empty"
+ - name: "invalid"
+ value: ":/"
+ set:
+ - name: ""
+ value: "empty"
+ - name: "invalid"
+ value: ":/"
+ remove:
+ - ""
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http-1
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: Same
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-headers-error.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-headers-error.out.yaml
new file mode 100644
index 00000000000..9eee58d7df7
--- /dev/null
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-headers-error.out.yaml
@@ -0,0 +1,127 @@
+clientTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: ClientTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: target-gateway-1
+ namespace: envoy-gateway
+ spec:
+ headers:
+ earlyRequestHeaders:
+ add:
+ - name: ""
+ value: empty
+ - name: invalid
+ value: :/
+ remove:
+ - ""
+ set:
+ - name: ""
+ value: empty
+ - name: invalid
+ value: :/
+ enableEnvoyHeaders: true
+ preserveXRequestID: true
+ withUnderscoresAction: Allow
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ conditions:
+ - lastTransitionTime: null
+ message: |-
+ Headers: EarlyRequestHeaders cannot add a header with an empty name
+ EarlyRequestHeaders cannot set a header with an empty name
+ EarlyRequestHeaders cannot remove a header with an empty name.
+ reason: Invalid
+ status: "False"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: Same
+ name: http-1
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 0
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http-1
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http-1
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ headers:
+ enableEnvoyHeaders: true
+ preserveXRequestID: true
+ withUnderscoresAction: Allow
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http-1
+ name: envoy-gateway/gateway-1/http-1
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-headers.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-headers.in.yaml
index 6d73bee1a16..3234aed7da8 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-headers.in.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-headers.in.yaml
@@ -9,6 +9,20 @@ clientTrafficPolicies:
enableEnvoyHeaders: true
withUnderscoresAction: Allow
preserveXRequestID: true
+ earlyRequestHeaders:
+ add:
+ - name: "my-added-header"
+ value: "my-added-header-value"
+ - name: "my-added-header"
+ value: "my-added-header-value"
+ set:
+ - name: "my-set-header"
+ value: "my-set-header-value"
+ - name: "my-set-header"
+ value: "my-set-header-value"
+ remove:
+ - "my-removed-header"
+ - "my-removed-header"
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-headers.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-headers.out.yaml
index 8b32bb192da..4e66bd91c64 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-headers.out.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-headers.out.yaml
@@ -7,6 +7,20 @@ clientTrafficPolicies:
namespace: envoy-gateway
spec:
headers:
+ earlyRequestHeaders:
+ add:
+ - name: my-added-header
+ value: my-added-header-value
+ - name: my-added-header
+ value: my-added-header-value
+ remove:
+ - my-removed-header
+ - my-removed-header
+ set:
+ - name: my-set-header
+ value: my-set-header-value
+ - name: my-set-header
+ value: my-set-header-value
enableEnvoyHeaders: true
preserveXRequestID: true
withUnderscoresAction: Allow
@@ -129,6 +143,17 @@ xdsIR:
http:
- address: 0.0.0.0
headers:
+ earlyAddRequestHeaders:
+ - append: true
+ name: my-added-header
+ value:
+ - my-added-header-value
+ - append: false
+ name: my-set-header
+ value:
+ - my-set-header-value
+ earlyRemoveRequestHeaders:
+ - my-removed-header
enableEnvoyHeaders: true
preserveXRequestID: true
withUnderscoresAction: Allow
@@ -147,6 +172,17 @@ xdsIR:
port: 10080
- address: 0.0.0.0
headers:
+ earlyAddRequestHeaders:
+ - append: true
+ name: my-added-header
+ value:
+ - my-added-header-value
+ - append: false
+ name: my-set-header
+ value:
+ - my-set-header-value
+ earlyRemoveRequestHeaders:
+ - my-removed-header
enableEnvoyHeaders: true
preserveXRequestID: true
withUnderscoresAction: Allow
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.in.yaml
new file mode 100644
index 00000000000..1f25d8f7e0b
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.in.yaml
@@ -0,0 +1,262 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: default
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - www.foo.com
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: /foo
+ backendRefs:
+ - name: service-1
+ port: 8080
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ hostnames:
+ - www.bar.com
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: /bar
+ backendRefs:
+ - name: service-1
+ port: 8080
+services:
+- apiVersion: v1
+ kind: Service
+ metadata:
+ namespace: envoy-gateway
+ name: grpc-backend
+ spec:
+ ports:
+ - port: 8000
+ name: grpc
+ protocol: TCP
+- apiVersion: v1
+ kind: Service
+ metadata:
+ namespace: default
+ name: grpc-backend-2
+ spec:
+ ports:
+ - port: 9000
+ name: grpc
+ protocol: TCP
+endpointSlices:
+- apiVersion: discovery.k8s.io/v1
+ kind: EndpointSlice
+ metadata:
+ name: endpointslice-grpc-backend
+ namespace: envoy-gateway
+ labels:
+ kubernetes.io/service-name: grpc-backend
+ addressType: IPv4
+ ports:
+ - name: http
+ protocol: TCP
+ port: 8000
+ endpoints:
+ - addresses:
+ - 7.7.7.7
+ conditions:
+ ready: true
+- apiVersion: discovery.k8s.io/v1
+ kind: EndpointSlice
+ metadata:
+ name: endpointslice-grpc-backend-2
+ namespace: default
+ labels:
+ kubernetes.io/service-name: grpc-backend-2
+ addressType: IPv4
+ ports:
+ - name: grpc
+ protocol: TCP
+ port: 9000
+ endpoints:
+ - addresses:
+ - 8.8.8.8
+ conditions:
+ ready: true
+referenceGrants:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: ReferenceGrant
+ metadata:
+ namespace: envoy-gateway
+ name: referencegrant-1
+ spec:
+ from:
+ - group: gateway.envoyproxy.io
+ kind: EnvoyExtensionPolicy
+ namespace: default
+ to:
+ - group: ''
+ kind: Service
+ - group: gateway.envoyproxy.io
+ kind: Backend
+configMaps:
+- apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: ca-cmap
+ namespace: default
+ data:
+ ca.crt: |
+ -----BEGIN CERTIFICATE-----
+ MIIDJzCCAg+gAwIBAgIUAl6UKIuKmzte81cllz5PfdN2IlIwDQYJKoZIhvcNAQEL
+ BQAwIzEQMA4GA1UEAwwHbXljaWVudDEPMA0GA1UECgwGa3ViZWRiMB4XDTIzMTAw
+ MjA1NDE1N1oXDTI0MTAwMTA1NDE1N1owIzEQMA4GA1UEAwwHbXljaWVudDEPMA0G
+ A1UECgwGa3ViZWRiMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwSTc
+ 1yj8HW62nynkFbXo4VXKv2jC0PM7dPVky87FweZcTKLoWQVPQE2p2kLDK6OEszmM
+ yyr+xxWtyiveremrWqnKkNTYhLfYPhgQkczib7eUalmFjUbhWdLvHakbEgCodn3b
+ kz57mInX2VpiDOKg4kyHfiuXWpiBqrCx0KNLpxo3DEQcFcsQTeTHzh4752GV04RU
+ Ti/GEWyzIsl4Rg7tGtAwmcIPgUNUfY2Q390FGqdH4ahn+mw/6aFbW31W63d9YJVq
+ ioyOVcaMIpM5B/c7Qc8SuhCI1YGhUyg4cRHLEw5VtikioyE3X04kna3jQAj54YbR
+ bpEhc35apKLB21HOUQIDAQABo1MwUTAdBgNVHQ4EFgQUyvl0VI5vJVSuYFXu7B48
+ 6PbMEAowHwYDVR0jBBgwFoAUyvl0VI5vJVSuYFXu7B486PbMEAowDwYDVR0TAQH/
+ BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAMLxrgFVMuNRq2wAwcBt7SnNR5Cfz
+ 2MvXq5EUmuawIUi9kaYjwdViDREGSjk7JW17vl576HjDkdfRwi4E28SydRInZf6J
+ i8HZcZ7caH6DxR335fgHVzLi5NiTce/OjNBQzQ2MJXVDd8DBmG5fyatJiOJQ4bWE
+ A7FlP0RdP3CO3GWE0M5iXOB2m1qWkE2eyO4UHvwTqNQLdrdAXgDQlbam9e4BG3Gg
+ d/6thAkWDbt/QNT+EJHDCvhDRKh1RuGHyg+Y+/nebTWWrFWsktRrbOoHCZiCpXI1
+ 3eXE6nt0YkgtDxG22KqnhpAg9gUSs2hlhoxyvkzyF0mu6NhPlwAgnq7+/Q==
+ -----END CERTIFICATE-----
+backendTLSPolicies:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ name: policy-btls-grpc
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: ''
+ kind: Service
+ name: grpc-backend
+ sectionName: "8000"
+ validation:
+ caCertificateRefs:
+ - name: ca-cmap
+ group: ''
+ kind: ConfigMap
+ hostname: grpc-backend
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ name: policy-btls-backend-ip
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls
+ validation:
+ caCertificateRefs:
+ - name: ca-cmap
+ group: ''
+ kind: ConfigMap
+ hostname: ip-backend
+envoyExtensionPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyExtensionPolicy
+ metadata:
+ namespace: default
+ name: policy-for-http-route
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ extProc:
+ - backendRefs:
+ - Name: grpc-backend
+ Namespace: envoy-gateway
+ Port: 8000
+ - Name: grpc-backend-2
+ Port: 9000
+ - Name: backend-ip
+ Kind: Backend
+ Group: gateway.envoyproxy.io
+ - Name: backend-ip-tls
+ Namespace: envoy-gateway
+ Kind: Backend
+ Group: gateway.envoyproxy.io
+ backendSettings:
+ dns:
+ respectDnsTtl: true
+ http2:
+ initialStreamWindowSize: 128Ki
+ initialConnectionWindowSize: 2Mi
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ loadBalancer:
+ type: ConsistentHash
+ consistentHash:
+ type: Header
+ header:
+ name: X-some-header
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ circuitBreaker:
+ maxConnections: 2048
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ connection:
+ bufferLimit: 20Mi
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip-tls
+ namespace: envoy-gateway
+ spec:
+ endpoints:
+ - ip:
+ address: 2.2.2.2
+ port: 3443
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.out.yaml
new file mode 100644
index 00000000000..17f9e8c15a6
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.out.yaml
@@ -0,0 +1,431 @@
+backendTLSPolicies:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-btls-grpc
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: ""
+ kind: Service
+ name: grpc-backend
+ sectionName: "8000"
+ validation:
+ caCertificateRefs:
+ - group: ""
+ kind: ConfigMap
+ name: ca-cmap
+ hostname: grpc-backend
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.envoyproxy.io
+ kind: EnvoyExtensionPolicy
+ name: policy-for-http-route
+ namespace: default
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-btls-backend-ip
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls
+ validation:
+ caCertificateRefs:
+ - group: ""
+ kind: ConfigMap
+ name: ca-cmap
+ hostname: ip-backend
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.envoyproxy.io
+ kind: EnvoyExtensionPolicy
+ name: policy-for-http-route
+ namespace: default
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip-tls
+ namespace: envoy-gateway
+ spec:
+ endpoints:
+ - ip:
+ address: 2.2.2.2
+ port: 3443
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+envoyExtensionPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyExtensionPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-http-route
+ namespace: default
+ spec:
+ extProc:
+ - backendRefs:
+ - name: grpc-backend
+ namespace: envoy-gateway
+ port: 8000
+ - name: grpc-backend-2
+ port: 9000
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls
+ namespace: envoy-gateway
+ backendSettings:
+ circuitBreaker:
+ maxConnections: 2048
+ connection:
+ bufferLimit: 20Mi
+ dns:
+ respectDnsTtl: true
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ http2:
+ initialConnectionWindowSize: 2Mi
+ initialStreamWindowSize: 128Ki
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ loadBalancer:
+ consistentHash:
+ header:
+ name: X-some-header
+ type: Header
+ type: ConsistentHash
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: default
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 2
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ hostnames:
+ - www.foo.com
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /foo
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ hostnames:
+ - www.bar.com
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /bar
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+infraIR:
+ default/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: default/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ name: default/gateway-1
+xdsIR:
+ default/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ envoyExtensions:
+ extProcs:
+ - authority: grpc-backend.envoy-gateway:8000
+ destination:
+ name: envoyextensionpolicy/default/policy-for-http-route/0
+ settings:
+ - addressType: IP
+ protocol: GRPC
+ tls:
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls-grpc/envoy-gateway-ca
+ sni: grpc-backend
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 8.8.8.8
+ port: 9000
+ protocol: GRPC
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ protocol: GRPC
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 2.2.2.2
+ port: 3443
+ protocol: GRPC
+ tls:
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls-backend-ip/envoy-gateway-ca
+ sni: ip-backend
+ weight: 1
+ name: envoyextensionpolicy/default/policy-for-http-route/extproc/0
+ traffic:
+ backendConnection:
+ bufferLimit: 20971520
+ circuitBreaker:
+ maxConnections: 2048
+ dns:
+ respectDnsTtl: true
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ http2:
+ initialConnectionWindowSize: 131072
+ initialStreamWindowSize: 2097152
+ maxConcurrentStreams: 200
+ resetStreamOnError: true
+ loadBalancer:
+ consistentHash:
+ header:
+ name: X-some-header
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ hostname: www.foo.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.bar.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.in.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.in.yaml
new file mode 100644
index 00000000000..72d40451a1f
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.in.yaml
@@ -0,0 +1,196 @@
+envoyProxyForGatewayClass:
+ apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyProxy
+ metadata:
+ namespace: envoy-gateway-system
+ name: test
+ spec:
+ telemetry:
+ accessLog:
+ settings:
+ - format:
+ type: Text
+ text: |
+ [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n
+ sinks:
+ - type: File
+ file:
+ path: /dev/stdout
+ - type: ALS
+ als:
+ logName: accesslog
+ backendSettings:
+ http2:
+ initialStreamWindowSize: 128Ki
+ initialConnectionWindowSize: 2Mi
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ loadBalancer:
+ type: ConsistentHash
+ consistentHash:
+ type: Header
+ header:
+ name: X-some-header
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ circuitBreaker:
+ maxConnections: 2048
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ connection:
+ bufferLimit: 20Mi
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ http:
+ requestHeaders:
+ - x-client-ip-address
+ responseHeaders:
+ - cache-control
+ responseTrailers:
+ - expires
+ type: HTTP
+ - type: ALS
+ als:
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ type: TCP
+ - type: OpenTelemetry
+ openTelemetry:
+ backendSettings:
+ http2:
+ initialStreamWindowSize: 128Ki
+ initialConnectionWindowSize: 2Mi
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ loadBalancer:
+ type: ConsistentHash
+ consistentHash:
+ type: Header
+ header:
+ name: X-some-header
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ circuitBreaker:
+ maxConnections: 2048
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ connection:
+ bufferLimit: 20Mi
+ host: otel-collector.monitoring.svc.cluster.local
+ port: 4317
+ resources:
+ k8s.cluster.name: "cluster-1"
+ provider:
+ type: Kubernetes
+ kubernetes:
+ envoyService:
+ type: LoadBalancer
+ envoyDeployment:
+ replicas: 2
+ container:
+ env:
+ - name: env_a
+ value: env_a_value
+ - name: env_b
+ value: env_b_name
+ image: "envoyproxy/envoy:distroless-dev"
+ resources:
+ requests:
+ cpu: 100m
+ memory: 512Mi
+ securityContext:
+ runAsUser: 2000
+ allowPrivilegeEscalation: false
+ pod:
+ annotations:
+ key1: val1
+ key2: val2
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: cloud.google.com/gke-nodepool
+ operator: In
+ values:
+ - router-node
+ tolerations:
+ - effect: NoSchedule
+ key: node-type
+ operator: Exists
+ value: "router"
+ securityContext:
+ runAsUser: 1000
+ runAsGroup: 3000
+ fsGroup: 2000
+ fsGroupChangePolicy: "OnRootMismatch"
+ volumes:
+ - name: certs
+ secret:
+ secretName: envoy-cert
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: Same
+services:
+- apiVersion: v1
+ kind: Service
+ metadata:
+ name: envoy-als
+ namespace: monitoring
+ spec:
+ type: ClusterIP
+ ports:
+ - name: grpc
+ port: 9000
+ appProtocol: grpc
+ protocol: TCP
+ targetPort: 9000
+endpointSlices:
+- apiVersion: discovery.k8s.io/v1
+ kind: EndpointSlice
+ metadata:
+ name: endpointslice-envoy-als
+ namespace: monitoring
+ labels:
+ kubernetes.io/service-name: envoy-als
+ addressType: IPv4
+ ports:
+ - name: grpc
+ protocol: TCP
+ appProtocol: grpc
+ port: 9090
+ endpoints:
+ - addresses:
+ - "10.240.0.10"
+ conditions:
+ ready: true
diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.out.yaml
new file mode 100644
index 00000000000..28ef831b03a
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.out.yaml
@@ -0,0 +1,326 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: Same
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 0
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ config:
+ apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyProxy
+ metadata:
+ creationTimestamp: null
+ name: test
+ namespace: envoy-gateway-system
+ spec:
+ logging: {}
+ provider:
+ kubernetes:
+ envoyDeployment:
+ container:
+ env:
+ - name: env_a
+ value: env_a_value
+ - name: env_b
+ value: env_b_name
+ image: envoyproxy/envoy:distroless-dev
+ resources:
+ requests:
+ cpu: 100m
+ memory: 512Mi
+ securityContext:
+ allowPrivilegeEscalation: false
+ runAsUser: 2000
+ pod:
+ affinity:
+ nodeAffinity:
+ requiredDuringSchedulingIgnoredDuringExecution:
+ nodeSelectorTerms:
+ - matchExpressions:
+ - key: cloud.google.com/gke-nodepool
+ operator: In
+ values:
+ - router-node
+ annotations:
+ key1: val1
+ key2: val2
+ securityContext:
+ fsGroup: 2000
+ fsGroupChangePolicy: OnRootMismatch
+ runAsGroup: 3000
+ runAsUser: 1000
+ tolerations:
+ - effect: NoSchedule
+ key: node-type
+ operator: Exists
+ value: router
+ volumes:
+ - name: certs
+ secret:
+ secretName: envoy-cert
+ replicas: 2
+ envoyService:
+ type: LoadBalancer
+ type: Kubernetes
+ telemetry:
+ accessLog:
+ settings:
+ - format:
+ text: |
+ [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n
+ type: Text
+ sinks:
+ - file:
+ path: /dev/stdout
+ type: File
+ - als:
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ backendSettings:
+ circuitBreaker:
+ maxConnections: 2048
+ connection:
+ bufferLimit: 20Mi
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ http2:
+ initialConnectionWindowSize: 2Mi
+ initialStreamWindowSize: 128Ki
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ loadBalancer:
+ consistentHash:
+ header:
+ name: X-some-header
+ type: Header
+ type: ConsistentHash
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ http:
+ requestHeaders:
+ - x-client-ip-address
+ responseHeaders:
+ - cache-control
+ responseTrailers:
+ - expires
+ logName: accesslog
+ type: HTTP
+ type: ALS
+ - als:
+ backendRefs:
+ - name: envoy-als
+ namespace: monitoring
+ port: 9000
+ type: TCP
+ type: ALS
+ - openTelemetry:
+ backendSettings:
+ circuitBreaker:
+ maxConnections: 2048
+ connection:
+ bufferLimit: 20Mi
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ http2:
+ initialConnectionWindowSize: 2Mi
+ initialStreamWindowSize: 128Ki
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ loadBalancer:
+ consistentHash:
+ header:
+ name: X-some-header
+ type: Header
+ type: ConsistentHash
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ host: otel-collector.monitoring.svc.cluster.local
+ port: 4317
+ resources:
+ k8s.cluster.name: cluster-1
+ type: OpenTelemetry
+ status: {}
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ als:
+ - destination:
+ name: accesslog_als_0_1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 10.240.0.10
+ port: 9090
+ protocol: GRPC
+ http:
+ requestHeaders:
+ - x-client-ip-address
+ responseHeaders:
+ - cache-control
+ responseTrailers:
+ - expires
+ name: accesslog
+ text: |
+ [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n
+ traffic:
+ backendConnection:
+ bufferLimit: 20971520
+ circuitBreaker:
+ maxConnections: 2048
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ http2:
+ initialConnectionWindowSize: 131072
+ initialStreamWindowSize: 2097152
+ maxConcurrentStreams: 200
+ resetStreamOnError: true
+ loadBalancer:
+ consistentHash:
+ header:
+ name: X-some-header
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ type: HTTP
+ - destination:
+ name: accesslog_als_0_2
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 10.240.0.10
+ port: 9090
+ protocol: GRPC
+ name: envoy-gateway-system/test
+ text: |
+ [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n
+ type: TCP
+ openTelemetry:
+ - authority: otel-collector.monitoring.svc.cluster.local
+ destination:
+ name: accesslog_otel_0_3
+ settings:
+ - endpoints:
+ - host: otel-collector.monitoring.svc.cluster.local
+ port: 4317
+ protocol: GRPC
+ weight: 1
+ resources:
+ k8s.cluster.name: cluster-1
+ text: |
+ [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n
+ traffic:
+ backendConnection:
+ bufferLimit: 20971520
+ circuitBreaker:
+ maxConnections: 2048
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ http2:
+ initialConnectionWindowSize: 131072
+ initialStreamWindowSize: 2097152
+ maxConcurrentStreams: 200
+ resetStreamOnError: true
+ loadBalancer:
+ consistentHash:
+ header:
+ name: X-some-header
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ text:
+ - format: |
+ [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n
+ path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
diff --git a/internal/gatewayapi/testdata/envoyproxy-priority-backend.in.yaml b/internal/gatewayapi/testdata/envoyproxy-priority-backend.in.yaml
new file mode 100644
index 00000000000..f44174b6d62
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyproxy-priority-backend.in.yaml
@@ -0,0 +1,236 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: default
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - www.foo.com
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: /foo
+ backendRefs:
+ - name: service-1
+ port: 8080
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ hostnames:
+ - www.bar.com
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: /bar
+ backendRefs:
+ - name: service-1
+ port: 8080
+services:
+ - apiVersion: v1
+ kind: Service
+ metadata:
+ namespace: envoy-gateway
+ name: grpc-backend
+ spec:
+ ports:
+ - port: 8000
+ name: grpc
+ protocol: TCP
+ - apiVersion: v1
+ kind: Service
+ metadata:
+ namespace: default
+ name: grpc-backend-2
+ spec:
+ ports:
+ - port: 9000
+ name: grpc
+ protocol: TCP
+endpointSlices:
+ - apiVersion: discovery.k8s.io/v1
+ kind: EndpointSlice
+ metadata:
+ name: endpointslice-grpc-backend
+ namespace: envoy-gateway
+ labels:
+ kubernetes.io/service-name: grpc-backend
+ addressType: IPv4
+ ports:
+ - name: http
+ protocol: TCP
+ port: 8000
+ endpoints:
+ - addresses:
+ - 7.7.7.7
+ conditions:
+ ready: true
+ - apiVersion: discovery.k8s.io/v1
+ kind: EndpointSlice
+ metadata:
+ name: endpointslice-grpc-backend-2
+ namespace: default
+ labels:
+ kubernetes.io/service-name: grpc-backend-2
+ addressType: IPv4
+ ports:
+ - name: grpc
+ protocol: TCP
+ port: 9000
+ endpoints:
+ - addresses:
+ - 8.8.8.8
+ conditions:
+ ready: true
+referenceGrants:
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: ReferenceGrant
+ metadata:
+ namespace: envoy-gateway
+ name: referencegrant-1
+ spec:
+ from:
+ - group: gateway.envoyproxy.io
+ kind: EnvoyExtensionPolicy
+ namespace: default
+ to:
+ - group: ''
+ kind: Service
+ - group: gateway.envoyproxy.io
+ kind: Backend
+configMaps:
+ - apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: ca-cmap
+ namespace: default
+ data:
+ ca.crt: |
+ -----BEGIN CERTIFICATE-----
+ MIIDJzCCAg+gAwIBAgIUAl6UKIuKmzte81cllz5PfdN2IlIwDQYJKoZIhvcNAQEL
+ BQAwIzEQMA4GA1UEAwwHbXljaWVudDEPMA0GA1UECgwGa3ViZWRiMB4XDTIzMTAw
+ MjA1NDE1N1oXDTI0MTAwMTA1NDE1N1owIzEQMA4GA1UEAwwHbXljaWVudDEPMA0G
+ A1UECgwGa3ViZWRiMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwSTc
+ 1yj8HW62nynkFbXo4VXKv2jC0PM7dPVky87FweZcTKLoWQVPQE2p2kLDK6OEszmM
+ yyr+xxWtyiveremrWqnKkNTYhLfYPhgQkczib7eUalmFjUbhWdLvHakbEgCodn3b
+ kz57mInX2VpiDOKg4kyHfiuXWpiBqrCx0KNLpxo3DEQcFcsQTeTHzh4752GV04RU
+ Ti/GEWyzIsl4Rg7tGtAwmcIPgUNUfY2Q390FGqdH4ahn+mw/6aFbW31W63d9YJVq
+ ioyOVcaMIpM5B/c7Qc8SuhCI1YGhUyg4cRHLEw5VtikioyE3X04kna3jQAj54YbR
+ bpEhc35apKLB21HOUQIDAQABo1MwUTAdBgNVHQ4EFgQUyvl0VI5vJVSuYFXu7B48
+ 6PbMEAowHwYDVR0jBBgwFoAUyvl0VI5vJVSuYFXu7B486PbMEAowDwYDVR0TAQH/
+ BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAMLxrgFVMuNRq2wAwcBt7SnNR5Cfz
+ 2MvXq5EUmuawIUi9kaYjwdViDREGSjk7JW17vl576HjDkdfRwi4E28SydRInZf6J
+ i8HZcZ7caH6DxR335fgHVzLi5NiTce/OjNBQzQ2MJXVDd8DBmG5fyatJiOJQ4bWE
+ A7FlP0RdP3CO3GWE0M5iXOB2m1qWkE2eyO4UHvwTqNQLdrdAXgDQlbam9e4BG3Gg
+ d/6thAkWDbt/QNT+EJHDCvhDRKh1RuGHyg+Y+/nebTWWrFWsktRrbOoHCZiCpXI1
+ 3eXE6nt0YkgtDxG22KqnhpAg9gUSs2hlhoxyvkzyF0mu6NhPlwAgnq7+/Q==
+ -----END CERTIFICATE-----
+backendTLSPolicies:
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ name: policy-btls-grpc
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: ''
+ kind: Service
+ name: grpc-backend
+ sectionName: "8000"
+ validation:
+ caCertificateRefs:
+ - name: ca-cmap
+ group: ''
+ kind: ConfigMap
+ hostname: grpc-backend
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ name: policy-btls-backend-ip
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls
+ validation:
+ caCertificateRefs:
+ - name: ca-cmap
+ group: ''
+ kind: ConfigMap
+ hostname: ip-backend
+envoyExtensionPolicies:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyExtensionPolicy
+ metadata:
+ namespace: default
+ name: policy-for-http-route
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ extProc:
+ - backendRefs:
+ - Name: grpc-backend
+ Namespace: envoy-gateway
+ Port: 8000
+ - Name: grpc-backend-2
+ Port: 9000
+ failover: true
+ - Name: backend-ip
+ Kind: Backend
+ Group: gateway.envoyproxy.io
+ failover: true
+ - Name: backend-ip-tls
+ Namespace: envoy-gateway
+ Kind: Backend
+ Group: gateway.envoyproxy.io
+ failover: true
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-ip-tls
+ namespace: envoy-gateway
+ spec:
+ endpoints:
+ - ip:
+ address: 2.2.2.2
+ port: 3443
diff --git a/internal/gatewayapi/testdata/envoyproxy-priority-backend.out.yaml b/internal/gatewayapi/testdata/envoyproxy-priority-backend.out.yaml
new file mode 100644
index 00000000000..9933d77c563
--- /dev/null
+++ b/internal/gatewayapi/testdata/envoyproxy-priority-backend.out.yaml
@@ -0,0 +1,381 @@
+backendTLSPolicies:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-btls-grpc
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: ""
+ kind: Service
+ name: grpc-backend
+ sectionName: "8000"
+ validation:
+ caCertificateRefs:
+ - group: ""
+ kind: ConfigMap
+ name: ca-cmap
+ hostname: grpc-backend
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.envoyproxy.io
+ kind: EnvoyExtensionPolicy
+ name: policy-for-http-route
+ namespace: default
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: BackendTLSPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-btls-backend-ip
+ namespace: envoy-gateway
+ spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls
+ validation:
+ caCertificateRefs:
+ - group: ""
+ kind: ConfigMap
+ name: ca-cmap
+ hostname: ip-backend
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.envoyproxy.io
+ kind: EnvoyExtensionPolicy
+ name: policy-for-http-route
+ namespace: default
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-ip-tls
+ namespace: envoy-gateway
+ spec:
+ endpoints:
+ - ip:
+ address: 2.2.2.2
+ port: 3443
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+envoyExtensionPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyExtensionPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-http-route
+ namespace: default
+ spec:
+ extProc:
+ - backendRefs:
+ - name: grpc-backend
+ namespace: envoy-gateway
+ port: 8000
+ - failover: true
+ name: grpc-backend-2
+ port: 9000
+ - failover: true
+ group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip
+ - failover: true
+ group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-ip-tls
+ namespace: envoy-gateway
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: default
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 2
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ hostnames:
+ - www.foo.com
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /foo
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ hostnames:
+ - www.bar.com
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /bar
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+infraIR:
+ default/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: default/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ name: default/gateway-1
+xdsIR:
+ default/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ envoyExtensions:
+ extProcs:
+ - authority: grpc-backend.envoy-gateway:8000
+ destination:
+ name: envoyextensionpolicy/default/policy-for-http-route/0
+ settings:
+ - addressType: IP
+ protocol: GRPC
+ tls:
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls-grpc/envoy-gateway-ca
+ sni: grpc-backend
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 8.8.8.8
+ port: 9000
+ priority: 1
+ protocol: GRPC
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ priority: 1
+ protocol: GRPC
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 2.2.2.2
+ port: 3443
+ priority: 1
+ protocol: GRPC
+ tls:
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls-backend-ip/envoy-gateway-ca
+ sni: ip-backend
+ weight: 1
+ name: envoyextensionpolicy/default/policy-for-http-route/extproc/0
+ hostname: www.foo.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.bar.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
diff --git a/internal/gatewayapi/testdata/envoyproxy-tracing-backend.in.yaml b/internal/gatewayapi/testdata/envoyproxy-tracing-backend.in.yaml
index 9cd3485cec3..4c06c534135 100644
--- a/internal/gatewayapi/testdata/envoyproxy-tracing-backend.in.yaml
+++ b/internal/gatewayapi/testdata/envoyproxy-tracing-backend.in.yaml
@@ -9,6 +9,33 @@ envoyProxyForGatewayClass:
tracing:
samplingRate: 100
provider:
+ backendSettings:
+ http2:
+ initialStreamWindowSize: 128Ki
+ initialConnectionWindowSize: 2Mi
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ loadBalancer:
+ type: ConsistentHash
+ consistentHash:
+ type: Header
+ header:
+ name: X-some-header
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ circuitBreaker:
+ maxConnections: 2048
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ connection:
+ bufferLimit: 20Mi
backendRefs:
- name: otel-collector
namespace: monitoring
diff --git a/internal/gatewayapi/testdata/envoyproxy-tracing-backend.out.yaml b/internal/gatewayapi/testdata/envoyproxy-tracing-backend.out.yaml
index 70e07bd18f2..b3a44d78fdc 100644
--- a/internal/gatewayapi/testdata/envoyproxy-tracing-backend.out.yaml
+++ b/internal/gatewayapi/testdata/envoyproxy-tracing-backend.out.yaml
@@ -106,6 +106,33 @@ infraIR:
- name: otel-collector
namespace: monitoring
port: 4317
+ backendSettings:
+ circuitBreaker:
+ maxConnections: 2048
+ connection:
+ bufferLimit: 20Mi
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ http2:
+ initialConnectionWindowSize: 2Mi
+ initialStreamWindowSize: 128Ki
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ loadBalancer:
+ consistentHash:
+ header:
+ name: X-some-header
+ type: Header
+ type: ConsistentHash
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
type: OpenTelemetry
samplingRate: 100
status: {}
@@ -156,6 +183,58 @@ xdsIR:
- name: otel-collector
namespace: monitoring
port: 4317
+ backendSettings:
+ circuitBreaker:
+ maxConnections: 2048
+ connection:
+ bufferLimit: 20Mi
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ http2:
+ initialConnectionWindowSize: 2Mi
+ initialStreamWindowSize: 128Ki
+ maxConcurrentStreams: 200
+ onInvalidMessage: TerminateStream
+ loadBalancer:
+ consistentHash:
+ header:
+ name: X-some-header
+ type: Header
+ type: ConsistentHash
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
type: OpenTelemetry
samplingRate: 100
serviceName: gateway-1.envoy-gateway
+ traffic:
+ backendConnection:
+ bufferLimit: 20971520
+ circuitBreaker:
+ maxConnections: 2048
+ healthCheck:
+ passive:
+ consecutiveGatewayErrors: 4
+ interval: 5s
+ http2:
+ initialConnectionWindowSize: 131072
+ initialStreamWindowSize: 2097152
+ maxConcurrentStreams: 200
+ resetStreamOnError: true
+ loadBalancer:
+ consistentHash:
+ header:
+ name: X-some-header
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
diff --git a/internal/gatewayapi/testdata/gateway-http-listener-with-hostname-intersection.in.yaml b/internal/gatewayapi/testdata/gateway-http-listener-with-hostname-intersection.in.yaml
new file mode 100644
index 00000000000..8fba772492e
--- /dev/null
+++ b/internal/gatewayapi/testdata/gateway-http-listener-with-hostname-intersection.in.yaml
@@ -0,0 +1,65 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: empty-hostname
+ port: 80
+ protocol: HTTP
+ allowedRoutes:
+ namespaces:
+ from: All
+ - name: wildcard-example-com
+ port: 80
+ protocol: HTTP
+ hostname: "*.example.com"
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ name: httproute-1
+ namespace: envoy-gateway
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: empty-hostname
+ hostnames:
+ - "bar.com"
+ - "*.example.com" # request matching is prevented by the isolation wildcard-example-com listener
+ rules:
+ - matches:
+ - path:
+ type: PathPrefix
+ value: /empty-hostname
+ backendRefs:
+ - name: service-1
+ port: 8080
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ name: httproute-2
+ namespace: envoy-gateway
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: wildcard-example-com
+ hostnames:
+ - "bar.com" # doesn't match wildcard-example-com listener
+ - "*.example.com"
+ rules:
+ - matches:
+ - path:
+ type: PathPrefix
+ value: /wildcard-example-com
+ backendRefs:
+ - name: service-1
+ port: 8080
diff --git a/internal/gatewayapi/testdata/gateway-http-listener-with-hostname-intersection.out.yaml b/internal/gatewayapi/testdata/gateway-http-listener-with-hostname-intersection.out.yaml
new file mode 100644
index 00000000000..cb47542a1c7
--- /dev/null
+++ b/internal/gatewayapi/testdata/gateway-http-listener-with-hostname-intersection.out.yaml
@@ -0,0 +1,238 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: empty-hostname
+ port: 80
+ protocol: HTTP
+ - allowedRoutes:
+ namespaces:
+ from: All
+ hostname: '*.example.com'
+ name: wildcard-example-com
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: empty-hostname
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+ - attachedRoutes: 1
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: wildcard-example-com
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: envoy-gateway
+ spec:
+ hostnames:
+ - bar.com
+ - '*.example.com'
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: empty-hostname
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ type: PathPrefix
+ value: /empty-hostname
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Service envoy-gateway/service-1 not found
+ reason: BackendNotFound
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: empty-hostname
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: envoy-gateway
+ spec:
+ hostnames:
+ - bar.com
+ - '*.example.com'
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: wildcard-example-com
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ type: PathPrefix
+ value: /wildcard-example-com
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Service envoy-gateway/service-1 not found
+ reason: BackendNotFound
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: wildcard-example-com
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/empty-hostname
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ name: envoy-gateway/gateway-1
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: empty-hostname
+ name: envoy-gateway/gateway-1/empty-hostname
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/envoy-gateway/httproute-1/rule/0
+ settings:
+ - weight: 1
+ directResponse:
+ statusCode: 500
+ hostname: bar.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute-1/rule/0/match/0/bar_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /empty-hostname
+ - address: 0.0.0.0
+ hostnames:
+ - '*.example.com'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: wildcard-example-com
+ name: envoy-gateway/gateway-1/wildcard-example-com
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/envoy-gateway/httproute-2/rule/0
+ settings:
+ - weight: 1
+ directResponse:
+ statusCode: 500
+ hostname: '*.example.com'
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute-2/rule/0/match/0/*_example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /wildcard-example-com
diff --git a/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.in.yaml b/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.in.yaml
index 2c48dad582e..29fcb5a75a1 100644
--- a/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.in.yaml
+++ b/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.in.yaml
@@ -26,6 +26,11 @@ grpcRoutes:
sectionName: http
rules:
- filters:
+ - type: "RequestHeaderModifier"
+ requestHeaderModifier:
+ add:
+ - name: "my-header-multi-value"
+ value: "foo,bar"
- type: "RequestHeaderModifier"
requestHeaderModifier:
add:
diff --git a/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.out.yaml b/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.out.yaml
index f36c9c969cc..110d404c44f 100644
--- a/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.out.yaml
+++ b/internal/gatewayapi/testdata/grpcroute-with-request-header-modifier.out.yaml
@@ -56,6 +56,11 @@ grpcRoutes:
- name: service-1
port: 8080
filters:
+ - requestHeaderModifier:
+ add:
+ - name: my-header-multi-value
+ value: foo,bar
+ type: RequestHeaderModifier
- requestHeaderModifier:
add:
- name: my-header
@@ -117,9 +122,15 @@ xdsIR:
port: 10080
routes:
- addRequestHeaders:
+ - append: true
+ name: my-header-multi-value
+ value:
+ - foo
+ - bar
- append: true
name: my-header
- value: foo
+ value:
+ - foo
destination:
name: grpcroute/default/grpcroute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/httproute-with-backendref-add-multiple-filters.out.yaml b/internal/gatewayapi/testdata/httproute-with-backendref-add-multiple-filters.out.yaml
index 78655fc8476..122d09efdeb 100644
--- a/internal/gatewayapi/testdata/httproute-with-backendref-add-multiple-filters.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-backendref-add-multiple-filters.out.yaml
@@ -147,7 +147,8 @@ xdsIR:
addRequestHeaders:
- append: false
name: add-header-3
- value: some-value
+ value:
+ - some-value
protocol: HTTP
weight: 1
hostname: '*'
@@ -172,10 +173,12 @@ xdsIR:
addRequestHeaders:
- append: true
name: add-header-1
- value: some-value
+ value:
+ - some-value
- append: true
name: add-header-2
- value: some-value
+ value:
+ - some-value
protocol: HTTP
weight: 8
- addressType: IP
diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-add-multiple-filters.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-add-multiple-filters.out.yaml
index a86e71b4534..605aa384f3e 100644
--- a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-add-multiple-filters.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-add-multiple-filters.out.yaml
@@ -134,13 +134,16 @@ xdsIR:
- addRequestHeaders:
- append: true
name: add-header-1
- value: some-value
+ value:
+ - some-value
- append: true
name: add-header-2
- value: some-value
+ value:
+ - some-value
- append: true
name: add-header-3
- value: some-value
+ value:
+ - some-value
destination:
name: httproute/default/httproute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-adds.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-adds.out.yaml
index 39cc44429f6..f122fc17d5b 100644
--- a/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-adds.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-header-filter-duplicate-adds.out.yaml
@@ -144,19 +144,24 @@ xdsIR:
- addRequestHeaders:
- append: true
name: Set-Header-1
- value: some-value
+ value:
+ - some-value
- append: true
name: set-header-2
- value: some-value
+ value:
+ - some-value
- append: true
name: set-header-3
- value: some-value
+ value:
+ - some-value
- append: true
name: set-header-5
- value: some-value
+ value:
+ - some-value
- append: false
name: set-header-4
- value: some-value
+ value:
+ - some-value
destination:
name: httproute/default/httproute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/httproute-with-header-filter-empty-header-values.out.yaml b/internal/gatewayapi/testdata/httproute-with-header-filter-empty-header-values.out.yaml
index b3814e2d41d..67c14e133a7 100644
--- a/internal/gatewayapi/testdata/httproute-with-header-filter-empty-header-values.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-header-filter-empty-header-values.out.yaml
@@ -128,10 +128,12 @@ xdsIR:
- addRequestHeaders:
- append: true
name: example-header-2
- value: ""
+ value:
+ - ""
- append: false
name: example-header-1
- value: ""
+ value:
+ - ""
destination:
name: httproute/default/httproute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/httproute-with-mirror-filter-multiple.out.yaml b/internal/gatewayapi/testdata/httproute-with-mirror-filter-multiple.out.yaml
index 9aa6f0bf23b..c6e534c9c63 100644
--- a/internal/gatewayapi/testdata/httproute-with-mirror-filter-multiple.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-mirror-filter-multiple.out.yaml
@@ -144,13 +144,16 @@ xdsIR:
- addRequestHeaders:
- append: true
name: X-Header-Add
- value: header-val-1
+ value:
+ - header-val-1
- append: true
name: X-Header-Add-Append
- value: header-val-2
+ value:
+ - header-val-2
- append: false
name: X-Header-Set
- value: set-overwrites-values
+ value:
+ - set-overwrites-values
destination:
name: httproute/default/httproute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-adds.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-adds.out.yaml
index 7b53542bdfa..6dcb4b28779 100644
--- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-adds.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-adds.out.yaml
@@ -140,19 +140,24 @@ xdsIR:
- addResponseHeaders:
- append: true
name: Set-Header-1
- value: some-value
+ value:
+ - some-value
- append: true
name: set-header-2
- value: some-value
+ value:
+ - some-value
- append: true
name: set-header-3
- value: some-value
+ value:
+ - some-value
- append: true
name: set-header-5
- value: some-value
+ value:
+ - some-value
- append: false
name: set-header-4
- value: some-value
+ value:
+ - some-value
destination:
name: httproute/default/httproute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-add-multiple-filters.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-add-multiple-filters.out.yaml
index 459c4264740..47d61c9fcfa 100644
--- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-add-multiple-filters.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-add-multiple-filters.out.yaml
@@ -134,13 +134,16 @@ xdsIR:
- addResponseHeaders:
- append: true
name: add-header-1
- value: some-value
+ value:
+ - some-value
- append: true
name: add-header-2
- value: some-value
+ value:
+ - some-value
- append: true
name: add-header-3
- value: some-value
+ value:
+ - some-value
destination:
name: httproute/default/httproute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-adds.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-adds.out.yaml
index d2b4ffbe3f2..1d2f4f7124c 100644
--- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-adds.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-duplicate-adds.out.yaml
@@ -144,19 +144,24 @@ xdsIR:
- addResponseHeaders:
- append: true
name: Set-Header-1
- value: some-value
+ value:
+ - some-value
- append: true
name: set-header-2
- value: some-value
+ value:
+ - some-value
- append: true
name: set-header-3
- value: some-value
+ value:
+ - some-value
- append: true
name: set-header-5
- value: some-value
+ value:
+ - some-value
- append: false
name: set-header-4
- value: some-value
+ value:
+ - some-value
destination:
name: httproute/default/httproute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-header-values.out.yaml b/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-header-values.out.yaml
index 9d188a03dc0..723cabbe6f7 100644
--- a/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-header-values.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-response-header-filter-empty-header-values.out.yaml
@@ -128,10 +128,12 @@ xdsIR:
- addResponseHeaders:
- append: true
name: example-header-2
- value: ""
+ value:
+ - ""
- append: false
name: example-header-1
- value: ""
+ value:
+ - ""
destination:
name: httproute/default/httproute-1/rule/0
settings:
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.in.yaml
new file mode 100644
index 00000000000..e1f50e75b2d
--- /dev/null
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.in.yaml
@@ -0,0 +1,107 @@
+gateways:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ namespace: default
+ name: gateway-1
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - www.foo.com
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: /foo1
+ backendRefs:
+ - name: service-1
+ port: 8080
+ - matches:
+ - path:
+ value: /foo2
+ backendRefs:
+ - name: service-2
+ port: 8080
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ hostnames:
+ - www.bar.com
+ parentRefs:
+ - namespace: default
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: /bar
+ backendRefs:
+ - name: service-3
+ port: 8080
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: 'primary.foo.com'
+ port: 3000
+referenceGrants:
+ - apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: ReferenceGrant
+ metadata:
+ namespace: envoy-gateway
+ name: referencegrant-1
+ spec:
+ from:
+ - group: gateway.envoyproxy.io
+ kind: SecurityPolicy
+ namespace: default
+ to:
+ - group: ""
+ kind: Service
+securityPolicies:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: SecurityPolicy
+ metadata:
+ namespace: default
+ name: policy-for-http-route-1
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ extAuth:
+ failOpen: true
+ headersToExtAuth:
+ - header1
+ - header2
+ grpc:
+ backendRefs:
+ - name: backend-fqdn
+ kind: Backend
+ group: gateway.envoyproxy.io
+ port: 3000
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.out.yaml
new file mode 100644
index 00000000000..a89bf53a8cf
--- /dev/null
+++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.out.yaml
@@ -0,0 +1,314 @@
+backends:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-fqdn
+ namespace: default
+ spec:
+ endpoints:
+ - fqdn:
+ hostname: primary.foo.com
+ port: 3000
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Invalid
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: gateway-1
+ namespace: default
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 2
+ conditions:
+ - lastTransitionTime: null
+ message: Sending translated listener configuration to the data plane
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ - lastTransitionTime: null
+ message: Listener has been successfully translated
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Listener references have been resolved
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ name: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-1
+ namespace: default
+ spec:
+ hostnames:
+ - www.foo.com
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /foo1
+ - backendRefs:
+ - name: service-2
+ port: 8080
+ matches:
+ - path:
+ value: /foo2
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ hostnames:
+ - www.bar.com
+ parentRefs:
+ - name: gateway-1
+ namespace: default
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-3
+ port: 8080
+ matches:
+ - path:
+ value: /bar
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: default
+ sectionName: http
+infraIR:
+ default/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: default/gateway-1/http
+ ports:
+ - containerPort: 10080
+ name: http-80
+ protocol: HTTP
+ servicePort: 80
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: default
+ name: default/gateway-1
+securityPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: SecurityPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-http-route-1
+ namespace: default
+ spec:
+ extAuth:
+ failOpen: true
+ grpc:
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-fqdn
+ port: 3000
+ headersToExtAuth:
+ - header1
+ - header2
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+xdsIR:
+ default/gateway-1:
+ accessLog:
+ text:
+ - path: /dev/stdout
+ http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.foo.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo1
+ security:
+ extAuth:
+ failOpen: true
+ grpc:
+ authority: primary.foo.com:3000
+ destination:
+ name: securitypolicy/default/policy-for-http-route-1/default/backend-fqdn
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ protocol: GRPC
+ weight: 1
+ headersToExtAuth:
+ - header1
+ - header2
+ name: securitypolicy/default/policy-for-http-route-1
+ - destination:
+ name: httproute/default/httproute-1/rule/1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.foo.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/1/match/0/www_foo_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo2
+ security:
+ extAuth:
+ failOpen: true
+ grpc:
+ authority: primary.foo.com:3000
+ destination:
+ name: securitypolicy/default/policy-for-http-route-1/default/backend-fqdn
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ protocol: GRPC
+ weight: 1
+ headersToExtAuth:
+ - header1
+ - header2
+ name: securitypolicy/default/policy-for-http-route-1
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.bar.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
diff --git a/internal/gatewayapi/tls.go b/internal/gatewayapi/tls.go
index 1d38897ed26..acde9bed339 100644
--- a/internal/gatewayapi/tls.go
+++ b/internal/gatewayapi/tls.go
@@ -88,10 +88,13 @@ func validateTLSSecretsData(secrets []*corev1.Secret, host *gwapiv1.Hostname) er
func verifyHostname(cert *x509.Certificate, host *gwapiv1.Hostname) ([]string, error) {
var matchedHosts []string
+ listenerContext := ListenerContext{
+ Listener: &gwapiv1.Listener{Hostname: host},
+ }
if len(cert.DNSNames) > 0 {
- matchedHosts = computeHosts(cert.DNSNames, host)
+ matchedHosts = computeHosts(cert.DNSNames, &listenerContext)
} else {
- matchedHosts = computeHosts([]string{cert.Subject.CommonName}, host)
+ matchedHosts = computeHosts([]string{cert.Subject.CommonName}, &listenerContext)
}
if len(matchedHosts) > 0 {
diff --git a/internal/gatewayapi/tls_test.go b/internal/gatewayapi/tls_test.go
index d97824382ce..87e8b27cad6 100644
--- a/internal/gatewayapi/tls_test.go
+++ b/internal/gatewayapi/tls_test.go
@@ -159,7 +159,6 @@ func TestValidateTLSSecretsData(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.Name, func(t *testing.T) {
secrets := createTestSecrets(t, tc.CertFile, tc.KeyFile)
require.NotNil(t, secrets)
@@ -204,7 +203,6 @@ func TestValidateCertificate(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.Name, func(t *testing.T) {
certData, err := os.ReadFile(filepath.Join("testdata", "tls", tc.CertFile))
require.NoError(t, err)
diff --git a/internal/gatewayapi/translator_test.go b/internal/gatewayapi/translator_test.go
index 357f6586bee..42bb1ca37b7 100644
--- a/internal/gatewayapi/translator_test.go
+++ b/internal/gatewayapi/translator_test.go
@@ -64,7 +64,6 @@ func TestTranslate(t *testing.T) {
require.NoError(t, err)
for _, inputFile := range inputFiles {
- inputFile := inputFile
t.Run(testName(inputFile), func(t *testing.T) {
input, err := os.ReadFile(inputFile)
require.NoError(t, err)
@@ -331,7 +330,6 @@ func TestTranslateWithExtensionKinds(t *testing.T) {
require.NoError(t, err)
for _, inputFile := range inputFiles {
- inputFile := inputFile
t.Run(testName(inputFile), func(t *testing.T) {
input, err := os.ReadFile(inputFile)
require.NoError(t, err)
@@ -625,7 +623,6 @@ func TestIsValidHostname(t *testing.T) {
}
for _, tc := range testcases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
err := translator.validateHostname(tc.hostname)
if tc.err == "" {
@@ -745,7 +742,6 @@ func TestIsValidCrossNamespaceRef(t *testing.T) {
testcases = append(testcases, modified)
for _, tc := range testcases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
var referenceGrants []*gwapiv1b1.ReferenceGrant
if tc.referenceGrant != nil {
diff --git a/internal/globalratelimit/runner/runner_test.go b/internal/globalratelimit/runner/runner_test.go
index e25f714792b..80598f7906e 100644
--- a/internal/globalratelimit/runner/runner_test.go
+++ b/internal/globalratelimit/runner/runner_test.go
@@ -202,7 +202,6 @@ func Test_subscribeAndTranslate(t *testing.T) {
}
for _, tt := range testCases {
- tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
diff --git a/internal/infrastructure/kubernetes/infra_resource.go b/internal/infrastructure/kubernetes/infra_resource.go
index fc471f8af33..bf32ecfd127 100644
--- a/internal/infrastructure/kubernetes/infra_resource.go
+++ b/internal/infrastructure/kubernetes/infra_resource.go
@@ -7,13 +7,18 @@ package kubernetes
import (
"context"
+ "fmt"
"time"
appsv1 "k8s.io/api/apps/v1"
autoscalingv2 "k8s.io/api/autoscaling/v2"
corev1 "k8s.io/api/core/v1"
policyv1 "k8s.io/api/policy/v1"
+ "k8s.io/apimachinery/pkg/api/equality"
+ apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/labels"
+ "k8s.io/apimachinery/pkg/types"
"github.com/envoyproxy/gateway/internal/metrics"
)
@@ -116,6 +121,45 @@ func (i *Infra) createOrUpdateDeployment(ctx context.Context, r ResourceRender)
}
}()
+ old := &appsv1.Deployment{}
+ err = i.Client.Get(ctx, types.NamespacedName{Name: deployment.Name, Namespace: deployment.Namespace}, old)
+ if err != nil {
+ if apierrors.IsNotFound(err) {
+ // It's the deployment creation.
+ return i.Client.ServerSideApply(ctx, deployment)
+ }
+ return err
+ }
+
+ if !equality.Semantic.DeepEqual(old.Spec.Selector, deployment.Spec.Selector) {
+ // Note: Deployment created by the old gateway controller may have a different selector generated based on a custom label feature,
+ // and it caused the issue that the gateway controller cannot update the deployment when users change the custom labels.
+ // Therefore, we changed the gateway to always use the same selector, independent of the custom labels -
+ // https://github.com/envoyproxy/gateway/issues/1818
+ //
+ // But, the change could break an existing deployment with custom labels initiated by the old gateway controller
+ // because the selector would be different.
+ //
+ // Here, as a workaround, we always copy the selector from the old deployment to the new deployment
+ // so that the update can be always applied successfully.
+ deployment.Spec.Selector = old.Spec.Selector
+
+ match, err := isSelectorMatch(deployment.Spec.Selector, deployment.Spec.Template.Labels)
+ if err != nil {
+ return err
+ }
+ if !match {
+ // If the selector now doesn't match with labels of the pod template, return an error.
+ // It could happen, for example, when users changed the custom label from {"foo": "bar"} to {"foo": "barv2"}
+ // because the pod's labels have {"foo": "barv2"} while the selector keeps {"foo": "bar"}.
+ // We cannot help this case, and just error it out.
+ // In this case, users should recreate the envoy proxy with the new custom label, instead of upgrading it.
+ // Once they recreate the envoy proxy, the envoy gateway of this version doesn't generate the selector based on the custom label,
+ // and the issue won't happen again, even if they have to the custom label again.
+ return fmt.Errorf("an illegal change in a custom label of EnvoyProxy is detected when updating %s/%s. The custom label config of deployment in EnvoyProxy, which is initiated with the envoy gateway of v1.1 or earlier, is immutable. Please recreate an envoy proxy with a new custom label if you need to change the custom label. This issue won't happen with the envoy proxy resource initialized by the envoygateway v1.2 or later", deployment.Namespace, deployment.Name)
+ }
+ }
+
return i.Client.ServerSideApply(ctx, deployment)
}
@@ -153,9 +197,56 @@ func (i *Infra) createOrUpdateDaemonSet(ctx context.Context, r ResourceRender) (
}
}()
+ old := &appsv1.DaemonSet{}
+ err = i.Client.Get(ctx, types.NamespacedName{Name: daemonSet.Name, Namespace: daemonSet.Namespace}, old)
+ if err != nil {
+ if apierrors.IsNotFound(err) {
+ // It's the daemonset creation.
+ return i.Client.ServerSideApply(ctx, daemonSet)
+ }
+ return err
+ }
+
+ if !equality.Semantic.DeepEqual(old.Spec.Selector, daemonSet.Spec.Selector) {
+ // Note: Daemonset created by the old gateway controller may have a different selector generated based on a custom label feature,
+ // and it caused the issue that the gateway controller cannot update the daemonset when users change the custom labels.
+ // Therefore, we changed the gateway to always use the same selector, independent of the custom labels -
+ // https://github.com/envoyproxy/gateway/issues/1818
+ //
+ // But, the change could break an existing daemonset with custom labels initiated by the old gateway controller
+ // because the selector would be different.
+ //
+ // Here, as a workaround, we always copy the selector from the old daemonset to the new daemonset
+ // so that the update can be always applied successfully.
+ daemonSet.Spec.Selector = old.Spec.Selector
+ match, err := isSelectorMatch(daemonSet.Spec.Selector, daemonSet.Spec.Template.Labels)
+ if err != nil {
+ return err
+ }
+ if !match {
+ // If the selector now doesn't match with labels of the pod template, return an error.
+ // It could happen, for example, when users changed the custom label from {"foo": "bar"} to {"foo": "barv2"}
+ // because the pod's labels have {"foo": "barv2"} while the selector keeps {"foo": "bar"}.
+ // We cannot help this case, and just error it out.
+ // In this case, users should recreate the envoy proxy with the new custom label, instead of upgrading it.
+ // Once they recreate the envoy proxy, the envoy gateway of this version doesn't generate the selector based on the custom label,
+ // and the issue won't happen again, even if they have to the custom label again.
+ return fmt.Errorf("an illegal change in a custom label of EnvoyProxy is detected when updating %s/%s. The custom label config of daemonset in EnvoyProxy, which is initiated with the envoy gateway of v1.1 or earlier, is immutable. Please recreate an envoy proxy with a new custom label if you need to change the custom label. This issue won't happen with the envoy proxy resource initialized by the envoygateway v1.2 or later", daemonSet.Namespace, daemonSet.Name)
+ }
+ }
+
return i.Client.ServerSideApply(ctx, daemonSet)
}
+func isSelectorMatch(labelselector *metav1.LabelSelector, l map[string]string) (bool, error) {
+ selector, err := metav1.LabelSelectorAsSelector(labelselector)
+ if err != nil {
+ return false, fmt.Errorf("invalid label selector is generated: %w", err)
+ }
+
+ return selector.Matches(labels.Set(l)), nil
+}
+
func (i *Infra) createOrUpdatePodDisruptionBudget(ctx context.Context, r ResourceRender) (err error) {
var (
pdb *policyv1.PodDisruptionBudget
diff --git a/internal/infrastructure/kubernetes/proxy/resource.go b/internal/infrastructure/kubernetes/proxy/resource.go
index 5045de6390a..406694be9bb 100644
--- a/internal/infrastructure/kubernetes/proxy/resource.go
+++ b/internal/infrastructure/kubernetes/proxy/resource.go
@@ -226,9 +226,9 @@ func expectedProxyContainers(infra *ir.ProxyInfra,
},
},
TimeoutSeconds: 1,
- PeriodSeconds: 10,
+ PeriodSeconds: 5,
SuccessThreshold: 1,
- FailureThreshold: 3,
+ FailureThreshold: 1,
},
Lifecycle: &corev1.Lifecycle{
PreStop: &corev1.LifecycleHandler{
diff --git a/internal/infrastructure/kubernetes/proxy/resource_provider.go b/internal/infrastructure/kubernetes/proxy/resource_provider.go
index e48122b62ea..dd5907b7d9b 100644
--- a/internal/infrastructure/kubernetes/proxy/resource_provider.go
+++ b/internal/infrastructure/kubernetes/proxy/resource_provider.go
@@ -192,6 +192,19 @@ func (r *ResourceRender) ConfigMap() (*corev1.ConfigMap, error) {
}, nil
}
+// stableSelector returns a stable selector based on the owning gateway labels.
+// "stable" here means the selector doesn't change when the infra is updated.
+func (r *ResourceRender) stableSelector() *metav1.LabelSelector {
+ labels := map[string]string{}
+ for k, v := range r.infra.GetProxyMetadata().Labels {
+ if k == gatewayapi.OwningGatewayNameLabel || k == gatewayapi.OwningGatewayNamespaceLabel || k == gatewayapi.OwningGatewayClassLabel {
+ labels[k] = v
+ }
+ }
+
+ return resource.GetSelector(envoyLabels(labels))
+}
+
// Deployment returns the expected Deployment based on the provided infra.
func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) {
proxyConfig := r.infra.GetProxyConfig()
@@ -222,8 +235,6 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) {
if err != nil {
return nil, err
}
- podLabels := r.getPodLabels(deploymentConfig.Pod)
- selector := resource.GetSelector(podLabels)
deployment := &appsv1.Deployment{
TypeMeta: metav1.TypeMeta{
@@ -238,10 +249,11 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) {
Spec: appsv1.DeploymentSpec{
Replicas: deploymentConfig.Replicas,
Strategy: *deploymentConfig.Strategy,
- Selector: selector,
+ // Deployment's selector is immutable.
+ Selector: r.stableSelector(),
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
- Labels: selector.MatchLabels,
+ Labels: r.getPodLabels(deploymentConfig.Pod),
Annotations: podAnnotations,
},
Spec: corev1.PodSpec{
@@ -317,8 +329,6 @@ func (r *ResourceRender) DaemonSet() (*appsv1.DaemonSet, error) {
if err != nil {
return nil, err
}
- podLabels := r.getPodLabels(daemonSetConfig.Pod)
- selector := resource.GetSelector(podLabels)
daemonSet := &appsv1.DaemonSet{
TypeMeta: metav1.TypeMeta{
@@ -331,11 +341,12 @@ func (r *ResourceRender) DaemonSet() (*appsv1.DaemonSet, error) {
Annotations: dsAnnotations,
},
Spec: appsv1.DaemonSetSpec{
- Selector: selector,
+ // Daemonset's selector is immutable.
+ Selector: r.stableSelector(),
UpdateStrategy: *daemonSetConfig.Strategy,
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
- Labels: selector.MatchLabels,
+ Labels: r.getPodLabels(daemonSetConfig.Pod),
Annotations: podAnnotations,
},
Spec: r.getPodSpec(containers, nil, daemonSetConfig.Pod, proxyConfig),
@@ -369,11 +380,6 @@ func (r *ResourceRender) PodDisruptionBudget() (*policyv1.PodDisruptionBudget, e
return nil, nil
}
- labels, err := r.getLabels()
- if err != nil {
- return nil, err
- }
-
return &policyv1.PodDisruptionBudget{
ObjectMeta: metav1.ObjectMeta{
Name: r.Name(),
@@ -385,9 +391,7 @@ func (r *ResourceRender) PodDisruptionBudget() (*policyv1.PodDisruptionBudget, e
},
Spec: policyv1.PodDisruptionBudgetSpec{
MinAvailable: &intstr.IntOrString{IntVal: ptr.Deref(podDisruptionBudget.MinAvailable, 0)},
- Selector: &metav1.LabelSelector{
- MatchLabels: labels,
- },
+ Selector: r.stableSelector(),
},
}, nil
}
diff --git a/internal/infrastructure/kubernetes/proxy/resource_test.go b/internal/infrastructure/kubernetes/proxy/resource_test.go
index 3cf71f2aea2..31054b1ef1d 100644
--- a/internal/infrastructure/kubernetes/proxy/resource_test.go
+++ b/internal/infrastructure/kubernetes/proxy/resource_test.go
@@ -30,7 +30,6 @@ func TestEnvoyPodSelector(t *testing.T) {
}
for _, tc := range cases {
- tc := tc
t.Run("", func(t *testing.T) {
got := envoyLabels(tc.in)
require.Equal(t, tc.expected, got)
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml
index 0622977315d..7f1bc6c41ab 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml
@@ -74,12 +74,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml
index 8f2752be07c..72c5d026b9b 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml
@@ -16,7 +16,6 @@ spec:
app.kubernetes.io/component: proxy
app.kubernetes.io/managed-by: envoy-gateway
app.kubernetes.io/name: envoy
- foo.bar: custom-label
gateway.envoyproxy.io/owning-gateway-name: default
gateway.envoyproxy.io/owning-gateway-namespace: default
template:
@@ -258,12 +257,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml
index 1d5a93c5ba2..b59b07a086c 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml
@@ -256,12 +256,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml
index 7ee2909f896..0808d5c0180 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml
@@ -241,12 +241,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml
index 7190df8f86f..73bc606336c 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml
@@ -212,12 +212,12 @@ spec:
name: EnvoyHTTPSPort
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml
index 3ceb7cee0ea..4f2f396b763 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml
@@ -260,12 +260,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml
index 9b8a0fcaf4b..2088c4cb3ce 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml
@@ -23,8 +23,6 @@ spec:
app.kubernetes.io/name: envoy
gateway.envoyproxy.io/owning-gateway-name: default
gateway.envoyproxy.io/owning-gateway-namespace: default
- label1: value1-override
- label2: value2
template:
metadata:
annotations:
@@ -252,12 +250,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml
index 970f58ba1ab..169eeb59394 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml
@@ -241,12 +241,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml
index 3bb5ccbe620..725055a9f4d 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml
@@ -242,12 +242,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml
index 060e0d42b92..b993f3bfbc1 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml
@@ -260,12 +260,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml
index ffc184f3fd8..c43c64302f3 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml
@@ -246,12 +246,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml
index 850b8a2510e..568aa4164ad 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml
@@ -74,12 +74,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml
index e75a89be5bc..612363ca2e6 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml
@@ -243,12 +243,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml
index 424eae5f2a3..a0324cb54e4 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml
@@ -241,12 +241,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml
index fb4fc761bb2..c31ea245056 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml
@@ -241,12 +241,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml
index 96a1e21f963..a0ebcf2e918 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml
@@ -241,12 +241,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml
index 7436383cc8e..e1d7c76a069 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml
@@ -241,12 +241,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml
index e98fd731131..b985e8d0f02 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml
@@ -77,12 +77,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml
index edcfa7b5322..445bf70d28c 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml
@@ -78,12 +78,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml
index 88983936f25..7628caffe1d 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml
@@ -19,7 +19,6 @@ spec:
app.kubernetes.io/component: proxy
app.kubernetes.io/managed-by: envoy-gateway
app.kubernetes.io/name: envoy
- foo.bar: custom-label
gateway.envoyproxy.io/owning-gateway-name: default
gateway.envoyproxy.io/owning-gateway-namespace: default
strategy:
@@ -263,12 +262,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml
index 07ceadcfb6d..f017b2d26ed 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml
@@ -19,7 +19,6 @@ spec:
app.kubernetes.io/component: proxy
app.kubernetes.io/managed-by: envoy-gateway
app.kubernetes.io/name: envoy
- foo.bar: custom-label
gateway.envoyproxy.io/owning-gateway-name: default
gateway.envoyproxy.io/owning-gateway-namespace: default
strategy:
@@ -263,12 +262,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml
index 4000dacbda3..992d976f40e 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml
@@ -261,12 +261,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml
index 44777d51a52..3bd69459a53 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml
@@ -245,12 +245,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml
index bee1b53938a..fa7078ae684 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml
@@ -216,12 +216,12 @@ spec:
name: EnvoyHTTPSPort
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml
index e84fd418ead..21ddbb9e6fc 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml
@@ -265,12 +265,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml
index 460de06f269..0fb0d414016 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml
@@ -25,8 +25,6 @@ spec:
app.kubernetes.io/name: envoy
gateway.envoyproxy.io/owning-gateway-name: default
gateway.envoyproxy.io/owning-gateway-namespace: default
- label1: value1-override
- label2: value2
strategy:
type: RollingUpdate
template:
@@ -256,12 +254,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml
index 5fe7b493015..8d70d4d85cd 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml
@@ -245,12 +245,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml
index 9ab5e2cc0dd..9f70f8bb642 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml
@@ -246,12 +246,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml
index 51f0ccc3a8a..1395e60cba7 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml
@@ -265,12 +265,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml
index cfc2685d49d..1bb027eacc5 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml
@@ -250,12 +250,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml
index c01d19873f1..44e6370811c 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml
@@ -78,12 +78,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml
index ef9f75cc636..397b43b9753 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml
@@ -245,12 +245,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml
index 81d0cbac111..a1aa0917bfd 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml
@@ -247,12 +247,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml
index 83f2881be23..57258870015 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml
@@ -245,12 +245,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml
index f1dc2a9bc6f..2dd83e8e3d6 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml
@@ -245,12 +245,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml
index cc8f66c7e33..72d297ca12a 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml
@@ -245,12 +245,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml
index 4083f99d3fe..20fcb8589a2 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml
@@ -245,12 +245,12 @@ spec:
name: metrics
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /ready
port: 19001
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/proxy_configmap_test.go b/internal/infrastructure/kubernetes/proxy_configmap_test.go
index b16a0f61bbf..a761b569498 100644
--- a/internal/infrastructure/kubernetes/proxy_configmap_test.go
+++ b/internal/infrastructure/kubernetes/proxy_configmap_test.go
@@ -95,7 +95,6 @@ func TestCreateOrUpdateProxyConfigMap(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
var cli client.Client
if tc.current != nil {
@@ -162,7 +161,6 @@ func TestDeleteConfigProxyMap(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
cli := fakeclient.NewClientBuilder().WithScheme(envoygateway.GetScheme()).WithObjects(tc.current).Build()
kube := NewInfra(cli, cfg)
diff --git a/internal/infrastructure/kubernetes/proxy_daemonset_test.go b/internal/infrastructure/kubernetes/proxy_daemonset_test.go
new file mode 100644
index 00000000000..e9fef86470c
--- /dev/null
+++ b/internal/infrastructure/kubernetes/proxy_daemonset_test.go
@@ -0,0 +1,266 @@
+// 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 kubernetes
+
+import (
+ "context"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+ appsv1 "k8s.io/api/apps/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/utils/ptr"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ fakeclient "sigs.k8s.io/controller-runtime/pkg/client/fake"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/envoygateway"
+ "github.com/envoyproxy/gateway/internal/envoygateway/config"
+ "github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/proxy"
+ resource2 "github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/resource"
+ "github.com/envoyproxy/gateway/internal/ir"
+)
+
+func daemonsetWithImage(ds *appsv1.DaemonSet, image string) *appsv1.DaemonSet {
+ dCopy := ds.DeepCopy()
+ for i, c := range dCopy.Spec.Template.Spec.Containers {
+ if c.Name == envoyContainerName {
+ dCopy.Spec.Template.Spec.Containers[i].Image = image
+ }
+ }
+ return dCopy
+}
+
+func daemonsetWithSelectorAndLabel(ds *appsv1.DaemonSet, selector *metav1.LabelSelector, additionalLabel map[string]string) *appsv1.DaemonSet {
+ dCopy := ds.DeepCopy()
+ if selector != nil {
+ dCopy.Spec.Selector = selector
+ }
+ for k, v := range additionalLabel {
+ dCopy.Spec.Template.Labels[k] = v
+ }
+ return dCopy
+}
+
+func TestCreateOrUpdateProxyDaemonSet(t *testing.T) {
+ cfg, err := config.New()
+ require.NoError(t, err)
+
+ infra := ir.NewInfra()
+ infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNamespaceLabel] = "default"
+ infra.Proxy.GetProxyMetadata().Labels[gatewayapi.OwningGatewayNameLabel] = infra.Proxy.Name
+ infra.Proxy.Config = &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ // Use daemonset, instead of deployment.
+ EnvoyDaemonSet: egv1a1.DefaultKubernetesDaemonSet(egv1a1.DefaultEnvoyProxyImage),
+ EnvoyService: egv1a1.DefaultKubernetesService(),
+ },
+ },
+ },
+ }
+
+ r := proxy.NewResourceRender(cfg.Namespace, infra.GetProxyInfra(), cfg.EnvoyGateway)
+ ds, err := r.DaemonSet()
+ require.NoError(t, err)
+
+ testCases := []struct {
+ name string
+ in *ir.Infra
+ current *appsv1.DaemonSet
+ want *appsv1.DaemonSet
+ wantErr bool
+ }{
+ {
+ name: "create daemonset",
+ in: infra,
+ want: ds,
+ },
+ {
+ name: "daemonset exists",
+ in: infra,
+ current: ds,
+ want: ds,
+ },
+ {
+ name: "update daemonset image",
+ in: &ir.Infra{
+ Proxy: &ir.ProxyInfra{
+ Metadata: &ir.InfraMetadata{
+ Labels: map[string]string{
+ gatewayapi.OwningGatewayNamespaceLabel: "default",
+ gatewayapi.OwningGatewayNameLabel: infra.Proxy.Name,
+ },
+ },
+ Config: &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDaemonSet: &egv1a1.KubernetesDaemonSetSpec{
+ Container: &egv1a1.KubernetesContainerSpec{
+ Image: ptr.To("envoyproxy/envoy-dev:v1.2.3"),
+ },
+ },
+ },
+ },
+ },
+ },
+ Name: ir.DefaultProxyName,
+ Listeners: ir.NewProxyListeners(),
+ },
+ },
+ current: ds,
+ want: daemonsetWithImage(ds, "envoyproxy/envoy-dev:v1.2.3"),
+ },
+ {
+ name: "update daemonset label",
+ in: &ir.Infra{
+ Proxy: &ir.ProxyInfra{
+ Metadata: &ir.InfraMetadata{
+ Labels: map[string]string{
+ gatewayapi.OwningGatewayNamespaceLabel: "default",
+ gatewayapi.OwningGatewayNameLabel: infra.Proxy.Name,
+ },
+ },
+ Config: &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDaemonSet: &egv1a1.KubernetesDaemonSetSpec{
+ Pod: &egv1a1.KubernetesPodSpec{
+ Labels: map[string]string{
+ // Add a new label to the custom label config.
+ // It wouldn't break the daemonset because the selector would still match after this label update.
+ "custom-label": "version1",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Name: ir.DefaultProxyName,
+ Listeners: ir.NewProxyListeners(),
+ },
+ },
+ current: ds,
+ // Selector is not updated with a custom label, only pod's label is updated.
+ want: daemonsetWithSelectorAndLabel(ds, nil, map[string]string{"custom-label": "version1"}),
+ },
+ {
+ name: "the daemonset originally has a selector and label, and an user add a new label to the custom label config",
+ in: &ir.Infra{
+ Proxy: &ir.ProxyInfra{
+ Metadata: &ir.InfraMetadata{
+ Labels: map[string]string{
+ gatewayapi.OwningGatewayNamespaceLabel: "default",
+ gatewayapi.OwningGatewayNameLabel: infra.Proxy.Name,
+ },
+ },
+ Config: &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDaemonSet: &egv1a1.KubernetesDaemonSetSpec{
+ Pod: &egv1a1.KubernetesPodSpec{
+ Labels: map[string]string{
+ "custom-label": "version1",
+ "another-custom-label": "version1", // added.
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Name: ir.DefaultProxyName,
+ Listeners: ir.NewProxyListeners(),
+ },
+ },
+ current: daemonsetWithSelectorAndLabel(ds, resource2.GetSelector(map[string]string{"custom-label": "version1"}), map[string]string{"custom-label": "version1"}),
+ // Only label is updated, selector is not updated.
+ want: daemonsetWithSelectorAndLabel(ds, resource2.GetSelector(map[string]string{"custom-label": "version1"}), map[string]string{"custom-label": "version1", "another-custom-label": "version1"}),
+ },
+ {
+ name: "the daemonset originally has a selector and label, and an user update an existing custom label",
+ in: &ir.Infra{
+ Proxy: &ir.ProxyInfra{
+ Metadata: &ir.InfraMetadata{
+ Labels: map[string]string{
+ gatewayapi.OwningGatewayNamespaceLabel: "default",
+ gatewayapi.OwningGatewayNameLabel: infra.Proxy.Name,
+ },
+ },
+ Config: &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDaemonSet: &egv1a1.KubernetesDaemonSetSpec{
+ Pod: &egv1a1.KubernetesPodSpec{
+ Labels: map[string]string{
+ // Update the label value which will break the daemonset
+ // because the selector cannot be updated while the user wants to update the label value.
+ // We cannot help this case, just emit an error and let the user recreate the envoy proxy by themselves.
+ "custom-label": "version2",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Name: ir.DefaultProxyName,
+ Listeners: ir.NewProxyListeners(),
+ },
+ },
+ current: daemonsetWithSelectorAndLabel(ds, resource2.GetSelector(map[string]string{"custom-label": "version1"}), map[string]string{"custom-label": "version1"}),
+ wantErr: true,
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ var cli client.Client
+ if tc.current != nil {
+ cli = fakeclient.NewClientBuilder().
+ WithScheme(envoygateway.GetScheme()).
+ WithObjects(tc.current).
+ WithInterceptorFuncs(interceptorFunc).
+ Build()
+ } else {
+ cli = fakeclient.NewClientBuilder().
+ WithScheme(envoygateway.GetScheme()).
+ WithInterceptorFuncs(interceptorFunc).
+ Build()
+ }
+
+ kube := NewInfra(cli, cfg)
+ r := proxy.NewResourceRender(kube.Namespace, tc.in.GetProxyInfra(), cfg.EnvoyGateway)
+ err := kube.createOrUpdateDaemonSet(context.Background(), r)
+ if tc.wantErr {
+ require.Error(t, err)
+ return
+ }
+ require.NoError(t, err)
+
+ actual := &appsv1.DaemonSet{
+ ObjectMeta: metav1.ObjectMeta{
+ Namespace: kube.Namespace,
+ Name: proxy.ExpectedResourceHashedName(tc.in.Proxy.Name),
+ },
+ }
+ require.NoError(t, kube.Client.Get(context.Background(), client.ObjectKeyFromObject(actual), actual))
+ require.Equal(t, tc.want.Spec, actual.Spec)
+ })
+ }
+}
diff --git a/internal/infrastructure/kubernetes/proxy_deployment_test.go b/internal/infrastructure/kubernetes/proxy_deployment_test.go
index a1d595b750d..616101e18a2 100644
--- a/internal/infrastructure/kubernetes/proxy_deployment_test.go
+++ b/internal/infrastructure/kubernetes/proxy_deployment_test.go
@@ -21,6 +21,7 @@ import (
"github.com/envoyproxy/gateway/internal/envoygateway/config"
"github.com/envoyproxy/gateway/internal/gatewayapi"
"github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/proxy"
+ resource2 "github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/resource"
"github.com/envoyproxy/gateway/internal/ir"
)
@@ -39,6 +40,17 @@ func deploymentWithImage(deploy *appsv1.Deployment, image string) *appsv1.Deploy
return dCopy
}
+func deploymentWithSelectorAndLabel(deploy *appsv1.Deployment, selector *metav1.LabelSelector, additionalLabel map[string]string) *appsv1.Deployment {
+ dCopy := deploy.DeepCopy()
+ if selector != nil {
+ dCopy.Spec.Selector = selector
+ }
+ for k, v := range additionalLabel {
+ dCopy.Spec.Template.Labels[k] = v
+ }
+ return dCopy
+}
+
func TestCreateOrUpdateProxyDeployment(t *testing.T) {
cfg, err := config.New()
require.NoError(t, err)
@@ -56,6 +68,7 @@ func TestCreateOrUpdateProxyDeployment(t *testing.T) {
in *ir.Infra
current *appsv1.Deployment
want *appsv1.Deployment
+ wantErr bool
}{
{
name: "create deployment",
@@ -99,10 +112,116 @@ func TestCreateOrUpdateProxyDeployment(t *testing.T) {
current: deploy,
want: deploymentWithImage(deploy, "envoyproxy/envoy-dev:v1.2.3"),
},
+ {
+ name: "update deployment label",
+ in: &ir.Infra{
+ Proxy: &ir.ProxyInfra{
+ Metadata: &ir.InfraMetadata{
+ Labels: map[string]string{
+ gatewayapi.OwningGatewayNamespaceLabel: "default",
+ gatewayapi.OwningGatewayNameLabel: infra.Proxy.Name,
+ },
+ },
+ Config: &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
+ Pod: &egv1a1.KubernetesPodSpec{
+ Labels: map[string]string{
+ "custom-label": "version1", // added.
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Name: ir.DefaultProxyName,
+ Listeners: ir.NewProxyListeners(),
+ },
+ },
+ current: deploy,
+ // Selector is not updated with a custom label, only pod's label is updated.
+ want: deploymentWithSelectorAndLabel(deploy, nil, map[string]string{"custom-label": "version1"}),
+ },
+ {
+ name: "the daemonset originally has a selector and label, and an user add a new label to the custom label config",
+ in: &ir.Infra{
+ Proxy: &ir.ProxyInfra{
+ Metadata: &ir.InfraMetadata{
+ Labels: map[string]string{
+ gatewayapi.OwningGatewayNamespaceLabel: "default",
+ gatewayapi.OwningGatewayNameLabel: infra.Proxy.Name,
+ },
+ },
+ Config: &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
+ Pod: &egv1a1.KubernetesPodSpec{
+ Labels: map[string]string{
+ "custom-label": "version1",
+ // Add a new label to the custom label config.
+ // It wouldn't break the deployment because the selector would still match after this label update.
+ "another-custom-label": "version1", // added.
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Name: ir.DefaultProxyName,
+ Listeners: ir.NewProxyListeners(),
+ },
+ },
+ current: deploymentWithSelectorAndLabel(deploy, resource2.GetSelector(map[string]string{"custom-label": "version1"}), map[string]string{"custom-label": "version1"}),
+ // Only label is updated, selector is not updated.
+ want: deploymentWithSelectorAndLabel(deploy, resource2.GetSelector(map[string]string{"custom-label": "version1"}), map[string]string{"custom-label": "version1", "another-custom-label": "version1"}),
+ },
+ {
+ name: "the deployment originally has a selector and label, and an user update an existing custom label",
+ in: &ir.Infra{
+ Proxy: &ir.ProxyInfra{
+ Metadata: &ir.InfraMetadata{
+ Labels: map[string]string{
+ gatewayapi.OwningGatewayNamespaceLabel: "default",
+ gatewayapi.OwningGatewayNameLabel: infra.Proxy.Name,
+ },
+ },
+ Config: &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
+ Pod: &egv1a1.KubernetesPodSpec{
+ Labels: map[string]string{
+ // Update the label value which will break the deployment
+ // because the selector cannot be updated while the user wants to update the label value.
+ // We cannot help this case, just emit an error and let the user recreate the envoy proxy by themselves.
+ "custom-label": "version2",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ Name: ir.DefaultProxyName,
+ Listeners: ir.NewProxyListeners(),
+ },
+ },
+ current: deploymentWithSelectorAndLabel(deploy, resource2.GetSelector(map[string]string{"custom-label": "version1"}), map[string]string{"custom-label": "version1"}),
+ wantErr: true,
+ },
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
var cli client.Client
if tc.current != nil {
@@ -121,6 +240,10 @@ func TestCreateOrUpdateProxyDeployment(t *testing.T) {
kube := NewInfra(cli, cfg)
r := proxy.NewResourceRender(kube.Namespace, tc.in.GetProxyInfra(), cfg.EnvoyGateway)
err := kube.createOrUpdateDeployment(context.Background(), r)
+ if tc.wantErr {
+ require.Error(t, err)
+ return
+ }
require.NoError(t, err)
actual := &appsv1.Deployment{
@@ -155,7 +278,6 @@ func TestDeleteProxyDeployment(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
kube := NewInfra(cli, cfg)
diff --git a/internal/infrastructure/kubernetes/proxy_infra_test.go b/internal/infrastructure/kubernetes/proxy_infra_test.go
index 5c8a8d34695..de0690e82c8 100644
--- a/internal/infrastructure/kubernetes/proxy_infra_test.go
+++ b/internal/infrastructure/kubernetes/proxy_infra_test.go
@@ -143,7 +143,6 @@ func TestCreateProxyInfra(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
kube := newTestInfra(t)
@@ -210,7 +209,6 @@ func TestDeleteProxyInfra(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
kube := newTestInfra(t)
diff --git a/internal/infrastructure/kubernetes/proxy_service_test.go b/internal/infrastructure/kubernetes/proxy_service_test.go
index 0c1c0cc6b89..ffc8e4912e6 100644
--- a/internal/infrastructure/kubernetes/proxy_service_test.go
+++ b/internal/infrastructure/kubernetes/proxy_service_test.go
@@ -26,7 +26,6 @@ func TestDeleteProxyService(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
kube := newTestInfra(t)
infra := ir.NewInfra()
diff --git a/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go b/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go
index 2b92fc53417..9aed62b6e6b 100644
--- a/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go
+++ b/internal/infrastructure/kubernetes/proxy_serviceaccount_test.go
@@ -166,7 +166,6 @@ func TestCreateOrUpdateProxyServiceAccount(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
cfg, err := config.New()
require.NoError(t, err)
diff --git a/internal/infrastructure/kubernetes/ratelimit/resource.go b/internal/infrastructure/kubernetes/ratelimit/resource.go
index 162396f62db..9747be33b52 100644
--- a/internal/infrastructure/kubernetes/ratelimit/resource.go
+++ b/internal/infrastructure/kubernetes/ratelimit/resource.go
@@ -184,9 +184,9 @@ func expectedRateLimitContainers(rateLimit *egv1a1.RateLimit, rateLimitDeploymen
},
},
TimeoutSeconds: 1,
- PeriodSeconds: 10,
+ PeriodSeconds: 5,
SuccessThreshold: 1,
- FailureThreshold: 3,
+ FailureThreshold: 1,
},
},
}
@@ -329,7 +329,11 @@ func expectedRateLimitContainerEnv(rateLimit *egv1a1.RateLimit, rateLimitDeploym
},
{
Name: UseStatsdEnvVar,
- Value: "false",
+ Value: "true",
+ },
+ {
+ Name: "STATSD_PORT",
+ Value: "9125",
},
{
Name: ConfigTypeEnvVar,
diff --git a/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go b/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go
index 4ee3a144bd9..47c4901e198 100644
--- a/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go
+++ b/internal/infrastructure/kubernetes/ratelimit/resource_provider_test.go
@@ -56,7 +56,6 @@ func TestRateLimitLabelSelector(t *testing.T) {
}
for _, tc := range cases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
got := LabelSelector()
require.ElementsMatch(t, tc.expected, got)
@@ -80,7 +79,6 @@ func TestRateLimitLabels(t *testing.T) {
}
for _, tc := range cases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
got := rateLimitLabels()
require.Equal(t, tc.expected, got)
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml
index c750b09a0b9..c6c0bb1a696 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml
@@ -50,7 +50,9 @@ spec:
- name: LOG_LEVEL
value: info
- name: USE_STATSD
- value: "false"
+ value: "true"
+ - name: STATSD_PORT
+ value: "9125"
- name: CONFIG_TYPE
value: GRPC_XDS_SOTW
- name: CONFIG_GRPC_XDS_SERVER_URL
@@ -87,12 +89,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml
index c750b09a0b9..c6c0bb1a696 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml
@@ -50,7 +50,9 @@ spec:
- name: LOG_LEVEL
value: info
- name: USE_STATSD
- value: "false"
+ value: "true"
+ - name: STATSD_PORT
+ value: "9125"
- name: CONFIG_TYPE
value: GRPC_XDS_SOTW
- name: CONFIG_GRPC_XDS_SERVER_URL
@@ -87,12 +89,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml
index 277d5e649d9..26c21e23653 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml
@@ -51,7 +51,9 @@ spec:
- name: LOG_LEVEL
value: info
- name: USE_STATSD
- value: "false"
+ value: "true"
+ - name: STATSD_PORT
+ value: "9125"
- name: CONFIG_TYPE
value: GRPC_XDS_SOTW
- name: CONFIG_GRPC_XDS_SERVER_URL
@@ -88,12 +90,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml
index 0cbbd6dbbb8..0dcbfb3f209 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml
@@ -47,7 +47,9 @@ spec:
- name: LOG_LEVEL
value: info
- name: USE_STATSD
- value: "false"
+ value: "true"
+ - name: STATSD_PORT
+ value: "9125"
- name: CONFIG_TYPE
value: GRPC_XDS_SOTW
- name: CONFIG_GRPC_XDS_SERVER_URL
@@ -84,12 +86,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml
index 1d53f34a9bc..78cdd0c784d 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml
@@ -51,7 +51,9 @@ spec:
- name: LOG_LEVEL
value: info
- name: USE_STATSD
- value: "false"
+ value: "true"
+ - name: STATSD_PORT
+ value: "9125"
- name: CONFIG_TYPE
value: GRPC_XDS_SOTW
- name: CONFIG_GRPC_XDS_SERVER_URL
@@ -103,12 +105,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml
index 56bd0a7dfe3..f0396c5aa44 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml
@@ -51,7 +51,9 @@ spec:
- name: LOG_LEVEL
value: info
- name: USE_STATSD
- value: "false"
+ value: "true"
+ - name: STATSD_PORT
+ value: "9125"
- name: CONFIG_TYPE
value: GRPC_XDS_SOTW
- name: CONFIG_GRPC_XDS_SERVER_URL
@@ -103,12 +105,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml
index 4468e0df0e4..9bf03106f2d 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml
@@ -50,7 +50,9 @@ spec:
- name: LOG_LEVEL
value: info
- name: USE_STATSD
- value: "false"
+ value: "true"
+ - name: STATSD_PORT
+ value: "9125"
- name: CONFIG_TYPE
value: GRPC_XDS_SOTW
- name: CONFIG_GRPC_XDS_SERVER_URL
@@ -91,12 +93,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml
index 826deab69ba..c6c0bb1a696 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml
@@ -51,6 +51,8 @@ spec:
value: info
- name: USE_STATSD
value: "true"
+ - name: STATSD_PORT
+ value: "9125"
- name: CONFIG_TYPE
value: GRPC_XDS_SOTW
- name: CONFIG_GRPC_XDS_SERVER_URL
@@ -87,12 +89,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml
index 790de9e159a..8482050ec25 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml
@@ -51,7 +51,9 @@ spec:
- name: LOG_LEVEL
value: info
- name: USE_STATSD
- value: "false"
+ value: "true"
+ - name: STATSD_PORT
+ value: "9125"
- name: CONFIG_TYPE
value: GRPC_XDS_SOTW
- name: CONFIG_GRPC_XDS_SERVER_URL
@@ -88,12 +90,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/redis-tls-settings.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/redis-tls-settings.yaml
index e3e723c1d40..2e223af79c4 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/redis-tls-settings.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/redis-tls-settings.yaml
@@ -51,6 +51,8 @@ spec:
value: info
- name: USE_STATSD
value: "true"
+ - name: STATSD_PORT
+ value: "9125"
- name: CONFIG_TYPE
value: GRPC_XDS_SOTW
- name: CONFIG_GRPC_XDS_SERVER_URL
@@ -95,12 +97,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml
index 5cbedb98853..525c2b1f75d 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml
@@ -51,6 +51,8 @@ spec:
value: info
- name: USE_STATSD
value: "true"
+ - name: STATSD_PORT
+ value: "9125"
- name: CONFIG_TYPE
value: GRPC_XDS_SOTW
- name: CONFIG_GRPC_XDS_SERVER_URL
@@ -95,12 +97,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/volumes.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/volumes.yaml
index fcee6df457d..165a6819288 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/volumes.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/volumes.yaml
@@ -51,6 +51,8 @@ spec:
value: info
- name: USE_STATSD
value: "true"
+ - name: STATSD_PORT
+ value: "9125"
- name: CONFIG_TYPE
value: GRPC_XDS_SOTW
- name: CONFIG_GRPC_XDS_SERVER_URL
@@ -95,12 +97,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-node-selector.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-node-selector.yaml
index 1365ac63f8f..44ea2f4b856 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-node-selector.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-node-selector.yaml
@@ -51,7 +51,9 @@ spec:
- name: LOG_LEVEL
value: info
- name: USE_STATSD
- value: "false"
+ value: "true"
+ - name: STATSD_PORT
+ value: "9125"
- name: CONFIG_TYPE
value: GRPC_XDS_SOTW
- name: CONFIG_GRPC_XDS_SERVER_URL
@@ -88,12 +90,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-topology-spread-constraints.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-topology-spread-constraints.yaml
index 1558a925c33..9ca2c8e53e9 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-topology-spread-constraints.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-topology-spread-constraints.yaml
@@ -51,7 +51,9 @@ spec:
- name: LOG_LEVEL
value: info
- name: USE_STATSD
- value: "false"
+ value: "true"
+ - name: STATSD_PORT
+ value: "9125"
- name: CONFIG_TYPE
value: GRPC_XDS_SOTW
- name: CONFIG_GRPC_XDS_SERVER_URL
@@ -88,12 +90,12 @@ spec:
name: grpc
protocol: TCP
readinessProbe:
- failureThreshold: 3
+ failureThreshold: 1
httpGet:
path: /healthcheck
port: 8080
scheme: HTTP
- periodSeconds: 10
+ periodSeconds: 5
successThreshold: 1
timeoutSeconds: 1
resources:
diff --git a/internal/infrastructure/kubernetes/ratelimit_deployment_test.go b/internal/infrastructure/kubernetes/ratelimit_deployment_test.go
index d57e003d383..ea0e5017fd3 100644
--- a/internal/infrastructure/kubernetes/ratelimit_deployment_test.go
+++ b/internal/infrastructure/kubernetes/ratelimit_deployment_test.go
@@ -64,7 +64,6 @@ func TestCreateOrUpdateRateLimitDeployment(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
var cli client.Client
if tc.current != nil {
@@ -120,7 +119,6 @@ func TestDeleteRateLimitDeployment(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
kube := newTestInfra(t)
kube.EnvoyGateway.RateLimit = rl
diff --git a/internal/infrastructure/kubernetes/ratelimit_infra_test.go b/internal/infrastructure/kubernetes/ratelimit_infra_test.go
index a5934b12086..1b4976ac361 100644
--- a/internal/infrastructure/kubernetes/ratelimit_infra_test.go
+++ b/internal/infrastructure/kubernetes/ratelimit_infra_test.go
@@ -127,7 +127,6 @@ func TestCreateRateLimitInfra(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
kube := newTestInfra(t)
@@ -193,7 +192,6 @@ func TestDeleteRateLimitInfra(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
kube := newTestInfra(t)
diff --git a/internal/infrastructure/kubernetes/ratelimit_service_test.go b/internal/infrastructure/kubernetes/ratelimit_service_test.go
index d117d9d57bf..db6578e2a31 100644
--- a/internal/infrastructure/kubernetes/ratelimit_service_test.go
+++ b/internal/infrastructure/kubernetes/ratelimit_service_test.go
@@ -34,7 +34,6 @@ func TestDeleteRateLimitService(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
kube := newTestInfra(t)
diff --git a/internal/infrastructure/kubernetes/ratelimit_serviceaccount_test.go b/internal/infrastructure/kubernetes/ratelimit_serviceaccount_test.go
index 53084f6620d..630fa2e330a 100644
--- a/internal/infrastructure/kubernetes/ratelimit_serviceaccount_test.go
+++ b/internal/infrastructure/kubernetes/ratelimit_serviceaccount_test.go
@@ -88,7 +88,6 @@ func TestCreateOrUpdateRateLimitServiceAccount(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
var cli client.Client
if tc.current != nil {
diff --git a/internal/infrastructure/kubernetes/resource/resource.go b/internal/infrastructure/kubernetes/resource/resource.go
index dbdc289eec3..dcbbadadb40 100644
--- a/internal/infrastructure/kubernetes/resource/resource.go
+++ b/internal/infrastructure/kubernetes/resource/resource.go
@@ -38,7 +38,7 @@ func ExpectedServiceSpec(service *egv1a1.KubernetesServiceSpec) corev1.ServiceSp
if service.AllocateLoadBalancerNodePorts != nil {
serviceSpec.AllocateLoadBalancerNodePorts = service.AllocateLoadBalancerNodePorts
}
- if service.LoadBalancerSourceRanges != nil && len(service.LoadBalancerSourceRanges) > 0 {
+ if len(service.LoadBalancerSourceRanges) > 0 {
serviceSpec.LoadBalancerSourceRanges = service.LoadBalancerSourceRanges
}
if service.LoadBalancerIP != nil {
diff --git a/internal/infrastructure/kubernetes/resource/resource_test.go b/internal/infrastructure/kubernetes/resource/resource_test.go
index b65549911c7..52c1d73f6da 100644
--- a/internal/infrastructure/kubernetes/resource/resource_test.go
+++ b/internal/infrastructure/kubernetes/resource/resource_test.go
@@ -156,7 +156,6 @@ func TestGetSelector(t *testing.T) {
}
for _, tc := range cases {
- tc := tc
t.Run("", func(t *testing.T) {
got := GetSelector(tc.in)
require.Equal(t, tc.expected, got.MatchLabels)
diff --git a/internal/ir/infra_test.go b/internal/ir/infra_test.go
index dcc1e0324d5..92781e06c61 100644
--- a/internal/ir/infra_test.go
+++ b/internal/ir/infra_test.go
@@ -116,7 +116,6 @@ func TestValidateInfra(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
err := tc.infra.Validate()
if !tc.expect {
@@ -142,7 +141,6 @@ func TestNewInfra(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
actual := NewInfra()
require.Equal(t, tc.expected, actual)
@@ -165,7 +163,6 @@ func TestNewProxyInfra(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
actual := NewProxyInfra()
require.Equal(t, tc.expected, actual)
@@ -205,7 +202,6 @@ func TestObjectName(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
actual := tc.infra.Proxy.ObjectName()
require.Equal(t, tc.expected, actual)
diff --git a/internal/ir/xds.go b/internal/ir/xds.go
index 7cc5ed8f354..c698bea626d 100644
--- a/internal/ir/xds.go
+++ b/internal/ir/xds.go
@@ -25,6 +25,10 @@ import (
egv1a1validation "github.com/envoyproxy/gateway/api/v1alpha1/validation"
)
+const (
+ EmptyPath = ""
+)
+
var (
ErrListenerNameEmpty = errors.New("field Name must be specified")
ErrListenerAddressInvalid = errors.New("field Address must be a valid IP address")
@@ -490,6 +494,12 @@ type HeaderSettings struct {
// (Edge request is the request from external clients to front Envoy) and not reset it, which is the current Envoy behaviour.
// It defaults to false.
PreserveXRequestID bool `json:"preserveXRequestID,omitempty" yaml:"preserveXRequestID,omitempty"`
+
+ // EarlyAddRequestHeaders defines headers that would be added before envoy request processing.
+ EarlyAddRequestHeaders []AddHeader `json:"earlyAddRequestHeaders,omitempty" yaml:"earlyAddRequestHeaders,omitempty"`
+
+ // EarlyRemoveRequestHeaders defines headers that would be removed before envoy request processing.
+ EarlyRemoveRequestHeaders []string `json:"earlyRemoveRequestHeaders,omitempty" yaml:"earlyRemoveRequestHeaders,omitempty"`
}
// ClientTimeout sets the timeout configuration for downstream connections
@@ -565,8 +575,8 @@ type HTTPRoute struct {
UseClientProtocol *bool `json:"useClientProtocol,omitempty" yaml:"useClientProtocol,omitempty"`
// Metadata is used to enrich envoy route metadata with user and provider-specific information
Metadata *ResourceMetadata `json:"metadata,omitempty" yaml:"metadata,omitempty"`
- // DNS is used to configure how DNS resolution is handled for the route
- DNS *DNS `json:"dns,omitempty" yaml:"dns,omitempty"`
+ // SessionPersistence holds the configuration for session persistence.
+ SessionPersistence *SessionPersistence `json:"sessionPersistence,omitempty" yaml:"sessionPersistence,omitempty"`
}
// DNS contains configuration options for DNS resolution.
@@ -578,6 +588,33 @@ type DNS struct {
RespectDNSTTL *bool `json:"respectDnsTtl,omitempty"`
}
+// SessionPersistence defines the desired state of SessionPersistence.
+// +k8s:deepcopy-gen=true
+type SessionPersistence struct {
+ // Cookie defines the configuration for cookie-based session persistence.
+ // Either Cookie or Header must be non-empty.
+ Cookie *CookieBasedSessionPersistence `json:"cookie,omitempty" yaml:"cookie,omitempty"`
+ // Header defines the configuration for header-based session persistence.
+ // Either Cookie or Header must be non-empty.
+ Header *HeaderBasedSessionPersistence `json:"header,omitempty" yaml:"header,omitempty"`
+}
+
+// CookieBasedSessionPersistence defines the configuration for cookie-based session persistence.
+// +k8s:deepcopy-gen=true
+type CookieBasedSessionPersistence struct {
+ // Name defines the name of the persistent session token.
+ Name string `json:"name"`
+
+ TTL *metav1.Duration `json:"ttl,omitempty" yaml:"ttl,omitempty"`
+}
+
+// HeaderBasedSessionPersistence defines the configuration for header-based session persistence.
+// +k8s:deepcopy-gen=true
+type HeaderBasedSessionPersistence struct {
+ // Name defines the name of the persistent session token.
+ Name string `json:"name"`
+}
+
// TrafficFeatures holds the information associated with the Backend Traffic Policy.
// +k8s:deepcopy-gen=true
type TrafficFeatures struct {
@@ -605,6 +642,8 @@ type TrafficFeatures struct {
// HTTP2 provides HTTP/2 configuration for clusters
// +optional
HTTP2 *HTTP2Settings `json:"http2,omitempty" yaml:"http2,omitempty"`
+ // DNS is used to configure how DNS resolution is handled by the Envoy Proxy cluster
+ DNS *DNS `json:"dns,omitempty" yaml:"dns,omitempty"`
}
func (b *TrafficFeatures) Validate() error {
@@ -817,6 +856,9 @@ type ExtAuth struct {
// Only one of GRPCService or HTTPService may be specified.
HTTP *HTTPExtAuthService `json:"http,omitempty"`
+ // Traffic contains configuration for traffic features for the ExtAuth service
+ Traffic *TrafficFeatures `json:"traffic,omitempty"`
+
// HeadersToExtAuth defines the client request headers that will be included
// in the request to the external authorization service.
// Note: If not specified, the default behavior for gRPC and HTTP external
@@ -1113,6 +1155,10 @@ type DestinationSetting struct {
// invalid endpoints are represents with a
// non-zero weight with an empty endpoints list
Weight *uint32 `json:"weight,omitempty" yaml:"weight,omitempty"`
+ // Priority default to priority 0, the highest level.
+ // If multiple destinations share the same priority, they will all be utilized.
+ // Lower priority endpoints will be used only if higher priority levels are unavailable.
+ Priority *uint32 `json:"priority,omitempty"`
// Protocol associated with this destination/port.
Protocol AppProtocol `json:"protocol,omitempty" yaml:"protocol,omitempty"`
Endpoints []*DestinationEndpoint `json:"endpoints,omitempty" yaml:"endpoints,omitempty"`
@@ -1194,9 +1240,9 @@ func NewDestEndpoint(host string, port uint32) *DestinationEndpoint {
// AddHeader configures a header to be added to a request or response.
// +k8s:deepcopy-gen=true
type AddHeader struct {
- Name string `json:"name" yaml:"name"`
- Value string `json:"value" yaml:"value"`
- Append bool `json:"append" yaml:"append"`
+ Name string `json:"name" yaml:"name"`
+ Value []string `json:"value" yaml:"value"`
+ Append bool `json:"append" yaml:"append"`
}
// Validate the fields within the AddHeader structure
@@ -1514,7 +1560,8 @@ type UDPRoute struct {
Timeout *Timeout `json:"timeout,omitempty" yaml:"timeout,omitempty"`
// settings of upstream connection
BackendConnection *BackendConnection `json:"backendConnection,omitempty" yaml:"backendConnection,omitempty"`
- DNS *DNS `json:"dns,omitempty" yaml:"dns,omitempty"`
+ // DNS is used to configure how DNS resolution is handled by the Envoy Proxy cluster
+ DNS *DNS `json:"dns,omitempty" yaml:"dns,omitempty"`
}
// Validate the fields within the UDPListener structure
@@ -1653,6 +1700,7 @@ type ALSAccessLog struct {
CELMatches []string `json:"celMatches,omitempty" yaml:"celMatches,omitempty"`
LogName string `json:"name" yaml:"name"`
Destination RouteDestination `json:"destination,omitempty" yaml:"destination,omitempty"`
+ Traffic *TrafficFeatures `json:"traffic,omitempty" yaml:"traffic,omitempty"`
Type egv1a1.ALSEnvoyProxyAccessLogType `json:"type" yaml:"type"`
Text *string `json:"text,omitempty" yaml:"text,omitempty"`
Attributes map[string]string `json:"attributes,omitempty" yaml:"attributes,omitempty"`
@@ -1676,6 +1724,7 @@ type OpenTelemetryAccessLog struct {
Attributes map[string]string `json:"attributes,omitempty" yaml:"attributes,omitempty"`
Resources map[string]string `json:"resources,omitempty" yaml:"resources,omitempty"`
Destination RouteDestination `json:"destination,omitempty" yaml:"destination,omitempty"`
+ Traffic *TrafficFeatures `json:"traffic,omitempty" yaml:"traffic,omitempty"`
}
// EnvoyPatchPolicy defines the intermediate representation of the EnvoyPatchPolicy resource.
@@ -1716,7 +1765,12 @@ type JSONPatchOperation struct {
Op string `json:"op" yaml:"op"`
// Path is the location of the target document/field where the operation will be performed
// Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details.
- Path string `json:"path" yaml:"path"`
+ // +optional
+ Path *string `json:"path,omitempty" yaml:"path,omitempty"`
+ // JSONPath specifies the locations of the target document/field where the operation will be performed
+ // Refer to https://datatracker.ietf.org/doc/rfc9535/ for more details.
+ // +optional
+ JSONPath *string `json:"jsonPath,omitempty" yaml:"jsonPath,omitempty"`
// From is the source location of the value to be copied or moved. Only valid
// for move or copy operations
// Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details.
@@ -1726,6 +1780,14 @@ type JSONPatchOperation struct {
Value *apiextensionsv1.JSON `json:"value,omitempty" yaml:"value,omitempty"`
}
+func (o *JSONPatchOperation) IsPathNilOrEmpty() bool {
+ return o.Path == nil || *o.Path == EmptyPath
+}
+
+func (o *JSONPatchOperation) IsJSONPathNilOrEmpty() bool {
+ return o.JSONPath == nil || *o.JSONPath == EmptyPath
+}
+
// Tracing defines the configuration for tracing a Envoy xDS Resource
// +k8s:deepcopy-gen=true
type Tracing struct {
@@ -1734,6 +1796,7 @@ type Tracing struct {
SamplingRate float64 `json:"samplingRate,omitempty"`
CustomTags map[string]egv1a1.CustomTag `json:"customTags,omitempty"`
Destination RouteDestination `json:"destination,omitempty"`
+ Traffic *TrafficFeatures `json:"traffic,omitempty"`
Provider egv1a1.TracingProvider `json:"provider"`
}
@@ -1915,6 +1978,8 @@ type ActiveHealthCheck struct {
HTTP *HTTPHealthChecker `json:"http,omitempty" yaml:"http,omitempty"`
// TCP defines the configuration of tcp health checker.
TCP *TCPHealthChecker `json:"tcp,omitempty" yaml:"tcp,omitempty"`
+ // GRPC defines if the GRPC healthcheck service should be used
+ GRPC *GRPCHealthChecker `json:"grpc,omitempty" yaml:"grpc,omitempty"`
}
func (h *HealthCheck) SetHTTPHostIfAbsent(host string) {
@@ -1947,6 +2012,9 @@ func (h *HealthCheck) Validate() error {
if h.Active.TCP != nil {
matchCount++
}
+ if h.Active.GRPC != nil {
+ matchCount++
+ }
if matchCount > 1 {
errs = errors.Join(errs, ErrHealthCheckerInvalid)
}
@@ -2041,6 +2109,15 @@ func (h HTTPStatus) Validate() error {
return nil
}
+// GRPCHealthChecker defines the settings of the gRPC health check.
+// +k8s:deepcopy-gen=true
+type GRPCHealthChecker struct {
+ // Service is the name of a specific service hosted by the server for
+ // which the health check should be requested. If not specified, then the default
+ // is to send a health check request for the entire server.
+ Service *string `json:"service,omitempty" yaml:"service,omitempty"`
+}
+
// TCPHealthChecker defines the settings of tcp health check.
// +k8s:deepcopy-gen=true
type TCPHealthChecker struct {
@@ -2230,6 +2307,9 @@ type ExtProc struct {
// Destination defines the destination for the gRPC External Processing service.
Destination RouteDestination `json:"destination" yaml:"destination"`
+ // Traffic holds the features associated with traffic management
+ Traffic *TrafficFeatures `json:"traffic,omitempty" yaml:"traffic,omitempty"`
+
// Authority is the hostname:port of the HTTP External Processing service.
Authority string `json:"authority" yaml:"authority"`
diff --git a/internal/ir/xds_test.go b/internal/ir/xds_test.go
index 9492c378344..876e37f9e13 100644
--- a/internal/ir/xds_test.go
+++ b/internal/ir/xds_test.go
@@ -338,17 +338,16 @@ var (
AddRequestHeaders: []AddHeader{
{
Name: "example-header",
- Value: "example-value",
+ Value: []string{"example-value"},
Append: true,
},
{
Name: "example-header-2",
- Value: "example-value-2",
+ Value: []string{"example-value-2"},
Append: false,
},
{
Name: "empty-header",
- Value: "",
Append: false,
},
},
@@ -376,12 +375,12 @@ var (
AddRequestHeaders: []AddHeader{
{
Name: "example-header",
- Value: "example-value",
+ Value: []string{"example-value"},
Append: true,
},
{
Name: "example-header",
- Value: "example-value-2",
+ Value: []string{"example-value-2"},
Append: false,
},
},
@@ -401,7 +400,7 @@ var (
AddRequestHeaders: []AddHeader{
{
Name: "",
- Value: "example-value",
+ Value: []string{"example-value"},
Append: true,
},
},
@@ -416,17 +415,16 @@ var (
AddResponseHeaders: []AddHeader{
{
Name: "example-header",
- Value: "example-value",
+ Value: []string{"example-value"},
Append: true,
},
{
Name: "example-header-2",
- Value: "example-value-2",
+ Value: []string{"example-value-2"},
Append: false,
},
{
Name: "empty-header",
- Value: "",
Append: false,
},
},
@@ -454,12 +452,12 @@ var (
AddResponseHeaders: []AddHeader{
{
Name: "example-header",
- Value: "example-value",
+ Value: []string{"example-value"},
Append: true,
},
{
Name: "example-header",
- Value: "example-value-2",
+ Value: []string{"example-value-2"},
Append: false,
},
},
@@ -479,7 +477,7 @@ var (
AddResponseHeaders: []AddHeader{
{
Name: "",
- Value: "example-value",
+ Value: []string{"example-value"},
Append: true,
},
},
@@ -579,7 +577,6 @@ func TestValidateXds(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
if test.want == nil {
require.NoError(t, test.input.Validate())
@@ -634,7 +631,6 @@ func TestValidateHTTPListener(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
if test.want == nil {
require.NoError(t, test.input.Validate())
@@ -686,7 +682,6 @@ func TestValidateTCPListener(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
if test.want == nil {
require.NoError(t, test.input.Validate())
@@ -736,7 +731,6 @@ func TestValidateTLSListenerConfig(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
if test.want == nil {
require.NoError(t, test.input.Validate())
@@ -849,7 +843,6 @@ func TestValidateUDPListener(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
if test.want == nil {
require.NoError(t, test.input.Validate())
@@ -1001,7 +994,6 @@ func TestValidateHTTPRoute(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
if test.want == nil {
require.NoError(t, test.input.Validate())
@@ -1043,7 +1035,6 @@ func TestValidateTCPRoute(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
if test.want == nil {
require.NoError(t, test.input.Validate())
@@ -1169,7 +1160,6 @@ func TestValidateRouteDestination(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
if test.want == nil {
require.NoError(t, test.input.Validate())
@@ -1209,7 +1199,6 @@ func TestValidateStringMatch(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
if test.want == nil {
require.NoError(t, test.input.Validate())
@@ -1347,7 +1336,6 @@ func TestPrintable(t *testing.T) {
},
}
for _, test := range tests {
- test := test
t.Run(test.name, func(t *testing.T) {
assert.Equal(t, *test.want, *test.input.Printable())
})
diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go
index dabb7af5afd..4423f71ba0c 100644
--- a/internal/ir/zz_generated.deepcopy.go
+++ b/internal/ir/zz_generated.deepcopy.go
@@ -25,6 +25,11 @@ func (in *ALSAccessLog) DeepCopyInto(out *ALSAccessLog) {
copy(*out, *in)
}
in.Destination.DeepCopyInto(&out.Destination)
+ if in.Traffic != nil {
+ in, out := &in.Traffic, &out.Traffic
+ *out = new(TrafficFeatures)
+ (*in).DeepCopyInto(*out)
+ }
if in.Text != nil {
in, out := &in.Text, &out.Text
*out = new(string)
@@ -176,6 +181,11 @@ func (in *ActiveHealthCheck) DeepCopyInto(out *ActiveHealthCheck) {
*out = new(TCPHealthChecker)
(*in).DeepCopyInto(*out)
}
+ if in.GRPC != nil {
+ in, out := &in.GRPC, &out.GRPC
+ *out = new(GRPCHealthChecker)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ActiveHealthCheck.
@@ -191,6 +201,11 @@ func (in *ActiveHealthCheck) DeepCopy() *ActiveHealthCheck {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AddHeader) DeepCopyInto(out *AddHeader) {
*out = *in
+ if in.Value != nil {
+ in, out := &in.Value, &out.Value
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddHeader.
@@ -531,6 +546,26 @@ func (in *ConsistentHash) DeepCopy() *ConsistentHash {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *CookieBasedSessionPersistence) DeepCopyInto(out *CookieBasedSessionPersistence) {
+ *out = *in
+ if in.TTL != nil {
+ in, out := &in.TTL, &out.TTL
+ *out = new(v1.Duration)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CookieBasedSessionPersistence.
+func (in *CookieBasedSessionPersistence) DeepCopy() *CookieBasedSessionPersistence {
+ if in == nil {
+ return nil
+ }
+ out := new(CookieBasedSessionPersistence)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CoreListenerDetails) DeepCopyInto(out *CoreListenerDetails) {
*out = *in
@@ -613,7 +648,9 @@ func (in *DestinationFilters) DeepCopyInto(out *DestinationFilters) {
if in.AddRequestHeaders != nil {
in, out := &in.AddRequestHeaders, &out.AddRequestHeaders
*out = make([]AddHeader, len(*in))
- copy(*out, *in)
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
}
if in.RemoveRequestHeaders != nil {
in, out := &in.RemoveRequestHeaders, &out.RemoveRequestHeaders
@@ -623,7 +660,9 @@ func (in *DestinationFilters) DeepCopyInto(out *DestinationFilters) {
if in.AddResponseHeaders != nil {
in, out := &in.AddResponseHeaders, &out.AddResponseHeaders
*out = make([]AddHeader, len(*in))
- copy(*out, *in)
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
}
if in.RemoveResponseHeaders != nil {
in, out := &in.RemoveResponseHeaders, &out.RemoveResponseHeaders
@@ -650,6 +689,11 @@ func (in *DestinationSetting) DeepCopyInto(out *DestinationSetting) {
*out = new(uint32)
**out = **in
}
+ if in.Priority != nil {
+ in, out := &in.Priority, &out.Priority
+ *out = new(uint32)
+ **out = **in
+ }
if in.Endpoints != nil {
in, out := &in.Endpoints, &out.Endpoints
*out = make([]*DestinationEndpoint, len(*in))
@@ -792,6 +836,11 @@ func (in *ExtAuth) DeepCopyInto(out *ExtAuth) {
*out = new(HTTPExtAuthService)
(*in).DeepCopyInto(*out)
}
+ if in.Traffic != nil {
+ in, out := &in.Traffic, &out.Traffic
+ *out = new(TrafficFeatures)
+ (*in).DeepCopyInto(*out)
+ }
if in.HeadersToExtAuth != nil {
in, out := &in.HeadersToExtAuth, &out.HeadersToExtAuth
*out = make([]string, len(*in))
@@ -818,6 +867,11 @@ func (in *ExtAuth) DeepCopy() *ExtAuth {
func (in *ExtProc) DeepCopyInto(out *ExtProc) {
*out = *in
in.Destination.DeepCopyInto(&out.Destination)
+ if in.Traffic != nil {
+ in, out := &in.Traffic, &out.Traffic
+ *out = new(TrafficFeatures)
+ (*in).DeepCopyInto(*out)
+ }
if in.MessageTimeout != nil {
in, out := &in.MessageTimeout, &out.MessageTimeout
*out = new(v1.Duration)
@@ -946,6 +1000,26 @@ func (in *GRPCExtAuthService) DeepCopy() *GRPCExtAuthService {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *GRPCHealthChecker) DeepCopyInto(out *GRPCHealthChecker) {
+ *out = *in
+ if in.Service != nil {
+ in, out := &in.Service, &out.Service
+ *out = new(string)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCHealthChecker.
+func (in *GRPCHealthChecker) DeepCopy() *GRPCHealthChecker {
+ if in == nil {
+ return nil
+ }
+ out := new(GRPCHealthChecker)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GlobalRateLimit) DeepCopyInto(out *GlobalRateLimit) {
*out = *in
@@ -1264,7 +1338,9 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) {
if in.AddRequestHeaders != nil {
in, out := &in.AddRequestHeaders, &out.AddRequestHeaders
*out = make([]AddHeader, len(*in))
- copy(*out, *in)
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
}
if in.RemoveRequestHeaders != nil {
in, out := &in.RemoveRequestHeaders, &out.RemoveRequestHeaders
@@ -1274,7 +1350,9 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) {
if in.AddResponseHeaders != nil {
in, out := &in.AddResponseHeaders, &out.AddResponseHeaders
*out = make([]AddHeader, len(*in))
- copy(*out, *in)
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
}
if in.RemoveResponseHeaders != nil {
in, out := &in.RemoveResponseHeaders, &out.RemoveResponseHeaders
@@ -1348,9 +1426,9 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) {
*out = new(ResourceMetadata)
(*in).DeepCopyInto(*out)
}
- if in.DNS != nil {
- in, out := &in.DNS, &out.DNS
- *out = new(DNS)
+ if in.SessionPersistence != nil {
+ in, out := &in.SessionPersistence, &out.SessionPersistence
+ *out = new(SessionPersistence)
(*in).DeepCopyInto(*out)
}
}
@@ -1410,6 +1488,21 @@ func (in *HTTPWasmCode) DeepCopy() *HTTPWasmCode {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *HeaderBasedSessionPersistence) DeepCopyInto(out *HeaderBasedSessionPersistence) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeaderBasedSessionPersistence.
+func (in *HeaderBasedSessionPersistence) DeepCopy() *HeaderBasedSessionPersistence {
+ if in == nil {
+ return nil
+ }
+ out := new(HeaderBasedSessionPersistence)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HeaderSettings) DeepCopyInto(out *HeaderSettings) {
*out = *in
@@ -1418,6 +1511,18 @@ func (in *HeaderSettings) DeepCopyInto(out *HeaderSettings) {
*out = new(XForwardedClientCert)
(*in).DeepCopyInto(*out)
}
+ if in.EarlyAddRequestHeaders != nil {
+ in, out := &in.EarlyAddRequestHeaders, &out.EarlyAddRequestHeaders
+ *out = make([]AddHeader, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.EarlyRemoveRequestHeaders != nil {
+ in, out := &in.EarlyRemoveRequestHeaders, &out.EarlyRemoveRequestHeaders
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeaderSettings.
@@ -1590,6 +1695,16 @@ func (in *JSONPatchConfig) DeepCopy() *JSONPatchConfig {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *JSONPatchOperation) DeepCopyInto(out *JSONPatchOperation) {
*out = *in
+ if in.Path != nil {
+ in, out := &in.Path, &out.Path
+ *out = new(string)
+ **out = **in
+ }
+ if in.JSONPath != nil {
+ in, out := &in.JSONPath, &out.JSONPath
+ *out = new(string)
+ **out = **in
+ }
if in.From != nil {
in, out := &in.From, &out.From
*out = new(string)
@@ -1825,6 +1940,11 @@ func (in *OpenTelemetryAccessLog) DeepCopyInto(out *OpenTelemetryAccessLog) {
}
}
in.Destination.DeepCopyInto(&out.Destination)
+ if in.Traffic != nil {
+ in, out := &in.Traffic, &out.Traffic
+ *out = new(TrafficFeatures)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenTelemetryAccessLog.
@@ -2334,6 +2454,31 @@ func (in *SecurityFeatures) DeepCopy() *SecurityFeatures {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SessionPersistence) DeepCopyInto(out *SessionPersistence) {
+ *out = *in
+ if in.Cookie != nil {
+ in, out := &in.Cookie, &out.Cookie
+ *out = new(CookieBasedSessionPersistence)
+ (*in).DeepCopyInto(*out)
+ }
+ if in.Header != nil {
+ in, out := &in.Header, &out.Header
+ *out = new(HeaderBasedSessionPersistence)
+ **out = **in
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SessionPersistence.
+func (in *SessionPersistence) DeepCopy() *SessionPersistence {
+ if in == nil {
+ return nil
+ }
+ out := new(SessionPersistence)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SlowStart) DeepCopyInto(out *SlowStart) {
*out = *in
@@ -2832,6 +2977,11 @@ func (in *Tracing) DeepCopyInto(out *Tracing) {
}
}
in.Destination.DeepCopyInto(&out.Destination)
+ if in.Traffic != nil {
+ in, out := &in.Traffic, &out.Traffic
+ *out = new(TrafficFeatures)
+ (*in).DeepCopyInto(*out)
+ }
in.Provider.DeepCopyInto(&out.Provider)
}
@@ -2903,6 +3053,11 @@ func (in *TrafficFeatures) DeepCopyInto(out *TrafficFeatures) {
*out = new(HTTP2Settings)
(*in).DeepCopyInto(*out)
}
+ if in.DNS != nil {
+ in, out := &in.DNS, &out.DNS
+ *out = new(DNS)
+ (*in).DeepCopyInto(*out)
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrafficFeatures.
diff --git a/internal/metrics/otel_label.go b/internal/metrics/otel_label.go
index bcf4c472209..8c4c54c339c 100644
--- a/internal/metrics/otel_label.go
+++ b/internal/metrics/otel_label.go
@@ -58,8 +58,7 @@ func mergeLabelValues(attrs []attribute.KeyValue, labelValues []LabelValue) ([]a
mergedAttrs := make([]attribute.KeyValue, 0, len(attrs)+len(labelValues))
mergedAttrs = append(mergedAttrs, attrs...)
for _, v := range labelValues {
- kv := v
- mergedAttrs = append(mergedAttrs, kv.keyValue)
+ mergedAttrs = append(mergedAttrs, v.keyValue)
}
return mergedAttrs, attribute.NewSet(mergedAttrs...)
diff --git a/internal/metrics/otel_metric_gauge.go b/internal/metrics/otel_metric_gauge.go
index 49e02395b67..7fe0ac3dc5d 100644
--- a/internal/metrics/otel_metric_gauge.go
+++ b/internal/metrics/otel_metric_gauge.go
@@ -29,15 +29,19 @@ type GaugeValues struct {
func (f *Gauge) Record(value float64) {
f.mutex.Lock()
+ defer f.mutex.Unlock()
+
if f.current == nil {
f.current = &GaugeValues{}
f.stores[attribute.NewSet()] = f.current
}
f.current.val = value
- f.mutex.Unlock()
}
func (f *Gauge) With(labelValues ...LabelValue) *Gauge {
+ f.mutex.Lock()
+ defer f.mutex.Unlock()
+
attrs, set := mergeLabelValues(f.attrs, labelValues)
m := &Gauge{
g: f.g,
diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go
index f7e88da222d..8078e767f8a 100644
--- a/internal/provider/kubernetes/controller.go
+++ b/internal/provider/kubernetes/controller.go
@@ -190,7 +190,6 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques
gwcResources := make(gatewayapi.ControllerResources, 0, len(managedGCs))
for _, managedGC := range managedGCs {
// Initialize resource types.
- managedGC := managedGC
gwcResource := gatewayapi.NewResources()
gwcResource.GatewayClass = managedGC
gwcResources = append(gwcResources, gwcResource)
@@ -348,7 +347,6 @@ func (r *gatewayAPIReconciler) managedGatewayClasses(ctx context.Context) ([]*gw
var cc controlledClasses
for _, gwClass := range gatewayClasses.Items {
- gwClass := gwClass
if gwClass.Spec.ControllerName == r.classController {
// The gatewayclass was marked for deletion and the finalizer removed,
// so clean-up dependents.
@@ -435,7 +433,7 @@ func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResour
backendRefKind, string(backendRef.Name))
} else {
for _, endpointSlice := range endpointSliceList.Items {
- endpointSlice := endpointSlice
+ endpointSlice := endpointSlice //nolint:copyloopvar
r.log.Info("added EndpointSlice to resource tree", "namespace", endpointSlice.Namespace,
"name", endpointSlice.Name)
gwcResource.EndpointSlices = append(gwcResource.EndpointSlices, &endpointSlice)
@@ -756,7 +754,6 @@ func (r *gatewayAPIReconciler) findReferenceGrant(ctx context.Context, from, to
if r.namespaceLabel != nil {
var rgs []gwapiv1b1.ReferenceGrant
for _, refGrant := range refGrants {
- refGrant := refGrant
if ok, err := r.checkObjectNamespaceLabels(&refGrant); err != nil {
r.log.Error(err, "failed to check namespace labels for ReferenceGrant %s in namespace %s: %w", refGrant.GetName(), refGrant.GetNamespace())
continue
@@ -769,13 +766,35 @@ func (r *gatewayAPIReconciler) findReferenceGrant(ctx context.Context, from, to
}
for _, refGrant := range refGrants {
- if refGrant.Namespace == to.namespace {
- for _, src := range refGrant.Spec.From {
- if src.Kind == gwapiv1a2.Kind(from.kind) && string(src.Namespace) == from.namespace {
- return &refGrant, nil
- }
+ if refGrant.Namespace != to.namespace {
+ continue
+ }
+
+ var fromAllowed bool
+ for _, refGrantFrom := range refGrant.Spec.From {
+ if string(refGrantFrom.Kind) == from.kind && string(refGrantFrom.Namespace) == from.namespace {
+ fromAllowed = true
+ break
+ }
+ }
+
+ if !fromAllowed {
+ continue
+ }
+
+ var toAllowed bool
+ for _, refGrantTo := range refGrant.Spec.To {
+ if string(refGrantTo.Kind) == to.kind && (refGrantTo.Name == nil || *refGrantTo.Name == "" || string(*refGrantTo.Name) == to.name) {
+ toAllowed = true
+ break
}
}
+
+ if !toAllowed {
+ continue
+ }
+
+ return &refGrant, nil
}
// No ReferenceGrant found.
@@ -794,7 +813,7 @@ func (r *gatewayAPIReconciler) processGateways(ctx context.Context, managedGC *g
}
for _, gtw := range gatewayList.Items {
- gtw := gtw
+ gtw := gtw //nolint:copyloopvar
if r.namespaceLabel != nil {
if ok, err := r.checkObjectNamespaceLabels(>w); err != nil {
r.log.Error(err, "failed to check namespace labels for gateway %s in namespace %s: %w", gtw.GetName(), gtw.GetNamespace())
@@ -811,11 +830,9 @@ func (r *gatewayAPIReconciler) processGateways(ctx context.Context, managedGC *g
}
for _, listener := range gtw.Spec.Listeners {
- listener := listener
// Get Secret for gateway if it exists.
if terminatesTLS(&listener) {
for _, certRef := range listener.TLS.CertificateRefs {
- certRef := certRef
if refsSecret(&certRef) {
if err := r.processSecretRef(
ctx,
@@ -877,7 +894,7 @@ func (r *gatewayAPIReconciler) processEnvoyPatchPolicies(ctx context.Context, re
}
for _, policy := range envoyPatchPolicies.Items {
- policy := policy
+ policy := policy //nolint:copyloopvar
// Discard Status to reduce memory consumption in watchable
// It will be recomputed by the gateway-api layer
policy.Status = gwapiv1a2.PolicyStatus{}
@@ -897,7 +914,7 @@ func (r *gatewayAPIReconciler) processClientTrafficPolicies(
}
for _, policy := range clientTrafficPolicies.Items {
- policy := policy
+ policy := policy //nolint:copyloopvar
// Discard Status to reduce memory consumption in watchable
// It will be recomputed by the gateway-api layer
policy.Status = gwapiv1a2.PolicyStatus{}
@@ -917,7 +934,7 @@ func (r *gatewayAPIReconciler) processBackendTrafficPolicies(ctx context.Context
}
for _, policy := range backendTrafficPolicies.Items {
- policy := policy
+ policy := policy //nolint:copyloopvar
// Discard Status to reduce memory consumption in watchable
// It will be recomputed by the gateway-api layer
policy.Status = gwapiv1a2.PolicyStatus{}
@@ -936,7 +953,7 @@ func (r *gatewayAPIReconciler) processSecurityPolicies(
}
for _, policy := range securityPolicies.Items {
- policy := policy
+ policy := policy //nolint:copyloopvar
// Discard Status to reduce memory consumption in watchable
// It will be recomputed by the gateway-api layer
policy.Status = gwapiv1a2.PolicyStatus{}
@@ -961,7 +978,7 @@ func (r *gatewayAPIReconciler) processBackendTLSPolicies(
}
for _, policy := range backendTLSPolicies.Items {
- policy := policy
+ policy := policy //nolint:copyloopvar
// Discard Status to reduce memory consumption in watchable
// It will be recomputed by the gateway-api layer
policy.Status = gwapiv1a2.PolicyStatus{}
@@ -981,7 +998,7 @@ func (r *gatewayAPIReconciler) processBackends(ctx context.Context, resourceTree
}
for _, backend := range backends.Items {
- backend := backend
+ backend := backend //nolint:copyloopvar
// Discard Status to reduce memory consumption in watchable
// It will be recomputed by the gateway-api layer
backend.Status = egv1a1.BackendStatus{}
@@ -1767,7 +1784,7 @@ func (r *gatewayAPIReconciler) processEnvoyExtensionPolicies(
}
for _, policy := range envoyExtensionPolicies.Items {
- policy := policy
+ policy := policy //nolint:copyloopvar
// Discard Status to reduce memory consumption in watchable
// It will be recomputed by the gateway-api layer
policy.Status = gwapiv1a2.PolicyStatus{}
@@ -1794,8 +1811,6 @@ func (r *gatewayAPIReconciler) processExtensionServerPolicies(
}
for _, policy := range polList.Items {
- policy := policy
-
policySpec, found := policy.Object["spec"].(map[string]any)
if !found {
return fmt.Errorf("no spec found in %s.%s %s", policy.GetAPIVersion(), policy.GetKind(), policy.GetName())
diff --git a/internal/provider/kubernetes/controller_test.go b/internal/provider/kubernetes/controller_test.go
index e3b63360163..b2fb1c3d791 100644
--- a/internal/provider/kubernetes/controller_test.go
+++ b/internal/provider/kubernetes/controller_test.go
@@ -73,7 +73,6 @@ func TestAddGatewayClassFinalizer(t *testing.T) {
ctx := context.Background()
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
r.client = fakeclient.NewClientBuilder().WithScheme(envoygateway.GetScheme()).WithObjects(tc.gc).Build()
err := r.addFinalizer(ctx, tc.gc)
@@ -137,7 +136,6 @@ func TestRemoveGatewayClassFinalizer(t *testing.T) {
ctx := context.Background()
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
r.client = fakeclient.NewClientBuilder().WithScheme(envoygateway.GetScheme()).WithObjects(tc.gc).Build()
err := r.removeFinalizer(ctx, tc.gc)
diff --git a/internal/provider/kubernetes/filters.go b/internal/provider/kubernetes/filters.go
index 8ef8dc1ede1..985990fef14 100644
--- a/internal/provider/kubernetes/filters.go
+++ b/internal/provider/kubernetes/filters.go
@@ -26,7 +26,6 @@ func (r *gatewayAPIReconciler) getExtensionRefFilters(ctx context.Context) ([]un
if r.namespaceLabel != nil {
var extRs []unstructured.Unstructured
for _, extR := range uExtResources {
- extR := extR
ok, err := r.checkObjectNamespaceLabels(&extR)
if err != nil {
r.log.Error(err, "failed to check namespace labels for ExtensionRefFilter %s in namespace %s: %w", extR.GetName(), extR.GetNamespace())
diff --git a/internal/provider/kubernetes/helpers_test.go b/internal/provider/kubernetes/helpers_test.go
index 0d5deb0d5d3..38a634f9c7b 100644
--- a/internal/provider/kubernetes/helpers_test.go
+++ b/internal/provider/kubernetes/helpers_test.go
@@ -103,7 +103,6 @@ func TestGatewaysOfClass(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
gwList := &gwapiv1.GatewayList{Items: tc.gws}
actual := gatewaysOfClass(gc, gwList)
@@ -185,7 +184,6 @@ func TestIsGatewayClassAccepted(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
actual := isAccepted(tc.gc)
require.Equal(t, tc.expect, actual)
diff --git a/internal/provider/kubernetes/predicates.go b/internal/provider/kubernetes/predicates.go
index e64c08619db..e606138fa09 100644
--- a/internal/provider/kubernetes/predicates.go
+++ b/internal/provider/kubernetes/predicates.go
@@ -208,7 +208,6 @@ func (r *gatewayAPIReconciler) isGatewayReferencingSecret(nsName *types.Namespac
}
for _, gw := range gwList.Items {
- gw := gw
if !r.validateGatewayForReconcile(&gw) {
return false
}
@@ -549,7 +548,6 @@ func (r *gatewayAPIReconciler) updateStatusForGatewaysUnderGatewayClass(ctx cont
}
for _, gateway := range gateways.Items {
- gateway := gateway
r.updateStatusForGateway(ctx, &gateway)
}
diff --git a/internal/provider/kubernetes/predicates_test.go b/internal/provider/kubernetes/predicates_test.go
index 6379263bdb0..054de1e5395 100644
--- a/internal/provider/kubernetes/predicates_test.go
+++ b/internal/provider/kubernetes/predicates_test.go
@@ -59,7 +59,6 @@ func TestGatewayClassHasMatchingController(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
res := r.hasMatchingController(tc.gc)
require.Equal(t, tc.expect, res)
@@ -107,8 +106,6 @@ func TestGatewayClassHasMatchingNamespaceLabels(t *testing.T) {
logger := logging.DefaultLogger(egv1a1.LogLevelInfo)
for _, tc := range testCases {
- tc := tc
-
r := gatewayAPIReconciler{
classController: egv1a1.GatewayControllerName,
namespaceLabel: &metav1.LabelSelector{MatchExpressions: matchExpressions(tc.namespaceLabels, metav1.LabelSelectorOpExists, []string{})},
@@ -172,7 +169,6 @@ func TestValidateGatewayForReconcile(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
r.client = fakeclient.NewClientBuilder().WithScheme(envoygateway.GetScheme()).WithObjects(tc.configs...).Build()
t.Run(tc.name, func(t *testing.T) {
res := r.validateGatewayForReconcile(tc.gateway)
@@ -368,7 +364,6 @@ func TestValidateSecretForReconcile(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
r.client = fakeclient.NewClientBuilder().
WithScheme(envoygateway.GetScheme()).
WithObjects(tc.configs...).
@@ -435,7 +430,6 @@ func TestValidateEndpointSliceForReconcile(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
r.client = fakeclient.NewClientBuilder().
WithScheme(envoygateway.GetScheme()).
WithObjects(tc.configs...).
@@ -471,12 +465,14 @@ func TestValidateServiceForReconcile(t *testing.T) {
{
Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry,
OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{
- BackendRefs: []egv1a1.BackendRef{
- {
- BackendObjectReference: gwapiv1.BackendObjectReference{
- Name: "otel-collector",
- Namespace: ptr.To(gwapiv1.Namespace("default")),
- Port: ptr.To(gwapiv1.PortNumber(4317)),
+ BackendCluster: egv1a1.BackendCluster{
+ BackendRefs: []egv1a1.BackendRef{
+ {
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Name: "otel-collector",
+ Namespace: ptr.To(gwapiv1.Namespace("default")),
+ Port: ptr.To(gwapiv1.PortNumber(4317)),
+ },
},
},
},
@@ -491,12 +487,14 @@ func TestValidateServiceForReconcile(t *testing.T) {
{
Type: egv1a1.MetricSinkTypeOpenTelemetry,
OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{
- BackendRefs: []egv1a1.BackendRef{
- {
- BackendObjectReference: gwapiv1.BackendObjectReference{
- Name: "otel-collector",
- Namespace: ptr.To(gwapiv1.Namespace("default")),
- Port: ptr.To(gwapiv1.PortNumber(4317)),
+ BackendCluster: egv1a1.BackendCluster{
+ BackendRefs: []egv1a1.BackendRef{
+ {
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Name: "otel-collector",
+ Namespace: ptr.To(gwapiv1.Namespace("default")),
+ Port: ptr.To(gwapiv1.PortNumber(4317)),
+ },
},
},
},
@@ -507,12 +505,14 @@ func TestValidateServiceForReconcile(t *testing.T) {
Tracing: &egv1a1.ProxyTracing{
Provider: egv1a1.TracingProvider{
Type: egv1a1.TracingProviderTypeOpenTelemetry,
- BackendRefs: []egv1a1.BackendRef{
- {
- BackendObjectReference: gwapiv1.BackendObjectReference{
- Name: "otel-collector",
- Namespace: ptr.To(gwapiv1.Namespace("default")),
- Port: ptr.To(gwapiv1.PortNumber(4317)),
+ BackendCluster: egv1a1.BackendCluster{
+ BackendRefs: []egv1a1.BackendRef{
+ {
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Name: "otel-collector",
+ Namespace: ptr.To(gwapiv1.Namespace("default")),
+ Port: ptr.To(gwapiv1.PortNumber(4317)),
+ },
},
},
},
@@ -675,10 +675,12 @@ func TestValidateServiceForReconcile(t *testing.T) {
},
ExtAuth: &egv1a1.ExtAuth{
HTTP: &egv1a1.HTTPExtAuthService{
- BackendRefs: []egv1a1.BackendRef{
- {
- BackendObjectReference: gwapiv1.BackendObjectReference{
- Name: "ext-auth-http-service",
+ BackendCluster: egv1a1.BackendCluster{
+ BackendRefs: []egv1a1.BackendRef{
+ {
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Name: "ext-auth-http-service",
+ },
},
},
},
@@ -708,10 +710,12 @@ func TestValidateServiceForReconcile(t *testing.T) {
},
ExtAuth: &egv1a1.ExtAuth{
GRPC: &egv1a1.GRPCExtAuthService{
- BackendRefs: []egv1a1.BackendRef{
- {
- BackendObjectReference: gwapiv1.BackendObjectReference{
- Name: "ext-auth-grpc-service",
+ BackendCluster: egv1a1.BackendCluster{
+ BackendRefs: []egv1a1.BackendRef{
+ {
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Name: "ext-auth-grpc-service",
+ },
},
},
},
@@ -741,10 +745,12 @@ func TestValidateServiceForReconcile(t *testing.T) {
},
ExtProc: []egv1a1.ExtProc{
{
- BackendRefs: []egv1a1.BackendRef{
- {
- BackendObjectReference: gwapiv1.BackendObjectReference{
- Name: "ext-proc-service",
+ BackendCluster: egv1a1.BackendCluster{
+ BackendRefs: []egv1a1.BackendRef{
+ {
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Name: "ext-proc-service",
+ },
},
},
},
@@ -774,10 +780,12 @@ func TestValidateServiceForReconcile(t *testing.T) {
},
ExtProc: []egv1a1.ExtProc{
{
- BackendRefs: []egv1a1.BackendRef{
- {
- BackendObjectReference: gwapiv1.BackendObjectReference{
- Name: "ext-proc-service",
+ BackendCluster: egv1a1.BackendCluster{
+ BackendRefs: []egv1a1.BackendRef{
+ {
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Name: "ext-proc-service",
+ },
},
},
},
@@ -836,7 +844,6 @@ func TestValidateServiceForReconcile(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
r.client = fakeclient.NewClientBuilder().
WithScheme(envoygateway.GetScheme()).
WithObjects(tc.configs...).
@@ -933,7 +940,6 @@ func TestValidateDeploymentForReconcile(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
r.client = fakeclient.NewClientBuilder().WithScheme(envoygateway.GetScheme()).WithObjects(tc.configs...).Build()
t.Run(tc.name, func(t *testing.T) {
res := r.validateDeploymentForReconcile(tc.deployment)
@@ -1039,7 +1045,6 @@ func TestCheckObjectNamespaceLabels(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
r.client = fakeclient.NewClientBuilder().WithObjects(tc.ns).Build()
r.namespaceLabel = &metav1.LabelSelector{MatchExpressions: matchExpressions(tc.reconcileLabels, metav1.LabelSelectorOpExists, []string{})}
ok, err := r.checkObjectNamespaceLabels(tc.object)
diff --git a/internal/provider/kubernetes/routes.go b/internal/provider/kubernetes/routes.go
index ad2638684cd..c52e39ef349 100644
--- a/internal/provider/kubernetes/routes.go
+++ b/internal/provider/kubernetes/routes.go
@@ -34,7 +34,7 @@ func (r *gatewayAPIReconciler) processTLSRoutes(ctx context.Context, gatewayName
}
for _, tlsRoute := range tlsRouteList.Items {
- tlsRoute := tlsRoute
+ tlsRoute := tlsRoute //nolint:copyloopvar
if r.namespaceLabel != nil {
if ok, err := r.checkObjectNamespaceLabels(&tlsRoute); err != nil {
r.log.Error(err, "failed to check namespace labels for TLSRoute %s in namespace %s: %w", tlsRoute.GetName(), tlsRoute.GetNamespace())
@@ -54,7 +54,6 @@ func (r *gatewayAPIReconciler) processTLSRoutes(ctx context.Context, gatewayName
for _, rule := range tlsRoute.Spec.Rules {
for _, backendRef := range rule.BackendRefs {
- backendRef := backendRef
ref := gatewayapi.UpgradeBackendRef(backendRef)
if err := validateBackendRef(&ref); err != nil {
r.log.Error(err, "invalid backendRef")
@@ -114,7 +113,7 @@ func (r *gatewayAPIReconciler) processGRPCRoutes(ctx context.Context, gatewayNam
}
for _, grpcRoute := range grpcRouteList.Items {
- grpcRoute := grpcRoute
+ grpcRoute := grpcRoute //nolint:copyloopvar
if r.namespaceLabel != nil {
if ok, err := r.checkObjectNamespaceLabels(&grpcRoute); err != nil {
r.log.Error(err, "failed to check namespace labels for GRPCRoute %s in namespace %s: %w", grpcRoute.GetName(), grpcRoute.GetNamespace())
@@ -134,7 +133,6 @@ func (r *gatewayAPIReconciler) processGRPCRoutes(ctx context.Context, gatewayNam
for _, rule := range grpcRoute.Spec.Rules {
for _, backendRef := range rule.BackendRefs {
- backendRef := backendRef
if err := validateBackendRef(&backendRef.BackendRef); err != nil {
r.log.Error(err, "invalid backendRef")
continue
@@ -249,7 +247,7 @@ func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNam
}
for _, httpRoute := range httpRouteList.Items {
- httpRoute := httpRoute
+ httpRoute := httpRoute //nolint:copyloopvar
if r.namespaceLabel != nil {
if ok, err := r.checkObjectNamespaceLabels(&httpRoute); err != nil {
r.log.Error(err, "failed to check namespace labels for HTTPRoute %s in namespace %s: %w", httpRoute.GetName(), httpRoute.GetNamespace())
@@ -269,7 +267,6 @@ func (r *gatewayAPIReconciler) processHTTPRoutes(ctx context.Context, gatewayNam
for _, rule := range httpRoute.Spec.Rules {
for _, backendRef := range rule.BackendRefs {
- backendRef := backendRef
if err := validateBackendRef(&backendRef.BackendRef); err != nil {
r.log.Error(err, "invalid backendRef")
continue
@@ -427,7 +424,7 @@ func (r *gatewayAPIReconciler) processTCPRoutes(ctx context.Context, gatewayName
}
for _, tcpRoute := range tcpRouteList.Items {
- tcpRoute := tcpRoute
+ tcpRoute := tcpRoute //nolint:copyloopvar
if r.namespaceLabel != nil {
if ok, err := r.checkObjectNamespaceLabels(&tcpRoute); err != nil {
r.log.Error(err, "failed to check namespace labels for TCPRoute %s in namespace %s: %w", tcpRoute.GetName(), tcpRoute.GetNamespace())
@@ -447,7 +444,6 @@ func (r *gatewayAPIReconciler) processTCPRoutes(ctx context.Context, gatewayName
for _, rule := range tcpRoute.Spec.Rules {
for _, backendRef := range rule.BackendRefs {
- backendRef := backendRef
ref := gatewayapi.UpgradeBackendRef(backendRef)
if err := validateBackendRef(&ref); err != nil {
r.log.Error(err, "invalid backendRef")
@@ -506,7 +502,7 @@ func (r *gatewayAPIReconciler) processUDPRoutes(ctx context.Context, gatewayName
}
for _, udpRoute := range udpRouteList.Items {
- udpRoute := udpRoute
+ udpRoute := udpRoute //nolint:copyloopvar
if r.namespaceLabel != nil {
if ok, err := r.checkObjectNamespaceLabels(&udpRoute); err != nil {
r.log.Error(err, "failed to check namespace labels for UDPRoute %s in namespace %s: %w", udpRoute.GetName(), udpRoute.GetNamespace())
@@ -526,7 +522,6 @@ func (r *gatewayAPIReconciler) processUDPRoutes(ctx context.Context, gatewayName
for _, rule := range udpRoute.Spec.Rules {
for _, backendRef := range rule.BackendRefs {
- backendRef := backendRef
ref := gatewayapi.UpgradeBackendRef(backendRef)
if err := validateBackendRef(&ref); err != nil {
r.log.Error(err, "invalid backendRef")
diff --git a/internal/provider/kubernetes/routes_test.go b/internal/provider/kubernetes/routes_test.go
index be6769589a1..9bd4126d325 100644
--- a/internal/provider/kubernetes/routes_test.go
+++ b/internal/provider/kubernetes/routes_test.go
@@ -851,7 +851,6 @@ func TestValidateHTTPRouteParentRefs(t *testing.T) {
ctx := context.Background()
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
var objs []client.Object
for i := range tc.classes {
diff --git a/internal/provider/runner/runner_test.go b/internal/provider/runner/runner_test.go
index a393462da94..8252bb407ca 100644
--- a/internal/provider/runner/runner_test.go
+++ b/internal/provider/runner/runner_test.go
@@ -47,7 +47,6 @@ func TestStart(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
runner := &Runner{
Config: Config{
diff --git a/internal/utils/misc_test.go b/internal/utils/misc_test.go
index 5955f28aecd..f1b10bcec63 100644
--- a/internal/utils/misc_test.go
+++ b/internal/utils/misc_test.go
@@ -24,7 +24,6 @@ func TestGetHashedName(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
result := GetHashedName(tc.nsName, tc.length)
require.Equal(t, tc.expected, result, "Result does not match expected string")
diff --git a/internal/wasm/cache.go b/internal/wasm/cache.go
index 6082a078855..785d8d3701a 100644
--- a/internal/wasm/cache.go
+++ b/internal/wasm/cache.go
@@ -247,7 +247,7 @@ func (c *localFileCache) getOrFetch(key cacheKey, opts GetOptions) (*cacheEntry,
sha := sha256.Sum256(b)
dChecksum = hex.EncodeToString(sha[:])
case "oci":
- if opts.PullSecret != nil && len(opts.PullSecret) > 0 {
+ if len(opts.PullSecret) > 0 {
isPrivate = true
}
if imageBinaryFetcher, dChecksum, err = c.prepareFetch(ctx, u, insecure, opts); err != nil {
@@ -303,7 +303,7 @@ func (c *localFileCache) prepareFetch(
imgFetcherOps := ImageFetcherOption{
Insecure: insecure,
}
- if opts.PullSecret != nil && len(opts.PullSecret) > 0 {
+ if len(opts.PullSecret) > 0 {
imgFetcherOps.PullSecret = opts.PullSecret
}
fetcher := NewImageFetcher(ctx, imgFetcherOps, c.logger)
diff --git a/internal/wasm/imagefetcher.go b/internal/wasm/imagefetcher.go
index 5c97ad5f4a4..1b8c40fcd25 100644
--- a/internal/wasm/imagefetcher.go
+++ b/internal/wasm/imagefetcher.go
@@ -54,7 +54,7 @@ type ImageFetcherOption struct {
}
func (o *ImageFetcherOption) useAnonymous() bool {
- return o.PullSecret == nil || len(o.PullSecret) == 0
+ return len(o.PullSecret) == 0
}
func (o *ImageFetcherOption) String() string {
diff --git a/internal/xds/bootstrap/bootstrap_test.go b/internal/xds/bootstrap/bootstrap_test.go
index 19e020c499e..2023a7096bd 100644
--- a/internal/xds/bootstrap/bootstrap_test.go
+++ b/internal/xds/bootstrap/bootstrap_test.go
@@ -86,12 +86,14 @@ func TestGetRenderedBootstrapConfig(t *testing.T) {
OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{
Host: ptr.To("otel-collector.monitoring.svc"),
Port: 4317,
- BackendRefs: []egv1a1.BackendRef{
- {
- BackendObjectReference: gwapiv1.BackendObjectReference{
- Name: "otel-collector",
- Namespace: ptr.To(gwapiv1.Namespace("monitoring")),
- Port: ptr.To(gwapiv1.PortNumber(4317)),
+ BackendCluster: egv1a1.BackendCluster{
+ BackendRefs: []egv1a1.BackendRef{
+ {
+ BackendObjectReference: gwapiv1.BackendObjectReference{
+ Name: "otel-collector",
+ Namespace: ptr.To(gwapiv1.Namespace("monitoring")),
+ Port: ptr.To(gwapiv1.PortNumber(4317)),
+ },
},
},
},
diff --git a/internal/xds/server/runner/runner_test.go b/internal/xds/server/runner/runner_test.go
index 45f59da0edc..74bf30f2caf 100644
--- a/internal/xds/server/runner/runner_test.go
+++ b/internal/xds/server/runner/runner_test.go
@@ -131,7 +131,6 @@ func TestTLSConfig(t *testing.T) {
defer g.GracefulStop()
for name, tc := range tests {
- tc := tc
t.Run(name, func(t *testing.T) {
// Store certificate and key to temp dir used by serveContext.
err = tc.serverCredentials.WritePEM(certFile, keyFile)
diff --git a/internal/xds/translator/accesslog.go b/internal/xds/translator/accesslog.go
index 01c448b65e9..8acb6e4b005 100644
--- a/internal/xds/translator/accesslog.go
+++ b/internal/xds/translator/accesslog.go
@@ -478,14 +478,27 @@ func processClusterForAccessLog(tCtx *types.ResourceVersionTable, al *ir.AccessL
if al == nil {
return nil
}
-
// add clusters for ALS access logs
for _, als := range al.ALS {
+ traffic := als.Traffic
+ // Make sure that there are safe defaults for the traffic
+ if traffic == nil {
+ traffic = &ir.TrafficFeatures{}
+ }
if err := addXdsCluster(tCtx, &xdsClusterArgs{
- name: als.Destination.Name,
- settings: als.Destination.Settings,
- tSocket: nil,
- endpointType: EndpointTypeStatic,
+ name: als.Destination.Name,
+ settings: als.Destination.Settings,
+ tSocket: nil,
+ endpointType: EndpointTypeStatic,
+ loadBalancer: traffic.LoadBalancer,
+ proxyProtocol: traffic.ProxyProtocol,
+ circuitBreaker: traffic.CircuitBreaker,
+ healthCheck: traffic.HealthCheck,
+ timeout: traffic.Timeout,
+ tcpkeepalive: traffic.TCPKeepalive,
+ backendConnection: traffic.BackendConnection,
+ dns: traffic.DNS,
+ http2Settings: traffic.HTTP2,
}); err != nil && !errors.Is(err, ErrXdsClusterExists) {
return err
}
@@ -493,12 +506,27 @@ func processClusterForAccessLog(tCtx *types.ResourceVersionTable, al *ir.AccessL
// add clusters for Open Telemetry access logs
for _, otel := range al.OpenTelemetry {
+ traffic := otel.Traffic
+ // Make sure that there are safe defaults for the traffic
+ if traffic == nil {
+ traffic = &ir.TrafficFeatures{}
+ }
+
if err := addXdsCluster(tCtx, &xdsClusterArgs{
- name: otel.Destination.Name,
- settings: otel.Destination.Settings,
- tSocket: nil,
- endpointType: EndpointTypeDNS,
- metrics: metrics,
+ name: otel.Destination.Name,
+ settings: otel.Destination.Settings,
+ tSocket: nil,
+ endpointType: EndpointTypeDNS,
+ metrics: metrics,
+ loadBalancer: traffic.LoadBalancer,
+ proxyProtocol: traffic.ProxyProtocol,
+ circuitBreaker: traffic.CircuitBreaker,
+ healthCheck: traffic.HealthCheck,
+ timeout: traffic.Timeout,
+ tcpkeepalive: traffic.TCPKeepalive,
+ backendConnection: traffic.BackendConnection,
+ dns: traffic.DNS,
+ http2Settings: traffic.HTTP2,
}); err != nil && !errors.Is(err, ErrXdsClusterExists) {
return err
}
diff --git a/internal/xds/translator/cluster.go b/internal/xds/translator/cluster.go
index 697736dbc4d..9786ed972c6 100644
--- a/internal/xds/translator/cluster.go
+++ b/internal/xds/translator/cluster.go
@@ -235,7 +235,8 @@ func buildXdsHealthCheck(healthcheck *ir.ActiveHealthCheck) []*corev3.HealthChec
if healthcheck.HealthyThreshold != nil {
hc.HealthyThreshold = wrapperspb.UInt32(*healthcheck.HealthyThreshold)
}
- if healthcheck.HTTP != nil {
+ switch {
+ case healthcheck.HTTP != nil:
httpChecker := &corev3.HealthCheck_HttpHealthCheck{
Host: healthcheck.HTTP.Host,
Path: healthcheck.HTTP.Path,
@@ -250,8 +251,7 @@ func buildXdsHealthCheck(healthcheck *ir.ActiveHealthCheck) []*corev3.HealthChec
hc.HealthChecker = &corev3.HealthCheck_HttpHealthCheck_{
HttpHealthCheck: httpChecker,
}
- }
- if healthcheck.TCP != nil {
+ case healthcheck.TCP != nil:
tcpChecker := &corev3.HealthCheck_TcpHealthCheck{
Send: buildHealthCheckPayload(healthcheck.TCP.Send),
}
@@ -261,6 +261,12 @@ func buildXdsHealthCheck(healthcheck *ir.ActiveHealthCheck) []*corev3.HealthChec
hc.HealthChecker = &corev3.HealthCheck_TcpHealthCheck_{
TcpHealthCheck: tcpChecker,
}
+ case healthcheck.GRPC != nil:
+ hc.HealthChecker = &corev3.HealthCheck_GrpcHealthCheck_{
+ GrpcHealthCheck: &corev3.HealthCheck_GrpcHealthCheck{
+ ServiceName: ptr.Deref(healthcheck.GRPC.Service, ""),
+ },
+ }
}
return []*corev3.HealthCheck{hc}
}
@@ -438,7 +444,7 @@ func buildXdsClusterLoadAssignment(clusterName string, destSettings []*ir.Destin
weight = 1
}
locality.LoadBalancingWeight = &wrapperspb.UInt32Value{Value: weight}
-
+ locality.Priority = ptr.Deref(ds.Priority, 0)
localities = append(localities, locality)
}
return &endpointv3.ClusterLoadAssignment{ClusterName: clusterName, Endpoints: localities}
@@ -739,10 +745,7 @@ func (httpRoute *HTTPRouteTranslator) asClusterArgs(extra *ExtraArgs) *xdsCluste
clusterArgs.timeout = bt.Timeout
clusterArgs.tcpkeepalive = bt.TCPKeepalive
clusterArgs.backendConnection = bt.BackendConnection
- }
-
- if httpRoute.DNS != nil {
- clusterArgs.dns = httpRoute.DNS
+ clusterArgs.dns = bt.DNS
}
return clusterArgs
diff --git a/internal/xds/translator/extauth.go b/internal/xds/translator/extauth.go
index 35ca41e79f6..3b64326c4c3 100644
--- a/internal/xds/translator/extauth.go
+++ b/internal/xds/translator/extauth.go
@@ -222,13 +222,13 @@ func (*extAuth) patchResources(tCtx *types.ResourceVersionTable,
}
if route.Security.ExtAuth.HTTP != nil {
if err := createExtServiceXDSCluster(
- &route.Security.ExtAuth.HTTP.Destination, tCtx); err != nil && !errors.Is(
+ &route.Security.ExtAuth.HTTP.Destination, route.Security.ExtAuth.Traffic, tCtx); err != nil && !errors.Is(
err, ErrXdsClusterExists) {
errs = errors.Join(errs, err)
}
} else {
if err := createExtServiceXDSCluster(
- &route.Security.ExtAuth.GRPC.Destination, tCtx); err != nil && !errors.Is(
+ &route.Security.ExtAuth.GRPC.Destination, route.Security.ExtAuth.Traffic, tCtx); err != nil && !errors.Is(
err, ErrXdsClusterExists) {
errs = errors.Join(errs, err)
}
diff --git a/internal/xds/translator/extproc.go b/internal/xds/translator/extproc.go
index 6f4db53a08b..2bc6c4b6ba6 100644
--- a/internal/xds/translator/extproc.go
+++ b/internal/xds/translator/extproc.go
@@ -173,12 +173,11 @@ func (*extProc) patchResources(tCtx *types.ResourceVersionTable,
for i := range route.EnvoyExtensions.ExtProcs {
ep := route.EnvoyExtensions.ExtProcs[i]
if err := createExtServiceXDSCluster(
- &ep.Destination, tCtx); err != nil && !errors.Is(
+ &ep.Destination, ep.Traffic, tCtx); err != nil && !errors.Is(
err, ErrXdsClusterExists) {
errs = errors.Join(errs, err)
}
}
-
}
return errs
diff --git a/internal/xds/translator/httpfilters.go b/internal/xds/translator/httpfilters.go
index ad5789fb6ff..1b994fba669 100644
--- a/internal/xds/translator/httpfilters.go
+++ b/internal/xds/translator/httpfilters.go
@@ -114,8 +114,10 @@ func newOrderedHTTPFilter(filter *hcmv3.HttpFilter) *OrderedHTTPFilter {
order = 5
case isFilterType(filter, egv1a1.EnvoyFilterJWTAuthn):
order = 6
+ case isFilterType(filter, egv1a1.EnvoyFilterSessionPersistence):
+ order = 7
case isFilterType(filter, egv1a1.EnvoyFilterExtProc):
- order = 7 + mustGetFilterIndex(filter.Name)
+ order = 8 + mustGetFilterIndex(filter.Name)
case isFilterType(filter, egv1a1.EnvoyFilterWasm):
order = 100 + mustGetFilterIndex(filter.Name)
case isFilterType(filter, egv1a1.EnvoyFilterRBAC):
diff --git a/internal/xds/translator/jsonpatch.go b/internal/xds/translator/jsonpatch.go
index e7808abe0c5..bb8ed8bef2b 100644
--- a/internal/xds/translator/jsonpatch.go
+++ b/internal/xds/translator/jsonpatch.go
@@ -84,9 +84,9 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
}
}
- // If Path is "" and op is "add", unmarshal and add the patch as a complete
+ // If Path and JSONPath is "" and op is "add", unmarshal and add the patch as a complete
// resource
- if p.Operation.Op == AddOperation && p.Operation.Path == EmptyPath {
+ if p.Operation.Op == AddOperation && p.Operation.IsPathNilOrEmpty() && p.Operation.IsJSONPathNilOrEmpty() {
// Convert patch to JSON
// The patch library expects an array so convert it into one
y, err := yaml.Marshal(p.Operation.Value)
@@ -106,7 +106,7 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
case resourcev3.ListenerType:
temp := &listenerv3.Listener{}
if err = protojson.Unmarshal(jsonBytes, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, p.Operation.Value))
+ tErr := errors.New(unmarshalErrorMessage(err, p.Operation.Value))
tErrs = errors.Join(tErrs, tErr)
continue
}
@@ -119,7 +119,7 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
case resourcev3.RouteType:
temp := &routev3.RouteConfiguration{}
if err = protojson.Unmarshal(jsonBytes, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, p.Operation.Value))
+ tErr := errors.New(unmarshalErrorMessage(err, p.Operation.Value))
tErrs = errors.Join(tErrs, tErr)
continue
}
@@ -132,7 +132,7 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
case resourcev3.ClusterType:
temp := &clusterv3.Cluster{}
if err = protojson.Unmarshal(jsonBytes, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, p.Operation.Value))
+ tErr := errors.New(unmarshalErrorMessage(err, p.Operation.Value))
tErrs = errors.Join(tErrs, tErr)
continue
}
@@ -145,7 +145,7 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
case resourcev3.EndpointType:
temp := &endpointv3.ClusterLoadAssignment{}
if err = protojson.Unmarshal(jsonBytes, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, p.Operation.Value))
+ tErr := errors.New(unmarshalErrorMessage(err, p.Operation.Value))
tErrs = errors.Join(tErrs, tErr)
continue
}
@@ -158,7 +158,7 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
case resourcev3.SecretType:
temp := &tlsv3.Secret{}
if err = protojson.Unmarshal(jsonBytes, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, p.Operation.Value))
+ tErr := errors.New(unmarshalErrorMessage(err, p.Operation.Value))
tErrs = errors.Join(tErrs, tErr)
continue
}
@@ -240,125 +240,150 @@ func processJSONPatches(tCtx *types.ResourceVersionTable, envoyPatchPolicies []*
}
}
- // Convert patch to JSON
- // The patch library expects an array so convert it into one
- y, err := yaml.Marshal([]ir.JSONPatchOperation{p.Operation})
- if err != nil {
- tErr := fmt.Errorf("unable to marshal patch %+v, err: %s", p.Operation, err.Error())
- tErrs = errors.Join(tErrs, tErr)
- continue
- }
- jsonBytes, err := yaml.YAMLToJSON(y)
- if err != nil {
- tErr := fmt.Errorf("unable to convert patch to json %s, err: %s", string(y), err.Error())
- tErrs = errors.Join(tErrs, tErr)
- continue
- }
- patchObj, err := jsonpatchv5.DecodePatch(jsonBytes)
- if err != nil {
- tErr := fmt.Errorf("unable to decode patch %s, err: %s", string(jsonBytes), err.Error())
- tErrs = errors.Join(tErrs, tErr)
- continue
- }
-
- // Apply patch
- opts := jsonpatchv5.NewApplyOptions()
- opts.EnsurePathExistsOnAdd = true
- modifiedJSON, err := patchObj.ApplyWithOptions(resourceJSON, opts)
- if err != nil {
- tErr := fmt.Errorf("unable to apply patch:\n%s on resource:\n%s, err: %s", string(jsonBytes), string(resourceJSON), err.Error())
- tErrs = errors.Join(tErrs, tErr)
- continue
- }
-
- // Unmarshal back to typed resource
- // Use a temp staging variable that can be marshalled
- // into and validated before saving it into the xds output resource
- switch p.Type {
- case resourcev3.ListenerType:
- temp := &listenerv3.Listener{}
- if err = protojson.Unmarshal(modifiedJSON, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, string(modifiedJSON)))
- tErrs = errors.Join(tErrs, tErr)
- continue
+ var jsonPointers []string
+ if p.Operation.JSONPath != nil {
+ path := ""
+ if p.Operation.Path != nil {
+ path = *p.Operation.Path
}
- if err = temp.Validate(); err != nil {
- tErr := fmt.Errorf("validation failed for xds resource %s, err:%s", string(modifiedJSON), err.Error())
- tErrs = errors.Join(tErrs, tErr)
- continue
- }
- if err = deepCopyPtr(temp, listener); err != nil {
- tErr := fmt.Errorf("unable to copy xds resource %s, err: %w", string(modifiedJSON), err)
- tErrs = errors.Join(tErrs, tErr)
- continue
- }
- case resourcev3.RouteType:
- temp := &routev3.RouteConfiguration{}
- if err = protojson.Unmarshal(modifiedJSON, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, string(modifiedJSON)))
- tErrs = errors.Join(tErrs, tErr)
- continue
- }
- if err = temp.Validate(); err != nil {
- tErr := fmt.Errorf("validation failed for xds resource %s, err:%s", string(modifiedJSON), err.Error())
- tErrs = errors.Join(tErrs, tErr)
- continue
- }
- if err = deepCopyPtr(temp, routeConfig); err != nil {
- tErr := fmt.Errorf("unable to copy xds resource %s, err: %w", string(modifiedJSON), err)
- tErrs = errors.Join(tErrs, tErr)
- continue
- }
- case resourcev3.ClusterType:
- temp := &clusterv3.Cluster{}
- if err = protojson.Unmarshal(modifiedJSON, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, string(modifiedJSON)))
- tErrs = errors.Join(tErrs, tErr)
- continue
- }
- if err = temp.Validate(); err != nil {
- tErr := fmt.Errorf("validation failed for xds resource %s, err:%s", string(modifiedJSON), err.Error())
- tErrs = errors.Join(tErrs, tErr)
- continue
- }
- if err = deepCopyPtr(temp, cluster); err != nil {
- tErr := fmt.Errorf("unable to copy xds resource %s, err: %w", string(modifiedJSON), err)
+ jsonPointers, err = ConvertPathToPointers(resourceJSON, *p.Operation.JSONPath, path)
+ if err != nil {
+ tErr := fmt.Errorf("unable to convert jsonPath: '%s' into jsonPointers, err: %s", *p.Operation.JSONPath, err.Error())
tErrs = errors.Join(tErrs, tErr)
continue
}
- case resourcev3.EndpointType:
- temp := &endpointv3.ClusterLoadAssignment{}
- if err = protojson.Unmarshal(modifiedJSON, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, string(modifiedJSON)))
- tErrs = errors.Join(tErrs, tErr)
- continue
+ } else {
+ jsonPointers = []string{*p.Operation.Path}
+ }
+
+ for _, path := range jsonPointers {
+ op := ir.JSONPatchOperation{
+ Path: &path,
+ Op: p.Operation.Op,
+ Value: p.Operation.Value,
+ From: p.Operation.From,
}
- if err = temp.Validate(); err != nil {
- tErr := fmt.Errorf("validation failed for xds resource %s, err:%s", string(modifiedJSON), err.Error())
+
+ // Convert patch to JSON
+ // The patch library expects an array so convert it into one
+ y, err := yaml.Marshal([]ir.JSONPatchOperation{op})
+ if err != nil {
+ tErr := fmt.Errorf("unable to marshal patch %+v, err: %s", op, err.Error())
tErrs = errors.Join(tErrs, tErr)
continue
}
- if err = deepCopyPtr(temp, endpoint); err != nil {
- tErr := fmt.Errorf("unable to copy xds resource %s, err: %w", string(modifiedJSON), err)
+ jsonBytes, err := yaml.YAMLToJSON(y)
+ if err != nil {
+ tErr := fmt.Errorf("unable to convert patch to json %s, err: %s", string(y), err.Error())
tErrs = errors.Join(tErrs, tErr)
continue
}
- case resourcev3.SecretType:
- temp := &tlsv3.Secret{}
- if err = protojson.Unmarshal(modifiedJSON, temp); err != nil {
- tErr := fmt.Errorf(unmarshalErrorMessage(err, string(modifiedJSON)))
+ patchObj, err := jsonpatchv5.DecodePatch(jsonBytes)
+ if err != nil {
+ tErr := fmt.Errorf("unable to decode patch %s, err: %s", string(jsonBytes), err.Error())
tErrs = errors.Join(tErrs, tErr)
continue
}
- if err = temp.Validate(); err != nil {
- tErr := fmt.Errorf("validation failed for xds resource %s, err:%s", string(modifiedJSON), err.Error())
+
+ // Apply patch
+ opts := jsonpatchv5.NewApplyOptions()
+ opts.EnsurePathExistsOnAdd = true
+ modifiedJSON, err := patchObj.ApplyWithOptions(resourceJSON, opts)
+ if err != nil {
+ tErr := fmt.Errorf("unable to apply patch:\n%s on resource:\n%s, err: %s", string(jsonBytes), string(resourceJSON), err.Error())
tErrs = errors.Join(tErrs, tErr)
continue
}
- if err = deepCopyPtr(temp, secret); err != nil {
- tErr := fmt.Errorf("unable to copy xds resource %s, err: %w", string(modifiedJSON), err)
- tErrs = errors.Join(tErrs, tErr)
- continue
+
+ // Unmarshal back to typed resource
+ // Use a temp staging variable that can be marshalled
+ // into and validated before saving it into the xds output resource
+ switch p.Type {
+ case resourcev3.ListenerType:
+ temp := &listenerv3.Listener{}
+ if err = protojson.Unmarshal(modifiedJSON, temp); err != nil {
+ tErr := errors.New(unmarshalErrorMessage(err, string(modifiedJSON)))
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ if err = temp.Validate(); err != nil {
+ tErr := fmt.Errorf("validation failed for xds resource %s, err:%s", string(modifiedJSON), err.Error())
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ if err = deepCopyPtr(temp, listener); err != nil {
+ tErr := fmt.Errorf("unable to copy xds resource %s, err: %w", string(modifiedJSON), err)
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ case resourcev3.RouteType:
+ temp := &routev3.RouteConfiguration{}
+ if err = protojson.Unmarshal(modifiedJSON, temp); err != nil {
+ tErr := errors.New(unmarshalErrorMessage(err, string(modifiedJSON)))
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ if err = temp.Validate(); err != nil {
+ tErr := fmt.Errorf("validation failed for xds resource %s, err:%s", string(modifiedJSON), err.Error())
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ if err = deepCopyPtr(temp, routeConfig); err != nil {
+ tErr := fmt.Errorf("unable to copy xds resource %s, err: %w", string(modifiedJSON), err)
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ case resourcev3.ClusterType:
+ temp := &clusterv3.Cluster{}
+ if err = protojson.Unmarshal(modifiedJSON, temp); err != nil {
+ tErr := errors.New(unmarshalErrorMessage(err, string(modifiedJSON)))
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ if err = temp.Validate(); err != nil {
+ tErr := fmt.Errorf("validation failed for xds resource %s, err:%s", string(modifiedJSON), err.Error())
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ if err = deepCopyPtr(temp, cluster); err != nil {
+ tErr := fmt.Errorf("unable to copy xds resource %s, err: %w", string(modifiedJSON), err)
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ case resourcev3.EndpointType:
+ temp := &endpointv3.ClusterLoadAssignment{}
+ if err = protojson.Unmarshal(modifiedJSON, temp); err != nil {
+ tErr := errors.New(unmarshalErrorMessage(err, string(modifiedJSON)))
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ if err = temp.Validate(); err != nil {
+ tErr := fmt.Errorf("validation failed for xds resource %s, err:%s", string(modifiedJSON), err.Error())
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ if err = deepCopyPtr(temp, endpoint); err != nil {
+ tErr := fmt.Errorf("unable to copy xds resource %s, err: %w", string(modifiedJSON), err)
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ case resourcev3.SecretType:
+ temp := &tlsv3.Secret{}
+ if err = protojson.Unmarshal(modifiedJSON, temp); err != nil {
+ tErr := errors.New(unmarshalErrorMessage(err, string(modifiedJSON)))
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ if err = temp.Validate(); err != nil {
+ tErr := fmt.Errorf("validation failed for xds resource %s, err:%s", string(modifiedJSON), err.Error())
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
+ if err = deepCopyPtr(temp, secret); err != nil {
+ tErr := fmt.Errorf("unable to copy xds resource %s, err: %w", string(modifiedJSON), err)
+ tErrs = errors.Join(tErrs, tErr)
+ continue
+ }
}
}
}
diff --git a/internal/xds/translator/jsonpathtopointer.go b/internal/xds/translator/jsonpathtopointer.go
new file mode 100644
index 00000000000..89d7fdf1c77
--- /dev/null
+++ b/internal/xds/translator/jsonpathtopointer.go
@@ -0,0 +1,120 @@
+// 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 translator
+
+import (
+ "reflect"
+ "strings"
+
+ "github.com/ohler55/ojg/jp"
+ "github.com/ohler55/ojg/oj"
+ "github.com/pkg/errors"
+)
+
+func ConvertPathToPointers(jsonDoc []byte, jsonPath string, path string) ([]string, error) {
+ var jsonPointers []string
+
+ jObj, err := oj.Parse(jsonDoc)
+ if err != nil {
+ return nil, errors.Wrap(err, "Error during parsing json")
+ }
+
+ jPath, err := jp.ParseString(jsonPath)
+ if err != nil {
+ return nil, errors.Wrap(err, "Error during parsing jpath")
+ }
+
+ if len(jPath) == 1 {
+ _, isRoot := jPath[0].(jp.Root)
+ if isRoot {
+ return nil, errors.New("Using only Root ('$') in json path expression is not allowed!")
+ }
+ }
+
+ locations := jPath.Locate(jObj, 0)
+ for _, l := range locations {
+ jsonPointer, err := expToPointer(l)
+ if err != nil {
+ return nil, errors.Wrap(err, "Error during converting path to pointer")
+ }
+ jsonPointers = append(jsonPointers, concat(jsonPointer, path))
+ }
+ return jsonPointers, nil
+}
+
+func concat(jsonPointer string, path string) string {
+ if path == "" {
+ return jsonPointer
+ }
+ const separator string = "/"
+ parts := []string{
+ strings.TrimSuffix(jsonPointer, separator),
+ strings.TrimPrefix(path, separator),
+ }
+ return strings.Join(parts, separator)
+}
+
+func expToPointer(e jp.Expr) (string, error) {
+ var buf []byte
+ for _, f := range e {
+ v, err := fragToPointer(f)
+ if err != nil {
+ return "", err
+ }
+ if v != nil {
+ buf = append(buf, '/')
+ }
+
+ buf = append(buf, v...)
+ }
+
+ return string(buf), nil
+}
+
+func fragToPointer(f jp.Frag) ([]byte, error) {
+ switch v := f.(type) {
+ case jp.Root:
+ return rootToPointer()
+ case jp.Nth:
+ return nthToPointer(v)
+ case jp.Child:
+ return toPointer(v)
+ default:
+ return nil, errors.New("There is no conversion implemented for " + reflect.TypeOf(v).Name())
+ }
+}
+
+func rootToPointer() ([]byte, error) {
+ return nil, nil
+}
+
+func nthToPointer(f jp.Nth) ([]byte, error) {
+ var buf []byte
+ i := int(f)
+ if i < 0 {
+ buf = append(buf, '-')
+ i = -i
+ }
+ num := [20]byte{}
+ cnt := 0
+ for ; i != 0; cnt++ {
+ num[cnt] = byte(i%10) + '0'
+ i /= 10
+ }
+ if 0 < cnt {
+ cnt--
+ for ; 0 <= cnt; cnt-- {
+ buf = append(buf, num[cnt])
+ }
+ } else {
+ buf = append(buf, '0')
+ }
+ return buf, nil
+}
+
+func toPointer(f jp.Frag) ([]byte, error) {
+ return f.Append(nil, false, true), nil
+}
diff --git a/internal/xds/translator/jsonpathtopointer_test.go b/internal/xds/translator/jsonpathtopointer_test.go
new file mode 100644
index 00000000000..cefb5925869
--- /dev/null
+++ b/internal/xds/translator/jsonpathtopointer_test.go
@@ -0,0 +1,395 @@
+// 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 translator
+
+import (
+ "sort"
+ "strconv"
+ "testing"
+
+ "github.com/ohler55/ojg/jp"
+ "github.com/stretchr/testify/require"
+)
+
+const case1Simple string = `{
+ "a": "b"
+ }`
+
+const case2Nested string = `{
+ "a": "b",
+ "v": [{
+ "x": "test1",
+ "y": "hello"
+ },
+ {
+ "x": "test2",
+ "y": "world"
+ }],
+ "f":{
+ "w": "hi",
+ "q": "welcome",
+ "y": "ciao"
+ },
+ "y": "c"
+ }`
+
+const case3Route string = `{
+ "name": "default/eg/http",
+ "virtual_hosts": [
+ {
+ "name": "default/eg/http/www_test_com",
+ "domains": [
+ "www.test.com"
+ ],
+ "routes": [
+ {
+ "name": "httproute/default/backend/rule/0/match/0/www_test_com",
+ "match": {
+ "prefix": "/"
+ },
+ "route": {
+ "cluster": "httproute/default/backend/rule/0",
+ "upgrade_configs": [
+ {
+ "upgrade_type": "websocket"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "default/eg/http/www_example_com",
+ "domains": [
+ "www.example.com"
+ ],
+ "routes": [
+ {
+ "name": "httproute/default/backend/rule/1/match/1/www_example_com",
+ "match": {
+ "prefix": "/"
+ },
+ "route": {
+ "cluster": "httproute/default/backend/rule/1",
+ "upgrade_configs": [
+ {
+ "upgrade_type": "websocket"
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ],
+ "ignore_port_in_host_matching": true
+}`
+
+func Test(t *testing.T) {
+ tests := []struct {
+ // Json Document
+ doc string
+
+ // JSONPath
+ jsonPath string
+
+ // path
+ path string
+
+ // List of expected pointers
+ expected []string
+ }{
+ {
+ doc: case1Simple,
+ jsonPath: "$.a",
+ expected: []string{
+ "/a",
+ },
+ },
+ {
+ doc: case2Nested,
+ jsonPath: "$.v[?(@.x=='test2')]",
+ expected: []string{
+ "/v/1",
+ },
+ },
+ {
+ doc: case2Nested,
+ jsonPath: "..v[?(@.x=='test1')].y",
+ expected: []string{
+ "/v/0/y",
+ },
+ },
+ {
+ doc: case2Nested,
+ jsonPath: "$.v[?(@.x=='test2')].y",
+ expected: []string{
+ "/v/1/y",
+ },
+ },
+ {
+ doc: case2Nested,
+ jsonPath: "$.v[?(@.x=='test1')].y",
+ expected: []string{
+ "/v/0/y",
+ },
+ },
+ {
+ doc: case2Nested,
+ jsonPath: "$.v[*].y",
+ expected: []string{
+ "/v/0/y",
+ "/v/1/y",
+ },
+ },
+ {
+ doc: case2Nested,
+ jsonPath: "$.v[?(@.x=='UNKNOWN')].y",
+ expected: []string{},
+ },
+ {
+ doc: case1Simple,
+ jsonPath: ".a",
+ expected: []string{
+ "/a",
+ },
+ },
+ {
+ doc: case1Simple,
+ jsonPath: "a",
+ expected: []string{
+ "/a",
+ },
+ },
+ {
+ doc: case2Nested,
+ jsonPath: "f.w",
+ expected: []string{
+ "/f/w",
+ },
+ },
+ {
+ doc: case2Nested,
+ jsonPath: "f.*",
+ expected: []string{
+ "/f/w",
+ "/f/q",
+ "/f/y",
+ },
+ },
+ {
+ doc: case2Nested,
+ jsonPath: "v.*",
+ expected: []string{
+ "/v/0",
+ "/v/1",
+ },
+ },
+ {
+ doc: case2Nested,
+ jsonPath: "v.**",
+ expected: []string{
+ "/v/0/x",
+ "/v/0/y",
+ "/v/1/x",
+ "/v/1/y",
+ },
+ },
+ {
+ doc: case2Nested,
+ jsonPath: "$..y",
+ expected: []string{
+ "/f/y",
+ "/v/0/y",
+ "/v/1/y",
+ "/y",
+ },
+ },
+ {
+ doc: case2Nested,
+ jsonPath: "..y",
+ expected: []string{
+ "/f/y",
+ "/v/0/y",
+ "/v/1/y",
+ "/y",
+ },
+ },
+ {
+ doc: case2Nested,
+ jsonPath: "**.y",
+ expected: []string{
+ "/v/0/y",
+ "/v/1/y",
+ },
+ },
+ {
+ doc: case3Route,
+ jsonPath: "..routes[?(@.name =~ 'www_example_com')]",
+ expected: []string{
+ "/virtual_hosts/1/routes/0",
+ },
+ },
+ {
+ doc: case3Route,
+ jsonPath: "..routes[?(@.name =~ 'www_test_com')]",
+ expected: []string{
+ "/virtual_hosts/0/routes/0",
+ },
+ },
+ {
+ doc: case3Route,
+ jsonPath: "..routes[?(@.name =~ 'www')]",
+ expected: []string{
+ "/virtual_hosts/0/routes/0",
+ "/virtual_hosts/1/routes/0",
+ },
+ },
+ {
+ doc: case3Route,
+ jsonPath: "..routes[?(@.name =~ 'www')].route.cluster",
+ expected: []string{
+ "/virtual_hosts/0/routes/0/route/cluster",
+ "/virtual_hosts/1/routes/0/route/cluster",
+ },
+ },
+ {
+ doc: case3Route,
+ jsonPath: "..routes[?(@.name =~ 'www')]['route']['cluster']",
+ expected: []string{
+ "/virtual_hosts/0/routes/0/route/cluster",
+ "/virtual_hosts/1/routes/0/route/cluster",
+ },
+ },
+ {
+ doc: case3Route,
+ jsonPath: "..routes[?(@.name=='httproute/default/backend/rule/1/match/1/www_example_com')].route.upgrade_configs",
+ expected: []string{
+ "/virtual_hosts/1/routes/0/route/upgrade_configs",
+ },
+ },
+ {
+ doc: case3Route,
+ jsonPath: "..routes[?(@.name =~ 'www')]",
+ path: "/abc",
+ expected: []string{
+ "/virtual_hosts/0/routes/0/abc",
+ "/virtual_hosts/1/routes/0/abc",
+ },
+ },
+ {
+ doc: case3Route,
+ jsonPath: "..routes[?(@.name =~ 'www')]",
+ path: "abc",
+ expected: []string{
+ "/virtual_hosts/0/routes/0/abc",
+ "/virtual_hosts/1/routes/0/abc",
+ },
+ },
+ {
+ doc: case3Route,
+ jsonPath: "..routes[?(@.name =~ 'www')]",
+ path: "/",
+ expected: []string{
+ "/virtual_hosts/0/routes/0/",
+ "/virtual_hosts/1/routes/0/",
+ },
+ },
+ }
+
+ for i, test := range tests {
+
+ testCasePrefix := "TestCase " + strconv.Itoa(i+1)
+ pointers, err := ConvertPathToPointers([]byte(test.doc), test.jsonPath, test.path)
+ if err != nil {
+ t.Error(testCasePrefix + ": Error during conversion:\n" + err.Error())
+ continue
+ }
+
+ expectedAsString := asString(test.expected)
+ pointersAsString := asString(pointers)
+
+ require.Equal(t, expectedAsString, pointersAsString)
+ }
+}
+
+func TestException(t *testing.T) {
+ tests := []struct {
+ // Json Document
+ doc string
+
+ // JSONPath
+ jsonPath string
+
+ // path
+ path string
+
+ // expected exception
+ expected string
+ }{
+ {
+ doc: case1Simple,
+ jsonPath: ".$",
+ expected: "Error during parsing jpath",
+ },
+ {
+ doc: case1Simple,
+ jsonPath: "$",
+ expected: "only Root",
+ },
+ {
+ doc: "{",
+ jsonPath: ".$",
+ expected: "Error during parsing json",
+ },
+ }
+
+ for i, test := range tests {
+
+ testCasePrefix := "TestCase " + strconv.Itoa(i+1)
+ _, err := ConvertPathToPointers([]byte(test.doc), test.jsonPath, test.path)
+ if err == nil {
+ t.Error(testCasePrefix + ": Error expected, but no error found!")
+ continue
+ }
+
+ require.ErrorContains(t, err, test.expected)
+ }
+}
+
+func TestUnexpectedFrag(t *testing.T) {
+ expr := jp.Expr{}
+ expr = append(expr, jp.Union{})
+
+ _, err := expToPointer(expr)
+ if err == nil {
+ t.Error("Error expected, but no error found!")
+ }
+
+ require.ErrorContains(t, err, "There is no conversion implemented for Union")
+}
+
+func TestNegativeNth(t *testing.T) {
+ result, err := nthToPointer(jp.Nth(-1))
+ if err != nil {
+ t.Error(err)
+ }
+ test := string(result)
+ if test != "-1" {
+ t.Error("expected -1, but was " + test + "!")
+ }
+}
+
+func asString(values []string) string {
+ var buf []byte
+
+ sort.Strings(values)
+ for _, v := range values {
+ buf = append(buf, []byte(v)...)
+ buf = append(buf, []byte("\n")...)
+ }
+
+ return string(buf)
+}
diff --git a/internal/xds/translator/listener.go b/internal/xds/translator/listener.go
index 0812010ade1..9b442c75105 100644
--- a/internal/xds/translator/listener.go
+++ b/internal/xds/translator/listener.go
@@ -12,6 +12,7 @@ import (
xdscore "github.com/cncf/xds/go/xds/core/v3"
matcher "github.com/cncf/xds/go/xds/type/matcher/v3"
+ mutation_rulesv3 "github.com/envoyproxy/go-control-plane/envoy/config/common/mutation_rules/v3"
corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
listenerv3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
tls_inspectorv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/listener/tls_inspector/v3"
@@ -19,6 +20,7 @@ import (
hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
tcpv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/tcp_proxy/v3"
udpv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/udp/udp_proxy/v3"
+ early_header_mutationv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/http/early_header_mutation/header_mutation/v3"
preservecasev3 "github.com/envoyproxy/go-control-plane/envoy/extensions/http/header_formatters/preserve_case/v3"
customheaderv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/http/original_ip_detection/custom_header/v3"
quicv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/quic/v3"
@@ -274,9 +276,10 @@ func (t *Translator) addHCMToXDSListener(xdsListener *listenerv3.Listener, irLis
CommonHttpProtocolOptions: &corev3.HttpProtocolOptions{
HeadersWithUnderscoresAction: buildHeadersWithUnderscoresAction(irListener.Headers),
},
- Tracing: hcmTracing,
- ForwardClientCertDetails: buildForwardClientCertDetailsAction(irListener.Headers),
- PreserveExternalRequestId: ptr.Deref(irListener.Headers, ir.HeaderSettings{}).PreserveXRequestID,
+ Tracing: hcmTracing,
+ ForwardClientCertDetails: buildForwardClientCertDetailsAction(irListener.Headers),
+ PreserveExternalRequestId: ptr.Deref(irListener.Headers, ir.HeaderSettings{}).PreserveXRequestID,
+ EarlyHeaderMutationExtensions: buildEarlyHeaderMutation(irListener.Headers),
}
if mgr.ForwardClientCertDetails == hcmv3.HttpConnectionManager_APPEND_FORWARD || mgr.ForwardClientCertDetails == hcmv3.HttpConnectionManager_SANITIZE_SET {
@@ -365,6 +368,73 @@ func (t *Translator) addHCMToXDSListener(xdsListener *listenerv3.Listener, irLis
return nil
}
+func buildEarlyHeaderMutation(headers *ir.HeaderSettings) []*corev3.TypedExtensionConfig {
+ if headers == nil || (len(headers.EarlyAddRequestHeaders) == 0 && len(headers.EarlyRemoveRequestHeaders) == 0) {
+ return nil
+ }
+
+ var mutationRules []*mutation_rulesv3.HeaderMutation
+
+ for _, header := range headers.EarlyAddRequestHeaders {
+ var appendAction corev3.HeaderValueOption_HeaderAppendAction
+ if header.Append {
+ appendAction = corev3.HeaderValueOption_APPEND_IF_EXISTS_OR_ADD
+ } else {
+ appendAction = corev3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD
+ }
+ // Allow empty headers to be set, but don't add the config to do so unless necessary
+ if len(header.Value) == 0 {
+ mutationRules = append(mutationRules, &mutation_rulesv3.HeaderMutation{
+ Action: &mutation_rulesv3.HeaderMutation_Append{
+ Append: &corev3.HeaderValueOption{
+ Header: &corev3.HeaderValue{
+ Key: header.Name,
+ },
+ AppendAction: appendAction,
+ KeepEmptyValue: true,
+ },
+ },
+ })
+ } else {
+ for _, val := range header.Value {
+ mutationRules = append(mutationRules, &mutation_rulesv3.HeaderMutation{
+ Action: &mutation_rulesv3.HeaderMutation_Append{
+ Append: &corev3.HeaderValueOption{
+ Header: &corev3.HeaderValue{
+ Key: header.Name,
+ Value: val,
+ },
+ AppendAction: appendAction,
+ KeepEmptyValue: val == "",
+ },
+ },
+ })
+ }
+ }
+ }
+
+ for _, header := range headers.EarlyRemoveRequestHeaders {
+ mr := &mutation_rulesv3.HeaderMutation{
+ Action: &mutation_rulesv3.HeaderMutation_Remove{
+ Remove: header,
+ },
+ }
+
+ mutationRules = append(mutationRules, mr)
+ }
+
+ earlyHeaderMutationAny, _ := anypb.New(&early_header_mutationv3.HeaderMutation{
+ Mutations: mutationRules,
+ })
+
+ return []*corev3.TypedExtensionConfig{
+ {
+ Name: "envoy.http.early_header_mutation.header_mutation",
+ TypedConfig: earlyHeaderMutationAny,
+ },
+ }
+}
+
func addServerNamesMatch(xdsListener *listenerv3.Listener, filterChain *listenerv3.FilterChain, hostnames []string) error {
// Dont add a filter chain match if the hostname is a wildcard character.
if len(hostnames) > 0 && hostnames[0] != "*" {
diff --git a/internal/xds/translator/route.go b/internal/xds/translator/route.go
index 8a56e9e42b1..42f17ff94f1 100644
--- a/internal/xds/translator/route.go
+++ b/internal/xds/translator/route.go
@@ -438,9 +438,9 @@ func buildXdsRequestMirrorPolicies(mirrorDestinations []*ir.RouteDestination) []
}
func buildXdsAddedHeaders(headersToAdd []ir.AddHeader) []*corev3.HeaderValueOption {
- headerValueOptions := make([]*corev3.HeaderValueOption, len(headersToAdd))
+ headerValueOptions := []*corev3.HeaderValueOption{}
- for i, header := range headersToAdd {
+ for _, header := range headersToAdd {
var appendAction corev3.HeaderValueOption_HeaderAppendAction
if header.Append {
@@ -448,18 +448,26 @@ func buildXdsAddedHeaders(headersToAdd []ir.AddHeader) []*corev3.HeaderValueOpti
} else {
appendAction = corev3.HeaderValueOption_OVERWRITE_IF_EXISTS_OR_ADD
}
-
- headerValueOptions[i] = &corev3.HeaderValueOption{
- Header: &corev3.HeaderValue{
- Key: header.Name,
- Value: header.Value,
- },
- AppendAction: appendAction,
- }
-
// Allow empty headers to be set, but don't add the config to do so unless necessary
- if header.Value == "" {
- headerValueOptions[i].KeepEmptyValue = true
+ if len(header.Value) == 0 {
+ headerValueOptions = append(headerValueOptions, &corev3.HeaderValueOption{
+ Header: &corev3.HeaderValue{
+ Key: header.Name,
+ },
+ AppendAction: appendAction,
+ KeepEmptyValue: true,
+ })
+ } else {
+ for _, val := range header.Value {
+ headerValueOptions = append(headerValueOptions, &corev3.HeaderValueOption{
+ Header: &corev3.HeaderValue{
+ Key: header.Name,
+ Value: val,
+ },
+ AppendAction: appendAction,
+ KeepEmptyValue: val == "",
+ })
+ }
}
}
@@ -548,7 +556,7 @@ func buildRetryPolicy(route *ir.HTTPRoute) (*routev3.RetryPolicy, error) {
}
if rr.RetryOn != nil {
- if rr.RetryOn.Triggers != nil && len(rr.RetryOn.Triggers) > 0 {
+ if len(rr.RetryOn.Triggers) > 0 {
if ro, err := buildRetryOn(rr.RetryOn.Triggers); err == nil {
rp.RetryOn = ro
} else {
@@ -556,7 +564,7 @@ func buildRetryPolicy(route *ir.HTTPRoute) (*routev3.RetryPolicy, error) {
}
}
- if rr.RetryOn.HTTPStatusCodes != nil && len(rr.RetryOn.HTTPStatusCodes) > 0 {
+ if len(rr.RetryOn.HTTPStatusCodes) > 0 {
rp.RetriableStatusCodes = buildRetryStatusCodes(rr.RetryOn.HTTPStatusCodes)
}
}
diff --git a/internal/xds/translator/session_persistence.go b/internal/xds/translator/session_persistence.go
new file mode 100644
index 00000000000..703e553ce47
--- /dev/null
+++ b/internal/xds/translator/session_persistence.go
@@ -0,0 +1,169 @@
+// 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 translator
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+
+ corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
+ routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3"
+ statefulsessionv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/stateful_session/v3"
+ hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3"
+ cookiev3 "github.com/envoyproxy/go-control-plane/envoy/extensions/http/stateful_session/cookie/v3"
+ headerv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/http/stateful_session/header/v3"
+ httpv3 "github.com/envoyproxy/go-control-plane/envoy/type/http/v3"
+ "google.golang.org/protobuf/proto"
+ "google.golang.org/protobuf/types/known/anypb"
+ "google.golang.org/protobuf/types/known/durationpb"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/xds/types"
+)
+
+const (
+ cookieConfigName = "envoy.http.stateful_session.cookie"
+ headerConfigName = "envoy.http.stateful_session.header"
+)
+
+type sessionPersistence struct{}
+
+func init() {
+ registerHTTPFilter(&sessionPersistence{})
+}
+
+var _ httpFilter = &sessionPersistence{}
+
+// patchHCM patches the HttpConnectionManager with the filter.
+// Note: this method may be called multiple times for the same filter, please
+// make sure to avoid duplicate additions of the same filter.
+func (s *sessionPersistence) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListener) error {
+ if mgr == nil {
+ return errors.New("hcm is nil")
+ }
+
+ if irListener == nil {
+ return errors.New("ir listener is nil")
+ }
+
+ for _, route := range irListener.Routes {
+ sp := route.SessionPersistence
+ if sp == nil {
+ continue
+ }
+
+ if hcmContainsFilter(mgr, perRouteFilterName(egv1a1.EnvoyFilterSessionPersistence, route.Name)) {
+ continue
+ }
+
+ var sessionCfg proto.Message
+ var configName string
+ switch {
+ case sp.Cookie != nil:
+ configName = cookieConfigName
+ sessionCfg = &cookiev3.CookieBasedSessionState{
+ Cookie: &httpv3.Cookie{
+ Name: sp.Cookie.Name,
+ Path: routePathToCookiePath(route.PathMatch),
+ Ttl: durationpb.New(sp.Cookie.TTL.Duration),
+ },
+ }
+ case sp.Header != nil:
+ configName = headerConfigName
+ sessionCfg = &headerv3.HeaderBasedSessionState{
+ Name: sp.Header.Name,
+ }
+ }
+
+ sessionCfgAny, err := anypb.New(sessionCfg)
+ if err != nil {
+ return fmt.Errorf("failed to marshal %s config: %w", egv1a1.EnvoyFilterSessionPersistence.String(), err)
+ }
+
+ cfg := &statefulsessionv3.StatefulSession{
+ SessionState: &corev3.TypedExtensionConfig{
+ Name: configName,
+ TypedConfig: sessionCfgAny,
+ },
+ }
+
+ cfgAny, err := anypb.New(cfg)
+ if err != nil {
+ return fmt.Errorf("failed to marshal %s config: %w", egv1a1.EnvoyFilterSessionPersistence.String(), err)
+ }
+
+ mgr.HttpFilters = append(mgr.HttpFilters, &hcmv3.HttpFilter{
+ Name: perRouteFilterName(egv1a1.EnvoyFilterSessionPersistence, route.Name),
+ Disabled: true,
+ ConfigType: &hcmv3.HttpFilter_TypedConfig{
+ TypedConfig: cfgAny,
+ },
+ })
+ }
+
+ return nil
+}
+
+func routePathToCookiePath(path *ir.StringMatch) string {
+ if path == nil {
+ return "/"
+ }
+ switch {
+ case path.Exact != nil:
+ return *path.Exact
+ case path.Prefix != nil:
+ return *path.Prefix
+ case path.SafeRegex != nil:
+ return getLongestNonRegexPrefix(*path.SafeRegex)
+ }
+
+ // Shouldn't reach here because the path should be either of the above three kinds.
+ return "/"
+}
+
+// getLongestNonRegexPrefix takes a regex path and returns the longest non-regex prefix.
+// > 3. For an xRoute using a path that is a regex, the Path should be set to the longest non-regex prefix
+// (.e.g. if the path is /p1/p2/*/p3 and the request path was /p1/p2/foo/p3, then the cookie path would be /p1/p2).
+// https://gateway-api.sigs.k8s.io/geps/gep-1619/#path
+func getLongestNonRegexPrefix(path string) string {
+ parts := strings.Split(path, "/")
+ var longestNonRegexPrefix []string
+ for _, part := range parts {
+ if part == "*" || strings.Contains(part, "*") {
+ break
+ }
+ longestNonRegexPrefix = append(longestNonRegexPrefix, part)
+ }
+
+ return strings.Join(longestNonRegexPrefix, "/")
+}
+
+// patchRoute patches the provide Route with a filter's Route level configuration.
+func (s *sessionPersistence) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error {
+ if route == nil {
+ return errors.New("xds route is nil")
+ }
+ if irRoute == nil {
+ return errors.New("ir route is nil")
+ }
+ if irRoute.SessionPersistence == nil {
+ return nil
+ }
+
+ if err := enableFilterOnRoute(route, perRouteFilterName(egv1a1.EnvoyFilterSessionPersistence, route.Name)); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// patchResources adds all the other needed resources referenced by this
+// filter to the resource version table.
+func (s *sessionPersistence) patchResources(tCtx *types.ResourceVersionTable, routes []*ir.HTTPRoute) error {
+ return nil
+}
diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-als-tcp.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-als-tcp.yaml
index 2d8f0c6aa48..4b437f443e8 100644
--- a/internal/xds/translator/testdata/in/xds-ir/accesslog-als-tcp.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-als-tcp.yaml
@@ -17,6 +17,27 @@ accesslog:
port: 9000
protocol: GRPC
weight: 1
+ traffic:
+ backendConnection:
+ bufferLimit: 20971520
+ circuitBreaker:
+ maxConnections: 2048
+ healthCheck:
+ passive:
+ baseEjectionTime: 30s
+ consecutiveGatewayErrors: 4
+ consecutive5XxErrors: 5
+ consecutiveLocalOriginFailures: 5
+ interval: 5s
+ maxEjectionPercent: 10
+ splitExternalLocalOriginErrors: false
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
attributes:
attr1: value1
attr2: value2
diff --git a/internal/xds/translator/testdata/in/xds-ir/backend-priority.yaml b/internal/xds/translator/testdata/in/xds-ir/backend-priority.yaml
new file mode 100644
index 00000000000..b18671d7879
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/backend-priority.yaml
@@ -0,0 +1,97 @@
+http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ envoyExtensions:
+ extProcs:
+ - authority: grpc-backend.envoy-gateway:8000
+ destination:
+ name: envoyextensionpolicy/default/policy-for-http-route/0
+ settings:
+ - addressType: IP
+ protocol: GRPC
+ tls:
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls-grpc/envoy-gateway-ca
+ sni: grpc-backend
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 8.8.8.8
+ port: 9000
+ priority: 1
+ protocol: GRPC
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ priority: 1
+ protocol: GRPC
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 2.2.2.2
+ port: 3443
+ priority: 1
+ protocol: GRPC
+ tls:
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls-backend-ip/envoy-gateway-ca
+ sni: ip-backend
+ weight: 1
+ name: envoyextensionpolicy/default/policy-for-http-route/extproc/0
+ hostname: www.foo.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.bar.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
diff --git a/internal/xds/translator/testdata/in/xds-ir/ext-auth-backend.yaml b/internal/xds/translator/testdata/in/xds-ir/ext-auth-backend.yaml
new file mode 100644
index 00000000000..4f93e2e7734
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/ext-auth-backend.yaml
@@ -0,0 +1,123 @@
+http:
+ - address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ hostname: www.foo.com
+ isHTTP2: false
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo1
+ backendWeights:
+ invalid: 0
+ valid: 0
+ destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ security:
+ extAuth:
+ name: securitypolicy/default/policy-for-http-route-1
+ failOpen: false
+ grpc:
+ authority: primary.foo.com
+ destination:
+ name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 9000
+ protocol: GRPC
+ weight: 1
+ headersToExtAuth:
+ - header1
+ - header2
+ - name: httproute/default/httproute-1/rule/1/match/0/www_foo_com
+ hostname: www.foo.com
+ isHTTP2: false
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo2
+ backendWeights:
+ invalid: 0
+ valid: 0
+ destination:
+ name: httproute/default/httproute-1/rule/1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ security:
+ extAuth:
+ name: securitypolicy/default/policy-for-http-route-1
+ failOpen: false
+ grpc:
+ authority: primary.foo.com
+ destination:
+ name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: primary.foo.com
+ port: 3000
+ protocol: GRPC
+ weight: 1
+ headersToExtAuth:
+ - header1
+ - header2
+ - name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ hostname: www.bar.com
+ isHTTP2: false
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
+ backendWeights:
+ invalid: 0
+ valid: 0
+ destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ security:
+ extAuth:
+ name: securitypolicy/default/policy-for-gateway-1
+ failOpen: true
+ http:
+ authority: primary.foo.com
+ destination:
+ name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ settings:
+ - addressType: FQDN
+ endpoints:
+ - host: primary.foo.com
+ port: 80
+ protocol: HTTP
+ weight: 1
+ headersToBackend:
+ - header1
+ - header2
+ path: /auth
diff --git a/internal/xds/translator/testdata/in/xds-ir/ext-proc-with-traffic-settings.yaml b/internal/xds/translator/testdata/in/xds-ir/ext-proc-with-traffic-settings.yaml
new file mode 100644
index 00000000000..136fd53ff6a
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/ext-proc-with-traffic-settings.yaml
@@ -0,0 +1,124 @@
+http:
+- address: 0.0.0.0
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ envoyExtensions:
+ extProcs:
+ - authority: grpc-backend.envoy-gateway:8000
+ destination:
+ name: envoyextensionpolicy/default/policy-for-http-route/0
+ settings:
+ - addressType: IP
+ protocol: GRPC
+ tls:
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls-grpc/envoy-gateway-ca
+ sni: grpc-backend
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 8.8.8.8
+ port: 9000
+ protocol: GRPC
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 1.1.1.1
+ port: 3001
+ protocol: GRPC
+ weight: 1
+ - addressType: IP
+ endpoints:
+ - host: 2.2.2.2
+ port: 3443
+ protocol: GRPC
+ tls:
+ caCertificate:
+ certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+ name: policy-btls-backend-ip/envoy-gateway-ca
+ sni: ip-backend
+ weight: 1
+ name: envoyextensionpolicy/default/policy-for-http-route/extproc/0
+ traffic:
+ backendConnection:
+ bufferLimit: 20971520
+ circuitBreaker:
+ maxConnections: 2048
+ healthCheck:
+ passive:
+ baseEjectionTime: 30s
+ consecutiveGatewayErrors: 4
+ consecutive5XxErrors: 5
+ consecutiveLocalOriginFailures: 5
+ interval: 5s
+ maxEjectionPercent: 10
+ splitExternalLocalOriginErrors: false
+ http2:
+ initialConnectionWindowSize: 131072
+ initialStreamWindowSize: 2097152
+ maxConcurrentStreams: 200
+ resetStreamOnError: true
+ loadBalancer:
+ roundRobin:
+ slowStart:
+ window: 5s
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
+ hostname: www.foo.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /foo
+ - destination:
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ protocol: HTTP
+ weight: 1
+ hostname: www.bar.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /bar
diff --git a/internal/xds/translator/testdata/in/xds-ir/health-check.yaml b/internal/xds/translator/testdata/in/xds-ir/health-check.yaml
index 30ecd2da792..12f62f86414 100644
--- a/internal/xds/translator/testdata/in/xds-ir/health-check.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/health-check.yaml
@@ -126,3 +126,21 @@ http:
- endpoints:
- host: "1.2.3.4"
port: 50000
+ - name: "fifth-route"
+ hostname: "*"
+ traffic:
+ healthCheck:
+ active:
+ timeout: "1s"
+ interval: "5s"
+ unhealthyThreshold: 3
+ healthyThreshold: 3
+ grpc:
+ service: my-service
+ destination:
+ name: "fifth-route-dest"
+ protocol: GRPC
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-early-header-mutation.yaml b/internal/xds/translator/testdata/in/xds-ir/http-early-header-mutation.yaml
new file mode 100644
index 00000000000..6301153cd1c
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/http-early-header-mutation.yaml
@@ -0,0 +1,59 @@
+http:
+- name: "first-listener"
+ address: "0.0.0.0"
+ port: 10080
+ hostnames:
+ - "*"
+ http1:
+ preserveHeaderCase: true
+ path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+ routes:
+ - name: "first-route"
+ hostname: "*"
+ destination:
+ name: "first-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+- name: "second-listener"
+ address: "0.0.0.0"
+ port: 10081
+ hostnames:
+ - "*"
+ headers:
+ earlyAddRequestHeaders:
+ - name: "some-header"
+ value:
+ - "some-value1"
+ - "some-value2"
+ append: true
+ - name: "some-header-2"
+ value:
+ - "some-value"
+ append: true
+ - name: "some-header3"
+ value:
+ - "some-value"
+ append: false
+ - name: "some-header4"
+ value:
+ - "some-value"
+ append: false
+ - name: "empty-header"
+ value:
+ append: false
+ earlyRemoveRequestHeaders:
+ - "some-header5"
+ - "some-header6"
+ routes:
+ - name: "second-route"
+ hostname: "*"
+ destination:
+ name: "second-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.5"
+ port: 50000
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-request-headers.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-request-headers.yaml
index c3dc4417dcc..fb45b8db724 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-request-headers.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-request-headers.yaml
@@ -18,20 +18,30 @@ http:
- host: "1.2.3.4"
port: 50000
addRequestHeaders:
+ - name: "some-header-multi-value"
+ value:
+ - "some-value"
+ - "some-additional-value"
+ append: true
- name: "some-header"
- value: "some-value"
+ value:
+ - "some-value"
append: true
- name: "some-header-2"
- value: "some-value"
+ value:
+ - "some-value"
append: true
- name: "some-header3"
- value: "some-value"
+ value:
+ - "some-value"
append: false
- name: "some-header4"
- value: "some-value"
+ value:
+ - "some-value"
append: false
- name: "empty-header"
- value: ""
+ value:
+ - ""
append: false
removeRequestHeaders:
- "some-header5"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-response-add-headers.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-response-add-headers.yaml
index e3114e2d252..3cfaf5e4945 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-response-add-headers.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-response-add-headers.yaml
@@ -19,17 +19,22 @@ http:
port: 50000
addResponseHeaders:
- name: "some-header"
- value: "some-value"
+ value:
+ - "some-value"
append: true
- name: "some-header-2"
- value: "some-value"
+ value:
+ - "some-value"
append: true
- name: "some-header3"
- value: "some-value"
+ value:
+ - "some-value"
append: false
- name: "some-header4"
- value: "some-value"
+ value:
+ - "some-value"
append: false
- name: "empty-header"
- value: ""
+ value:
+ - ""
append: false
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-response-add-remove-headers.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-response-add-remove-headers.yaml
index 0e59f8f124d..c97d927dff6 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-response-add-remove-headers.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-response-add-remove-headers.yaml
@@ -19,19 +19,24 @@ http:
port: 50000
addResponseHeaders:
- name: "some-header"
- value: "some-value"
+ value:
+ - "some-value"
append: true
- name: "some-header-2"
- value: "some-value"
+ value:
+ - "some-value"
append: true
- name: "some-header3"
- value: "some-value"
+ value:
+ - "some-value"
append: false
- name: "some-header4"
- value: "some-value"
+ value:
+ - "some-value"
append: false
- name: "empty-header"
- value: ""
+ value:
+ - ""
append: false
removeResponseHeaders:
- "some-header5"
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-session-persistence.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-session-persistence.yaml
new file mode 100644
index 00000000000..536c5ad50cb
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-session-persistence.yaml
@@ -0,0 +1,66 @@
+http:
+- name: "first-listener"
+ address: "0.0.0.0"
+ port: 10080
+ hostnames:
+ - "*"
+ path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+ routes:
+ - name: "header-based-session-persistence-route"
+ hostname: "*"
+ pathMatch:
+ safeRegex: "/v1/.*"
+ sessionPersistence:
+ header: {
+ name: "session-header"
+ }
+ destination:
+ name: "regex-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ - name: "cookie-based-session-persistence-route-regex"
+ hostname: "*"
+ pathMatch:
+ safeRegex: "/v1/.*/hoge"
+ sessionPersistence:
+ cookie:
+ name: "session-header"
+ ttl: "1h"
+ destination:
+ name: "regex-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ - name: "cookie-based-session-persistence-route-prefix"
+ hostname: "*"
+ pathMatch:
+ prefix: "/v2/"
+ sessionPersistence:
+ cookie:
+ name: "session-header"
+ ttl: "1h"
+ destination:
+ name: "regex-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ - name: "cookie-based-session-persistence-route-exact"
+ hostname: "*"
+ pathMatch:
+ exact: "/v3/user"
+ sessionPersistence:
+ cookie:
+ name: "session-cookie"
+ ttl: "1h"
+ destination:
+ name: "regex-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend-with-filters.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend-with-filters.yaml
index f8943d07f01..8745e9893bc 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend-with-filters.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-weighted-backend-with-filters.yaml
@@ -19,7 +19,8 @@ http:
addRequestHeaders:
- append: false
name: add-header-3
- value: some-value
+ value:
+ - some-value
protocol: HTTP
weight: 1
hostname: '*'
@@ -37,10 +38,12 @@ http:
addRequestHeaders:
- append: true
name: add-header-1
- value: some-value
+ value:
+ - some-value
- append: true
name: add-header-2
- value: some-value
+ value:
+ - some-value
protocol: HTTP
weight: 8
- addressType: IP
diff --git a/internal/xds/translator/testdata/in/xds-ir/jsonpatch-add-op-empty-jsonpath.yaml b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-add-op-empty-jsonpath.yaml
new file mode 100644
index 00000000000..9c248772920
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-add-op-empty-jsonpath.yaml
@@ -0,0 +1,63 @@
+envoyPatchPolicies:
+- status:
+ ancestors:
+ - ancestorRef:
+ group: "gateway.networking.k8s.io"
+ kind: "Gateway"
+ namespace: "default"
+ name: "foobar"
+ name: "first-policy"
+ namespace: "default"
+ jsonPatches:
+ - type: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment"
+ name: second-listener
+ operation:
+ op: add
+ value:
+ clusterName: second-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 4.5.6.7
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: second-route-dest/backend/0
+http:
+- name: "first-listener"
+ address: "0.0.0.0"
+ port: 10080
+ hostnames:
+ - "*"
+ path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+ tls:
+ alpnProtocols:
+ - h2
+ - http/1.1
+ certificates:
+ - name: secret-1
+ # byte slice representation of "key-data"
+ serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97]
+ # byte slice representation of "key-data"
+ privateKey: [107, 101, 121, 45, 100, 97, 116, 97]
+ - name: secret-2
+ serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97]
+ privateKey: [107, 101, 121, 45, 100, 97, 116, 97]
+ routes:
+ - name: "first-route"
+ hostname: "*"
+ headerMatches:
+ - name: user
+ stringMatch:
+ exact: "jason"
+ destination:
+ name: "first-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
diff --git a/internal/xds/translator/testdata/in/xds-ir/jsonpatch-with-jsonpath.yaml b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-with-jsonpath.yaml
new file mode 100644
index 00000000000..a02cad99d67
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/jsonpatch-with-jsonpath.yaml
@@ -0,0 +1,172 @@
+envoyPatchPolicies:
+- status:
+ ancestors:
+ - ancestorRef:
+ group: "gateway.networking.k8s.io"
+ kind: "Gateway"
+ namespace: "default"
+ name: "foobar"
+ name: "first-policy"
+ namespace: "default"
+ jsonPatches:
+ - type: "type.googleapis.com/envoy.config.listener.v3.Listener"
+ name: first-listener
+ operation:
+ op: "add"
+ jsonPath: "$.filter_chains[0].filters[0].typed_config"
+ path: "/preserve_external_request_id"
+ value: true
+ - type: "type.googleapis.com/envoy.config.listener.v3.Listener"
+ name: "first-listener"
+ operation:
+ op: "add"
+ jsonPath: "filter_chains[0].filters[0].typed_config.http_filters[0]"
+ value:
+ name: "envoy.filters.http.ratelimit"
+ typed_config:
+ "@type": "type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit"
+ domain: "eg-ratelimit"
+ failure_mode_deny: true
+ timeout: 1s
+ rate_limit_service:
+ grpc_service:
+ envoy_grpc:
+ cluster_name: rate-limit-cluster
+ transport_api_version: V3
+ - type: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration"
+ name: "first-listener"
+ operation:
+ op: "add"
+ jsonPath: "virtual_hosts[0]"
+ path: "rate_limits"
+ value:
+ - actions:
+ - remote_address: {}
+ - type: "type.googleapis.com/envoy.config.route.v3.RouteConfiguration"
+ name: "first-listener"
+ operation:
+ op: "replace"
+ jsonPath: "..routes[?(@.name=='second-route')].route.upgrade_configs"
+ value:
+ - upgrade_type: CONNECT
+ connect_config:
+ {}
+ - type: "type.googleapis.com/envoy.config.cluster.v3.Cluster"
+ name: rate-limit-cluster
+ operation:
+ op: add
+ path: ""
+ value:
+ name: rate-limit-cluster
+ type: STRICT_DNS
+ connect_timeout: 10s
+ lb_policy: ROUND_ROBIN
+ http2_protocol_options: {}
+ load_assignment:
+ cluster_name: rate-limit-cluster
+ endpoints:
+ - lb_endpoints:
+ - endpoint:
+ address:
+ socket_address:
+ address: ratelimit.svc.cluster.local
+ port_value: 8081
+ - type: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment"
+ name: "first-route-dest"
+ operation:
+ op: "replace"
+ jsonPath: "..endpoints[*].load_balancing_weight"
+ value: "50"
+ - type: "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
+ name: "secret-1"
+ operation:
+ op: "replace"
+ jsonPath: "$.tls_certificate.certificate_chain.inline_bytes"
+ value: "a2V5LWRhdGE="
+ - type: "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
+ name: "test-secret"
+ operation:
+ op: "add"
+ path: ""
+ value:
+ name: test_secret
+ tls_certificate:
+ certificate_chain:
+ inline_bytes: Y2VydC1kYXRh
+ - type: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment"
+ name: "first-route-dest"
+ operation:
+ op: add
+ jsonPath: "endpoints"
+ path: "/1"
+ value:
+ lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ - type: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment"
+ name: "first-route-dest"
+ operation:
+ op: "move"
+ from: "/endpoints/0/load_balancing_weight"
+ path: "/endpoints/1/load_balancing_weight"
+ - type: "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment"
+ name: "first-route-dest"
+ operation:
+ op: copy
+ from: "/endpoints/1/load_balancing_weight"
+ path: "/endpoints/0/load_balancing_weight"
+http:
+- name: "first-listener"
+ address: "0.0.0.0"
+ port: 10080
+ hostnames:
+ - "*"
+ path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+ tls:
+ alpnProtocols:
+ - h2
+ - http/1.1
+ certificates:
+ - name: secret-1
+ # byte slice representation of "key-data"
+ serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97]
+ # byte slice representation of "key-data"
+ privateKey: [107, 101, 121, 45, 100, 97, 116, 97]
+ - name: secret-2
+ serverCertificate: [99, 101, 114, 116, 45, 100, 97, 116, 97]
+ privateKey: [107, 101, 121, 45, 100, 97, 116, 97]
+ routes:
+ - name: "first-route"
+ hostname: "*"
+ headerMatches:
+ - name: user
+ stringMatch:
+ exact: "jason"
+ destination:
+ name: "first-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ - name: "second-route"
+ hostname: "*"
+ headerMatches:
+ - name: user
+ stringMatch:
+ exact: "james"
+ - name: country
+ stringMatch:
+ exact: "US"
+ destination:
+ name: "second-route-dest"
+ settings:
+ - endpoints:
+ - host: "4.5.6.7"
+ port: 60000
+
diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing.yaml
index 0f3555524ff..2bd8aff1b7d 100644
--- a/internal/xds/translator/testdata/in/xds-ir/tracing.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/tracing.yaml
@@ -25,6 +25,27 @@ tracing:
- host: "otel-collector.default.svc.cluster.local"
port: 4317
protocol: "GRPC"
+ traffic:
+ backendConnection:
+ bufferLimit: 20971520
+ circuitBreaker:
+ maxConnections: 2048
+ healthCheck:
+ passive:
+ baseEjectionTime: 30s
+ consecutiveGatewayErrors: 4
+ consecutive5XxErrors: 5
+ consecutiveLocalOriginFailures: 5
+ interval: 5s
+ maxEjectionPercent: 10
+ splitExternalLocalOriginErrors: false
+ proxyProtocol:
+ version: V2
+ tcpKeepalive:
+ probes: 7
+ timeout:
+ tcp:
+ connectTimeout: 15s
provider:
host: otel-collector.monitoring.svc.cluster.local
port: 4317
diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-als-tcp.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-als-tcp.clusters.yaml
index 9603f302b73..be515fc1afb 100755
--- a/internal/xds/translator/testdata/out/xds-ir/accesslog-als-tcp.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-als-tcp.clusters.yaml
@@ -1,9 +1,10 @@
- circuitBreakers:
thresholds:
- - maxRetries: 1024
+ - maxConnections: 2048
+ maxRetries: 1024
commonLbConfig:
localityWeightedLbConfig: {}
- connectTimeout: 10s
+ connectTimeout: 15s
dnsLookupFamily: V4_ONLY
edsClusterConfig:
edsConfig:
@@ -12,8 +13,24 @@
serviceName: accesslog/monitoring/envoy-als/port/9000
lbPolicy: LEAST_REQUEST
name: accesslog/monitoring/envoy-als/port/9000
- outlierDetection: {}
- perConnectionBufferLimitBytes: 32768
+ outlierDetection:
+ baseEjectionTime: 30s
+ consecutive5xx: 5
+ consecutiveGatewayFailure: 4
+ consecutiveLocalOriginFailure: 5
+ interval: 5s
+ maxEjectionPercent: 10
+ perConnectionBufferLimitBytes: 20971520
+ transportSocket:
+ name: envoy.transport_sockets.upstream_proxy_protocol
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.proxy_protocol.v3.ProxyProtocolUpstreamTransport
+ config:
+ version: V2
+ transportSocket:
+ name: envoy.transport_sockets.raw_buffer
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.raw_buffer.v3.RawBuffer
type: EDS
typedExtensionProtocolOptions:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -22,3 +39,6 @@
http2ProtocolOptions:
initialConnectionWindowSize: 1048576
initialStreamWindowSize: 65536
+ upstreamConnectionOptions:
+ tcpKeepalive:
+ keepaliveProbes: 7
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-priority.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-priority.clusters.yaml
new file mode 100644
index 00000000000..b6f2821b650
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-priority.clusters.yaml
@@ -0,0 +1,99 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-1/rule/0
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-1/rule/0
+ outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-2/rule/0
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-2/rule/0
+ outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: envoyextensionpolicy/default/policy-for-http-route/0
+ lbPolicy: LEAST_REQUEST
+ name: envoyextensionpolicy/default/policy-for-http-route/0
+ outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ transportSocketMatches:
+ - match:
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/0
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/0
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ combinedValidationContext:
+ defaultValidationContext:
+ matchTypedSubjectAltNames:
+ - matcher:
+ exact: grpc-backend
+ sanType: DNS
+ validationContextSdsSecretConfig:
+ name: policy-btls-grpc/envoy-gateway-ca
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ sni: grpc-backend
+ - match:
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/3
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/3
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ combinedValidationContext:
+ defaultValidationContext:
+ matchTypedSubjectAltNames:
+ - matcher:
+ exact: ip-backend
+ sanType: DNS
+ validationContextSdsSecretConfig:
+ name: policy-btls-backend-ip/envoy-gateway-ca
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ sni: ip-backend
+ type: EDS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-priority.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-priority.endpoints.yaml
new file mode 100644
index 00000000000..30f113b0a73
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-priority.endpoints.yaml
@@ -0,0 +1,66 @@
+- clusterName: httproute/default/httproute-1/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-1/rule/0/backend/0
+- clusterName: httproute/default/httproute-2/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-2/rule/0/backend/0
+- clusterName: envoyextensionpolicy/default/policy-for-http-route/0
+ endpoints:
+ - loadBalancingWeight: 1
+ locality:
+ region: envoyextensionpolicy/default/policy-for-http-route/0/backend/0
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 8.8.8.8
+ portValue: 9000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: envoyextensionpolicy/default/policy-for-http-route/0/backend/1
+ priority: 1
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.1.1.1
+ portValue: 3001
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: envoyextensionpolicy/default/policy-for-http-route/0/backend/2
+ priority: 1
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 2.2.2.2
+ portValue: 3443
+ loadBalancingWeight: 1
+ metadata:
+ filterMetadata:
+ envoy.transport_socket_match:
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/3
+ loadBalancingWeight: 1
+ locality:
+ region: envoyextensionpolicy/default/policy-for-http-route/0/backend/3
+ priority: 1
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-priority.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-priority.listeners.yaml
new file mode 100644
index 00000000000..7ed44e9e2bf
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-priority.listeners.yaml
@@ -0,0 +1,49 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - disabled: true
+ name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor
+ grpcService:
+ envoyGrpc:
+ authority: grpc-backend.envoy-gateway:8000
+ clusterName: envoyextensionpolicy/default/policy-for-http-route/0
+ timeout: 10s
+ processingMode:
+ requestHeaderMode: SKIP
+ requestTrailerMode: SKIP
+ responseHeaderMode: SKIP
+ responseTrailerMode: SKIP
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: default/gateway-1/http
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: default/gateway-1/http
+ drainType: MODIFY_ONLY
+ name: default/gateway-1/http
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-priority.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-priority.routes.yaml
new file mode 100644
index 00000000000..e5e50ccde27
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-priority.routes.yaml
@@ -0,0 +1,59 @@
+- ignorePortInHostMatching: true
+ name: default/gateway-1/http
+ virtualHosts:
+ - domains:
+ - www.foo.com
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http/www_foo_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /foo
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ route:
+ cluster: httproute/default/httproute-1/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ - domains:
+ - www.bar.com
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http/www_bar_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /bar
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ route:
+ cluster: httproute/default/httproute-2/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-priority.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-priority.secrets.yaml
new file mode 100644
index 00000000000..387926a79f3
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-priority.secrets.yaml
@@ -0,0 +1,8 @@
+- name: policy-btls-grpc/envoy-gateway-ca
+ validationContext:
+ trustedCa:
+ inlineBytes: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+- name: policy-btls-backend-ip/envoy-gateway-ca
+ validationContext:
+ trustedCa:
+ inlineBytes: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.clusters.yaml
new file mode 100644
index 00000000000..880f77a06f0
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.clusters.yaml
@@ -0,0 +1,112 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-1/rule/0
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-1/rule/0
+ outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-1/rule/1
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-1/rule/1
+ outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-2/rule/0
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-2/rule/0
+ outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: primary.foo.com
+ portValue: 9000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: securitypolicy/default/policy-for-http-route-1/default/grpc-backend/backend/0
+ name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ type: STRICT_DNS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ dnsRefreshRate: 30s
+ lbPolicy: LEAST_REQUEST
+ loadAssignment:
+ clusterName: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: primary.foo.com
+ portValue: 80
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend/backend/0
+ name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ respectDnsTtl: true
+ type: STRICT_DNS
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.endpoints.yaml
new file mode 100644
index 00000000000..bf9f0023789
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.endpoints.yaml
@@ -0,0 +1,36 @@
+- clusterName: httproute/default/httproute-1/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-1/rule/0/backend/0
+- clusterName: httproute/default/httproute-1/rule/1
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-1/rule/1/backend/0
+- clusterName: httproute/default/httproute-2/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-2/rule/0/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.listeners.yaml
new file mode 100644
index 00000000000..c60348a3b91
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.listeners.yaml
@@ -0,0 +1,70 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - disabled: true
+ name: envoy.filters.http.ext_authz/securitypolicy/default/policy-for-http-route-1
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
+ allowedHeaders:
+ patterns:
+ - exact: header1
+ ignoreCase: true
+ - exact: header2
+ ignoreCase: true
+ grpcService:
+ envoyGrpc:
+ authority: primary.foo.com
+ clusterName: securitypolicy/default/policy-for-http-route-1/default/grpc-backend
+ timeout: 10s
+ transportApiVersion: V3
+ - disabled: true
+ name: envoy.filters.http.ext_authz/securitypolicy/default/policy-for-gateway-1
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
+ failureModeAllow: true
+ httpService:
+ authorizationResponse:
+ allowedUpstreamHeaders:
+ patterns:
+ - exact: header1
+ ignoreCase: true
+ - exact: header2
+ ignoreCase: true
+ pathPrefix: /auth
+ serverUri:
+ cluster: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend
+ timeout: 10s
+ uri: http://primary.foo.com/auth
+ transportApiVersion: V3
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: default/gateway-1/http
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: default/gateway-1/http
+ drainType: MODIFY_ONLY
+ name: default/gateway-1/http
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.routes.yaml
new file mode 100644
index 00000000000..08edfc3c406
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.routes.yaml
@@ -0,0 +1,44 @@
+- ignorePortInHostMatching: true
+ name: default/gateway-1/http
+ virtualHosts:
+ - domains:
+ - www.foo.com
+ name: default/gateway-1/http/www_foo_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /foo1
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ route:
+ cluster: httproute/default/httproute-1/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.ext_authz/securitypolicy/default/policy-for-http-route-1:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ - match:
+ pathSeparatedPrefix: /foo2
+ name: httproute/default/httproute-1/rule/1/match/0/www_foo_com
+ route:
+ cluster: httproute/default/httproute-1/rule/1
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.ext_authz/securitypolicy/default/policy-for-http-route-1:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ - domains:
+ - www.bar.com
+ name: default/gateway-1/http/www_bar_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /bar
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ route:
+ cluster: httproute/default/httproute-2/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.ext_authz/securitypolicy/default/policy-for-gateway-1:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.clusters.yaml
new file mode 100644
index 00000000000..4e73328fa8e
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.clusters.yaml
@@ -0,0 +1,135 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-1/rule/0
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-1/rule/0
+ outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: httproute/default/httproute-2/rule/0
+ lbPolicy: LEAST_REQUEST
+ name: httproute/default/httproute-2/rule/0
+ outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxConnections: 2048
+ maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 15s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: envoyextensionpolicy/default/policy-for-http-route/0
+ name: envoyextensionpolicy/default/policy-for-http-route/0
+ outlierDetection:
+ baseEjectionTime: 30s
+ consecutive5xx: 5
+ consecutiveGatewayFailure: 4
+ consecutiveLocalOriginFailure: 5
+ interval: 5s
+ maxEjectionPercent: 10
+ perConnectionBufferLimitBytes: 20971520
+ roundRobinLbConfig:
+ slowStartConfig:
+ slowStartWindow: 5s
+ transportSocket:
+ name: envoy.transport_sockets.upstream_proxy_protocol
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.proxy_protocol.v3.ProxyProtocolUpstreamTransport
+ config:
+ version: V2
+ transportSocket:
+ name: envoy.transport_sockets.raw_buffer
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.raw_buffer.v3.RawBuffer
+ transportSocketMatches:
+ - match:
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/0
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/0
+ transportSocket:
+ name: envoy.transport_sockets.upstream_proxy_protocol
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.proxy_protocol.v3.ProxyProtocolUpstreamTransport
+ config:
+ version: V2
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ combinedValidationContext:
+ defaultValidationContext:
+ matchTypedSubjectAltNames:
+ - matcher:
+ exact: grpc-backend
+ sanType: DNS
+ validationContextSdsSecretConfig:
+ name: policy-btls-grpc/envoy-gateway-ca
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ sni: grpc-backend
+ - match:
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/3
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/3
+ transportSocket:
+ name: envoy.transport_sockets.upstream_proxy_protocol
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.proxy_protocol.v3.ProxyProtocolUpstreamTransport
+ config:
+ version: V2
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ commonTlsContext:
+ combinedValidationContext:
+ defaultValidationContext:
+ matchTypedSubjectAltNames:
+ - matcher:
+ exact: ip-backend
+ sanType: DNS
+ validationContextSdsSecretConfig:
+ name: policy-btls-backend-ip/envoy-gateway-ca
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ sni: ip-backend
+ type: EDS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 2097152
+ initialStreamWindowSize: 131072
+ maxConcurrentStreams: 200
+ overrideStreamErrorOnInvalidHttpMessage: true
+ upstreamConnectionOptions:
+ tcpKeepalive:
+ keepaliveProbes: 7
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.endpoints.yaml
new file mode 100644
index 00000000000..a3d4fd4dc11
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.endpoints.yaml
@@ -0,0 +1,63 @@
+- clusterName: httproute/default/httproute-1/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-1/rule/0/backend/0
+- clusterName: httproute/default/httproute-2/rule/0
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 7.7.7.7
+ portValue: 8080
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: httproute/default/httproute-2/rule/0/backend/0
+- clusterName: envoyextensionpolicy/default/policy-for-http-route/0
+ endpoints:
+ - loadBalancingWeight: 1
+ locality:
+ region: envoyextensionpolicy/default/policy-for-http-route/0/backend/0
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 8.8.8.8
+ portValue: 9000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: envoyextensionpolicy/default/policy-for-http-route/0/backend/1
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.1.1.1
+ portValue: 3001
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: envoyextensionpolicy/default/policy-for-http-route/0/backend/2
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 2.2.2.2
+ portValue: 3443
+ loadBalancingWeight: 1
+ metadata:
+ filterMetadata:
+ envoy.transport_socket_match:
+ name: envoyextensionpolicy/default/policy-for-http-route/0/tls/3
+ loadBalancingWeight: 1
+ locality:
+ region: envoyextensionpolicy/default/policy-for-http-route/0/backend/3
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.listeners.yaml
new file mode 100644
index 00000000000..7ed44e9e2bf
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.listeners.yaml
@@ -0,0 +1,49 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - disabled: true
+ name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor
+ grpcService:
+ envoyGrpc:
+ authority: grpc-backend.envoy-gateway:8000
+ clusterName: envoyextensionpolicy/default/policy-for-http-route/0
+ timeout: 10s
+ processingMode:
+ requestHeaderMode: SKIP
+ requestTrailerMode: SKIP
+ responseHeaderMode: SKIP
+ responseTrailerMode: SKIP
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: default/gateway-1/http
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: default/gateway-1/http
+ drainType: MODIFY_ONLY
+ name: default/gateway-1/http
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.routes.yaml
new file mode 100644
index 00000000000..e5e50ccde27
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.routes.yaml
@@ -0,0 +1,59 @@
+- ignorePortInHostMatching: true
+ name: default/gateway-1/http
+ virtualHosts:
+ - domains:
+ - www.foo.com
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http/www_foo_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /foo
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/www_foo_com
+ route:
+ cluster: httproute/default/httproute-1/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ - domains:
+ - www.bar.com
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: Gateway
+ name: gateway-1
+ namespace: default
+ sectionName: http
+ name: default/gateway-1/http/www_bar_com
+ routes:
+ - match:
+ pathSeparatedPrefix: /bar
+ metadata:
+ filterMetadata:
+ envoy-gateway:
+ resources:
+ - kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/www_bar_com
+ route:
+ cluster: httproute/default/httproute-2/rule/0
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.secrets.yaml
new file mode 100644
index 00000000000..387926a79f3
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.secrets.yaml
@@ -0,0 +1,8 @@
+- name: policy-btls-grpc/envoy-gateway-ca
+ validationContext:
+ trustedCa:
+ inlineBytes: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
+- name: policy-btls-backend-ip/envoy-gateway-ca
+ validationContext:
+ trustedCa:
+ inlineBytes: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
diff --git a/internal/xds/translator/testdata/out/xds-ir/health-check.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/health-check.clusters.yaml
index b789b876c3c..485139eb2c8 100644
--- a/internal/xds/translator/testdata/out/xds-ir/health-check.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/health-check.clusters.yaml
@@ -139,3 +139,27 @@
splitExternalLocalOriginErrors: true
perConnectionBufferLimitBytes: 32768
type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: fifth-route-dest
+ healthChecks:
+ - grpcHealthCheck:
+ serviceName: my-service
+ healthyThreshold: 3
+ interval: 5s
+ timeout: 1s
+ unhealthyThreshold: 3
+ lbPolicy: LEAST_REQUEST
+ name: fifth-route-dest
+ outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/health-check.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/health-check.endpoints.yaml
index f185af17da7..b93d9b43bde 100644
--- a/internal/xds/translator/testdata/out/xds-ir/health-check.endpoints.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/health-check.endpoints.yaml
@@ -46,3 +46,15 @@
loadBalancingWeight: 1
locality:
region: fourth-route-dest/backend/0
+- clusterName: fifth-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: fifth-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/health-check.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/health-check.routes.yaml
index de4249178e4..2f5c4977b24 100644
--- a/internal/xds/translator/testdata/out/xds-ir/health-check.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/health-check.routes.yaml
@@ -33,3 +33,10 @@
cluster: fourth-route-dest
upgradeConfigs:
- upgradeType: websocket
+ - match:
+ prefix: /
+ name: fifth-route
+ route:
+ cluster: fifth-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.clusters.yaml
new file mode 100644
index 00000000000..22e6727066a
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.clusters.yaml
@@ -0,0 +1,44 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: first-route-dest
+ lbPolicy: LEAST_REQUEST
+ name: first-route-dest
+ outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+ typedExtensionProtocolOptions:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicitHttpConfig:
+ httpProtocolOptions:
+ headerKeyFormat:
+ statefulFormatter:
+ name: preserve_case
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.http.header_formatters.preserve_case.v3.PreserveCaseFormatterConfig
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: second-route-dest
+ lbPolicy: LEAST_REQUEST
+ name: second-route-dest
+ outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.endpoints.yaml
new file mode 100644
index 00000000000..28a57caf3b5
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.endpoints.yaml
@@ -0,0 +1,24 @@
+- clusterName: first-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: first-route-dest/backend/0
+- clusterName: second-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.5
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: second-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.listeners.yaml
new file mode 100644
index 00000000000..69c2612a5f8
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.listeners.yaml
@@ -0,0 +1,108 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ httpProtocolOptions:
+ headerKeyFormat:
+ statefulFormatter:
+ name: preserve_case
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.http.header_formatters.preserve_case.v3.PreserveCaseFormatterConfig
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: first-listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: first-listener
+ drainType: MODIFY_ONLY
+ name: first-listener
+ perConnectionBufferLimitBytes: 32768
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10081
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ earlyHeaderMutationExtensions:
+ - name: envoy.http.early_header_mutation.header_mutation
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.http.early_header_mutation.header_mutation.v3.HeaderMutation
+ mutations:
+ - append:
+ header:
+ key: some-header
+ value: some-value1
+ - append:
+ header:
+ key: some-header
+ value: some-value2
+ - append:
+ header:
+ key: some-header-2
+ value: some-value
+ - append:
+ appendAction: OVERWRITE_IF_EXISTS_OR_ADD
+ header:
+ key: some-header3
+ value: some-value
+ - append:
+ appendAction: OVERWRITE_IF_EXISTS_OR_ADD
+ header:
+ key: some-header4
+ value: some-value
+ - append:
+ appendAction: OVERWRITE_IF_EXISTS_OR_ADD
+ header:
+ key: empty-header
+ keepEmptyValue: true
+ - remove: some-header5
+ - remove: some-header6
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ normalizePath: true
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: second-listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10081
+ useRemoteAddress: true
+ name: second-listener
+ drainType: MODIFY_ONLY
+ name: second-listener
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.routes.yaml
new file mode 100644
index 00000000000..ff93cfff360
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-early-header-mutation.routes.yaml
@@ -0,0 +1,28 @@
+- ignorePortInHostMatching: true
+ name: first-listener
+ virtualHosts:
+ - domains:
+ - '*'
+ name: first-listener/*
+ routes:
+ - match:
+ prefix: /
+ name: first-route
+ route:
+ cluster: first-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+- ignorePortInHostMatching: true
+ name: second-listener
+ virtualHosts:
+ - domains:
+ - '*'
+ name: second-listener/*
+ routes:
+ - match:
+ prefix: /
+ name: second-route
+ route:
+ cluster: second-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-request-headers.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-request-headers.routes.yaml
index f91a70cb2ee..1f2c6be4057 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-request-headers.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-request-headers.routes.yaml
@@ -9,6 +9,12 @@
prefix: /
name: request-header-route
requestHeadersToAdd:
+ - header:
+ key: some-header-multi-value
+ value: some-value
+ - header:
+ key: some-header-multi-value
+ value: some-additional-value
- header:
key: some-header
value: some-value
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.clusters.yaml
new file mode 100644
index 00000000000..0f75e67e278
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.clusters.yaml
@@ -0,0 +1,17 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: regex-route-dest
+ lbPolicy: LEAST_REQUEST
+ name: regex-route-dest
+ outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.endpoints.yaml
new file mode 100644
index 00000000000..b36ee450059
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.endpoints.yaml
@@ -0,0 +1,12 @@
+- clusterName: regex-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: regex-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.listeners.yaml
new file mode 100644
index 00000000000..f29e11a27a4
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.listeners.yaml
@@ -0,0 +1,80 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ defaultFilterChain:
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - disabled: true
+ name: envoy.filters.http.stateful_session/header-based-session-persistence-route
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSession
+ sessionState:
+ name: envoy.http.stateful_session.header
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.http.stateful_session.header.v3.HeaderBasedSessionState
+ name: session-header
+ - disabled: true
+ name: envoy.filters.http.stateful_session/cookie-based-session-persistence-route-regex
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSession
+ sessionState:
+ name: envoy.http.stateful_session.cookie
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.http.stateful_session.cookie.v3.CookieBasedSessionState
+ cookie:
+ name: session-header
+ path: /v1
+ ttl: 3600s
+ - disabled: true
+ name: envoy.filters.http.stateful_session/cookie-based-session-persistence-route-prefix
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSession
+ sessionState:
+ name: envoy.http.stateful_session.cookie
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.http.stateful_session.cookie.v3.CookieBasedSessionState
+ cookie:
+ name: session-header
+ path: /v2/
+ ttl: 3600s
+ - disabled: true
+ name: envoy.filters.http.stateful_session/cookie-based-session-persistence-route-exact
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSession
+ sessionState:
+ name: envoy.http.stateful_session.cookie
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.http.stateful_session.cookie.v3.CookieBasedSessionState
+ cookie:
+ name: session-cookie
+ path: /v3/user
+ ttl: 3600s
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: first-listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: http-10080
+ useRemoteAddress: true
+ name: first-listener
+ drainType: MODIFY_ONLY
+ name: first-listener
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.routes.yaml
new file mode 100644
index 00000000000..c5450601be4
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.routes.yaml
@@ -0,0 +1,53 @@
+- ignorePortInHostMatching: true
+ name: first-listener
+ virtualHosts:
+ - domains:
+ - '*'
+ name: first-listener/*
+ routes:
+ - match:
+ safeRegex:
+ regex: /v1/.*
+ name: header-based-session-persistence-route
+ route:
+ cluster: regex-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.stateful_session/header-based-session-persistence-route:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ - match:
+ safeRegex:
+ regex: /v1/.*/hoge
+ name: cookie-based-session-persistence-route-regex
+ route:
+ cluster: regex-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.stateful_session/cookie-based-session-persistence-route-regex:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ - match:
+ pathSeparatedPrefix: /v2
+ name: cookie-based-session-persistence-route-prefix
+ route:
+ cluster: regex-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.stateful_session/cookie-based-session-persistence-route-prefix:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
+ - match:
+ path: /v3/user
+ name: cookie-based-session-persistence-route-exact
+ route:
+ cluster: regex-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+ typedPerFilterConfig:
+ envoy.filters.http.stateful_session/cookie-based-session-persistence-route-exact:
+ '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
+ config: {}
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.clusters.yaml
new file mode 100644
index 00000000000..d53a7a1b2ce
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.clusters.yaml
@@ -0,0 +1,17 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: first-route-dest
+ lbPolicy: LEAST_REQUEST
+ name: first-route-dest
+ outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.endpoints.yaml
new file mode 100644
index 00000000000..9a6f5a46c91
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.endpoints.yaml
@@ -0,0 +1,24 @@
+- clusterName: first-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: first-route-dest/backend/0
+- clusterName: second-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 4.5.6.7
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: second-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.envoypatchpolicies.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.envoypatchpolicies.yaml
new file mode 100644
index 00000000000..9508dd3e7b3
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.envoypatchpolicies.yaml
@@ -0,0 +1,16 @@
+- name: first-policy
+ namespace: default
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: foobar
+ namespace: default
+ conditions:
+ - lastTransitionTime: null
+ message: Patches have been successfully applied.
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ controllerName: ""
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.listeners.yaml
new file mode 100644
index 00000000000..51c022c26f3
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.listeners.yaml
@@ -0,0 +1,52 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ drainType: MODIFY_ONLY
+ filterChains:
+ - filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: first-listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: https-10080
+ useRemoteAddress: true
+ name: first-listener
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
+ commonTlsContext:
+ alpnProtocols:
+ - h2
+ - http/1.1
+ tlsCertificateSdsSecretConfigs:
+ - name: secret-1
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ - name: secret-2
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ name: first-listener
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.routes.yaml
new file mode 100644
index 00000000000..4a412b3576a
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.routes.yaml
@@ -0,0 +1,18 @@
+- ignorePortInHostMatching: true
+ name: first-listener
+ virtualHosts:
+ - domains:
+ - '*'
+ name: first-listener/*
+ routes:
+ - match:
+ headers:
+ - name: user
+ stringMatch:
+ exact: jason
+ prefix: /
+ name: first-route
+ route:
+ cluster: first-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.secrets.yaml
new file mode 100644
index 00000000000..ad88ffe43cd
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-add-op-empty-jsonpath.secrets.yaml
@@ -0,0 +1,12 @@
+- name: secret-1
+ tlsCertificate:
+ certificateChain:
+ inlineBytes: Y2VydC1kYXRh
+ privateKey:
+ inlineBytes: a2V5LWRhdGE=
+- name: secret-2
+ tlsCertificate:
+ certificateChain:
+ inlineBytes: Y2VydC1kYXRh
+ privateKey:
+ inlineBytes: a2V5LWRhdGE=
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.clusters.yaml
new file mode 100644
index 00000000000..b3842b6e52e
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.clusters.yaml
@@ -0,0 +1,47 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: first-route-dest
+ lbPolicy: LEAST_REQUEST
+ name: first-route-dest
+ outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig:
+ localityWeightedLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_ONLY
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: second-route-dest
+ lbPolicy: LEAST_REQUEST
+ name: second-route-dest
+ outlierDetection: {}
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- connectTimeout: 10s
+ http2ProtocolOptions: {}
+ loadAssignment:
+ clusterName: rate-limit-cluster
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: ratelimit.svc.cluster.local
+ portValue: 8081
+ name: rate-limit-cluster
+ type: STRICT_DNS
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.endpoints.yaml
new file mode 100644
index 00000000000..131cd47c730
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.endpoints.yaml
@@ -0,0 +1,32 @@
+- clusterName: first-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 50
+ locality:
+ region: first-route-dest/backend/0
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 1.2.3.4
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 50
+- clusterName: second-route-dest
+ endpoints:
+ - lbEndpoints:
+ - endpoint:
+ address:
+ socketAddress:
+ address: 4.5.6.7
+ portValue: 60000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: second-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.envoypatchpolicies.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.envoypatchpolicies.yaml
new file mode 100644
index 00000000000..9508dd3e7b3
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.envoypatchpolicies.yaml
@@ -0,0 +1,16 @@
+- name: first-policy
+ namespace: default
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: foobar
+ namespace: default
+ conditions:
+ - lastTransitionTime: null
+ message: Patches have been successfully applied.
+ reason: Programmed
+ status: "True"
+ type: Programmed
+ controllerName: ""
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.listeners.yaml
new file mode 100644
index 00000000000..08b5d410df5
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.listeners.yaml
@@ -0,0 +1,64 @@
+- address:
+ socketAddress:
+ address: 0.0.0.0
+ portValue: 10080
+ drainType: MODIFY_ONLY
+ filterChains:
+ - filters:
+ - name: envoy.filters.network.http_connection_manager
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+ commonHttpProtocolOptions:
+ headersWithUnderscoresAction: REJECT_REQUEST
+ http2ProtocolOptions:
+ initialConnectionWindowSize: 1048576
+ initialStreamWindowSize: 65536
+ maxConcurrentStreams: 100
+ httpFilters:
+ - name: envoy.filters.http.ratelimit
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
+ domain: eg-ratelimit
+ failureModeDeny: true
+ rateLimitService:
+ grpcService:
+ envoyGrpc:
+ clusterName: rate-limit-cluster
+ transportApiVersion: V3
+ timeout: 1s
+ - name: envoy.filters.http.router
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ suppressEnvoyHeaders: true
+ mergeSlashes: true
+ normalizePath: true
+ pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+ preserveExternalRequestId: true
+ rds:
+ configSource:
+ ads: {}
+ resourceApiVersion: V3
+ routeConfigName: first-listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: https-10080
+ useRemoteAddress: true
+ name: first-listener
+ transportSocket:
+ name: envoy.transport_sockets.tls
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
+ commonTlsContext:
+ alpnProtocols:
+ - h2
+ - http/1.1
+ tlsCertificateSdsSecretConfigs:
+ - name: secret-1
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ - name: secret-2
+ sdsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ name: first-listener
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.routes.yaml
new file mode 100644
index 00000000000..a7273c7a1b8
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.routes.yaml
@@ -0,0 +1,36 @@
+- ignorePortInHostMatching: true
+ name: first-listener
+ virtualHosts:
+ - domains:
+ - '*'
+ name: first-listener/*
+ rateLimits:
+ - actions:
+ - remoteAddress: {}
+ routes:
+ - match:
+ headers:
+ - name: user
+ stringMatch:
+ exact: jason
+ prefix: /
+ name: first-route
+ route:
+ cluster: first-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+ - match:
+ headers:
+ - name: user
+ stringMatch:
+ exact: james
+ - name: country
+ stringMatch:
+ exact: US
+ prefix: /
+ name: second-route
+ route:
+ cluster: second-route-dest
+ upgradeConfigs:
+ - connectConfig: {}
+ upgradeType: CONNECT
diff --git a/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.secrets.yaml
new file mode 100644
index 00000000000..d1c4b32fd5f
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/jsonpatch-with-jsonpath.secrets.yaml
@@ -0,0 +1,16 @@
+- name: secret-1
+ tlsCertificate:
+ certificateChain:
+ inlineBytes: a2V5LWRhdGE=
+ privateKey:
+ inlineBytes: a2V5LWRhdGE=
+- name: secret-2
+ tlsCertificate:
+ certificateChain:
+ inlineBytes: Y2VydC1kYXRh
+ privateKey:
+ inlineBytes: a2V5LWRhdGE=
+- name: test_secret
+ tlsCertificate:
+ certificateChain:
+ inlineBytes: Y2VydC1kYXRh
diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml
index dce48b2c083..4d419611516 100644
--- a/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml
@@ -17,10 +17,11 @@
type: EDS
- circuitBreakers:
thresholds:
- - maxRetries: 1024
+ - maxConnections: 2048
+ maxRetries: 1024
commonLbConfig:
localityWeightedLbConfig: {}
- connectTimeout: 10s
+ connectTimeout: 15s
dnsLookupFamily: V4_ONLY
dnsRefreshRate: 30s
lbPolicy: LEAST_REQUEST
@@ -38,9 +39,25 @@
locality:
region: tracing-0/backend/0
name: tracing-0
- outlierDetection: {}
- perConnectionBufferLimitBytes: 32768
+ outlierDetection:
+ baseEjectionTime: 30s
+ consecutive5xx: 5
+ consecutiveGatewayFailure: 4
+ consecutiveLocalOriginFailure: 5
+ interval: 5s
+ maxEjectionPercent: 10
+ perConnectionBufferLimitBytes: 20971520
respectDnsTtl: true
+ transportSocket:
+ name: envoy.transport_sockets.upstream_proxy_protocol
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.proxy_protocol.v3.ProxyProtocolUpstreamTransport
+ config:
+ version: V2
+ transportSocket:
+ name: envoy.transport_sockets.raw_buffer
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.transport_sockets.raw_buffer.v3.RawBuffer
type: STRICT_DNS
typedExtensionProtocolOptions:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -49,3 +66,6 @@
http2ProtocolOptions:
initialConnectionWindowSize: 1048576
initialStreamWindowSize: 65536
+ upstreamConnectionOptions:
+ tcpKeepalive:
+ keepaliveProbes: 7
diff --git a/internal/xds/translator/tracing.go b/internal/xds/translator/tracing.go
index b2a52ec6a18..ad9a3ecc0e1 100644
--- a/internal/xds/translator/tracing.go
+++ b/internal/xds/translator/tracing.go
@@ -160,12 +160,26 @@ func processClusterForTracing(tCtx *types.ResourceVersionTable, tracing *ir.Trac
return nil
}
+ traffic := tracing.Traffic
+ // Make sure that there are safe defaults for the traffic
+ if traffic == nil {
+ traffic = &ir.TrafficFeatures{}
+ }
if err := addXdsCluster(tCtx, &xdsClusterArgs{
- name: tracing.Destination.Name,
- settings: tracing.Destination.Settings,
- tSocket: nil,
- endpointType: EndpointTypeDNS,
- metrics: metrics,
+ name: tracing.Destination.Name,
+ settings: tracing.Destination.Settings,
+ tSocket: nil,
+ endpointType: EndpointTypeDNS,
+ metrics: metrics,
+ loadBalancer: traffic.LoadBalancer,
+ proxyProtocol: traffic.ProxyProtocol,
+ circuitBreaker: traffic.CircuitBreaker,
+ healthCheck: traffic.HealthCheck,
+ timeout: traffic.Timeout,
+ tcpkeepalive: traffic.TCPKeepalive,
+ backendConnection: traffic.BackendConnection,
+ dns: traffic.DNS,
+ http2Settings: traffic.HTTP2,
}); err != nil && !errors.Is(err, ErrXdsClusterExists) {
return err
}
diff --git a/internal/xds/translator/translator_test.go b/internal/xds/translator/translator_test.go
index 44d6d127bca..08ab0d24b3b 100644
--- a/internal/xds/translator/translator_test.go
+++ b/internal/xds/translator/translator_test.go
@@ -55,6 +55,12 @@ func TestTranslateXds(t *testing.T) {
"jsonpatch": {
requireEnvoyPatchPolicies: true,
},
+ "jsonpatch-with-jsonpath": {
+ requireEnvoyPatchPolicies: true,
+ },
+ "jsonpatch-add-op-empty-jsonpath": {
+ requireEnvoyPatchPolicies: true,
+ },
"jsonpatch-missing-resource": {
requireEnvoyPatchPolicies: true,
},
@@ -103,7 +109,6 @@ func TestTranslateXds(t *testing.T) {
require.NoError(t, err)
for _, inputFile := range inputFiles {
- inputFile := inputFile
inputFileName := testName(inputFile)
t.Run(inputFileName, func(t *testing.T) {
cfg, ok := testConfigs[inputFileName]
@@ -127,10 +132,9 @@ func TestTranslateXds(t *testing.T) {
},
FilterOrder: x.FilterOrder,
}
-
tCtx, err := tr.Translate(x)
if !strings.HasSuffix(inputFileName, "partial-invalid") && len(cfg.errMsg) == 0 {
- t.Logf(inputFileName)
+ t.Log(inputFileName)
require.NoError(t, err)
} else if len(cfg.errMsg) > 0 {
require.Error(t, err)
@@ -187,7 +191,6 @@ func TestTranslateRateLimitConfig(t *testing.T) {
require.NoError(t, err)
for _, inputFile := range inputFiles {
- inputFile := inputFile
inputFileName := testName(inputFile)
t.Run(inputFileName, func(t *testing.T) {
in := requireXdsIRListenerFromInputTestData(t, inputFile)
@@ -217,7 +220,6 @@ func TestTranslateXdsWithExtension(t *testing.T) {
require.NoError(t, err)
for _, inputFile := range inputFiles {
- inputFile := inputFile
inputFileName := testName(inputFile)
t.Run(inputFileName, func(t *testing.T) {
cfg, ok := testConfigs[inputFileName]
diff --git a/internal/xds/translator/utils.go b/internal/xds/translator/utils.go
index 10148150865..23d455edd9c 100644
--- a/internal/xds/translator/utils.go
+++ b/internal/xds/translator/utils.go
@@ -129,13 +129,17 @@ func hcmContainsFilter(mgr *hcmv3.HttpConnectionManager, filterName string) bool
return false
}
-func createExtServiceXDSCluster(rd *ir.RouteDestination, tCtx *types.ResourceVersionTable) error {
+func createExtServiceXDSCluster(rd *ir.RouteDestination, traffic *ir.TrafficFeatures, tCtx *types.ResourceVersionTable) error {
var (
endpointType EndpointType
tSocket *corev3.TransportSocket
err error
)
+ // Make sure that there are safe defaults for the traffic
+ if traffic == nil {
+ traffic = &ir.TrafficFeatures{}
+ }
// Get the address type from the first setting.
// This is safe because no mixed address types in the settings.
addrTypeState := rd.Settings[0].AddressType
@@ -144,12 +148,20 @@ func createExtServiceXDSCluster(rd *ir.RouteDestination, tCtx *types.ResourceVer
} else {
endpointType = EndpointTypeStatic
}
-
if err = addXdsCluster(tCtx, &xdsClusterArgs{
- name: rd.Name,
- settings: rd.Settings,
- tSocket: tSocket,
- endpointType: endpointType,
+ name: rd.Name,
+ settings: rd.Settings,
+ tSocket: tSocket,
+ loadBalancer: traffic.LoadBalancer,
+ proxyProtocol: traffic.ProxyProtocol,
+ circuitBreaker: traffic.CircuitBreaker,
+ healthCheck: traffic.HealthCheck,
+ timeout: traffic.Timeout,
+ tcpkeepalive: traffic.TCPKeepalive,
+ backendConnection: traffic.BackendConnection,
+ endpointType: endpointType,
+ dns: traffic.DNS,
+ http2Settings: traffic.HTTP2,
}); err != nil && !errors.Is(err, ErrXdsClusterExists) {
return err
}
diff --git a/internal/xds/types/resourceversiontable_test.go b/internal/xds/types/resourceversiontable_test.go
index 8da1c0cc7ca..5fe96253bc8 100644
--- a/internal/xds/types/resourceversiontable_test.go
+++ b/internal/xds/types/resourceversiontable_test.go
@@ -71,7 +71,6 @@ func TestDeepCopy(t *testing.T) {
},
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
if tc.out == nil {
require.Nil(t, tc.in.DeepCopy())
@@ -531,7 +530,6 @@ func TestAddOrReplaceXdsResource(t *testing.T) {
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
err := tc.tableIn.AddOrReplaceXdsResource(tc.typeIn, tc.resourceIn, tc.funcIn)
require.NoError(t, err)
@@ -887,7 +885,6 @@ func TestInvalidAddXdsResource(t *testing.T) {
},
}
for _, tc := range testCases {
- tc := tc
t.Run(tc.name, func(t *testing.T) {
err := tc.tableIn.AddOrReplaceXdsResource(tc.typeIn, tc.resourceIn, tc.funcIn)
require.Error(t, err)
diff --git a/site/content/en/docs/boilerplates/prerequisites.md b/site/content/en/docs/boilerplates/prerequisites.md
new file mode 100644
index 00000000000..064238e4d13
--- /dev/null
+++ b/site/content/en/docs/boilerplates/prerequisites.md
@@ -0,0 +1,24 @@
+---
+---
+
+Follow the steps from the [Quickstart](../tasks/quickstart) task to install Envoy Gateway and the example manifest.
+Before proceeding, you should be able to query the example backend using HTTP.
+
+Verify the Gateway status:
+
+{{< tabpane text=true >}}
+{{% tab header="kubectl" %}}
+
+```shell
+kubectl get gateway/eg -o yaml
+```
+
+{{% /tab %}}
+{{% tab header="egctl (experimental)" %}}
+
+```shell
+egctl x status gateway -v
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
diff --git a/site/content/en/docs/concepts/concepts_overview.md b/site/content/en/docs/concepts/concepts_overview.md
index 31838b520f2..9af9a3fff10 100644
--- a/site/content/en/docs/concepts/concepts_overview.md
+++ b/site/content/en/docs/concepts/concepts_overview.md
@@ -10,13 +10,12 @@ There are several resources that play a part in enabling you to meet your Kubern
There are several resources that play a part in enabling you to meet your Kubernetes ingress traffic handling needs. This page provides a brief overview of the resources you’ll be working with.
-# Overview
-
-## Kubernetes Gateway API Resources
+### Kubernetes Gateway API Resources
- **GatewayClass:** Defines a class of Gateways with common configuration.
- **Gateway:** Specifies how traffic can enter the cluster.
- **Routes:** **HTTPRoute, GRPCRoute, TLSRoute, TCPRoute, UDPRoute:** Define routing rules for different types of traffic.
-## Envoy Gateway (EG) API Resources
+
+### Envoy Gateway (EG) API Resources
- **EnvoyProxy:** Represents the deployment and configuration of the Envoy proxy within a Kubernetes cluster, managing its lifecycle and settings.
- **EnvoyPatchPolicy, ClientTrafficPolicy, SecurityPolicy, BackendTrafficPolicy, EnvoyExtensionPolicy, BackendTLSPolicy:** Additional policies and configurations specific to Envoy Gateway.
- **Backend:** A resource that makes routing to cluster-external backends easier and makes access to external processes via Unix Domain Sockets possible.
diff --git a/site/content/en/docs/install/install-yaml.md b/site/content/en/docs/install/install-yaml.md
index e675f15fbec..c0a8d1caa72 100644
--- a/site/content/en/docs/install/install-yaml.md
+++ b/site/content/en/docs/install/install-yaml.md
@@ -13,7 +13,7 @@ installation, it is recommended that you use helm.
Envoy Gateway is designed to run in Kubernetes for production. The most essential requirements are:
-* Kubernetes 1.25 or later
+* Kubernetes 1.27 or later
* The `kubectl` command-line tool
{{% alert title="Compatibility Matrix" color="warning" %}}
@@ -37,3 +37,31 @@ Refer to the [Developer Guide](../../contributions/develop) to learn more.
2. Next Steps
Envoy Gateway should now be successfully installed and running, but in order to experience more abilities of Envoy Gateway, you can refer to [Tasks](/latest/tasks).
+
+## Upgrading from v1.0
+
+Due to breaking changes in Gateway API v1.1, some manual migration steps are required to upgrade Envoy Gateway to v1.1.
+
+1. Delete `BackendTLSPolicy` CRD (and resources):
+
+```shell
+kubectl delete crd backendtlspolicies.gateway.networking.k8s.io
+```
+
+2. Update Gateway-API and Envoy Gateway CRDs:
+
+```shell
+helm pull oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} --untar
+kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/gatewayapi-crds.yaml
+kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/generated
+```
+
+3. Update your `BackendTLSPolicy` and `GRPCRoute` resources according to Gateway-API [v1.1 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v11-upgrade-notes)
+
+4. Update your Envoy Gateway xPolicy resources: remove the namespace section from targetRef.
+
+5. Install Envoy Gateway {{< yaml-version >}}:
+
+```shell
+helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} -n envoy-gateway-system
+```
diff --git a/site/content/en/docs/tasks/extensibility/envoy-patch-policy.md b/site/content/en/docs/tasks/extensibility/envoy-patch-policy.md
index ff819754d1f..7fe84762189 100644
--- a/site/content/en/docs/tasks/extensibility/envoy-patch-policy.md
+++ b/site/content/en/docs/tasks/extensibility/envoy-patch-policy.md
@@ -111,7 +111,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -151,7 +150,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -195,7 +193,6 @@ spec:
group: gateway.networking.k8s.io
kind: GatewayClass
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -235,7 +232,6 @@ spec:
group: gateway.networking.k8s.io
kind: GatewayClass
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -322,7 +318,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
status:
conditions:
diff --git a/site/content/en/docs/tasks/extensibility/ext-proc.md b/site/content/en/docs/tasks/extensibility/ext-proc.md
index 9028447ab09..31ad551c63b 100644
--- a/site/content/en/docs/tasks/extensibility/ext-proc.md
+++ b/site/content/en/docs/tasks/extensibility/ext-proc.md
@@ -113,10 +113,10 @@ kind: EnvoyExtensionPolicy
metadata:
name: ext-proc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extProc:
- backendRefs:
- name: grpc-ext-proc
@@ -139,10 +139,10 @@ kind: EnvoyExtensionPolicy
metadata:
name: ext-proc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extProc:
- backendRefs:
- name: grpc-ext-proc
diff --git a/site/content/en/docs/tasks/extensibility/wasm.md b/site/content/en/docs/tasks/extensibility/wasm.md
index d973de77950..cb2e013dd80 100644
--- a/site/content/en/docs/tasks/extensibility/wasm.md
+++ b/site/content/en/docs/tasks/extensibility/wasm.md
@@ -44,10 +44,10 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
wasm:
- name: wasm-filter
rootID: my_root_id
@@ -70,10 +70,10 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
wasm:
- name: wasm-filter
rootID: my_root_id
@@ -107,8 +107,8 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
wasm:
@@ -132,17 +132,17 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
wasm:
- - name: wasm-filter
- rootID: my_root_id
- code:
- type: Image
- image:
- url: zhaohuabing/testwasm:v0.0.1
+ - name: wasm-filter
+ rootID: my_root_id
+ code:
+ type: Image
+ image:
+ url: zhaohuabing/testwasm:v0.0.1
```
{{% /tab %}}
diff --git a/site/content/en/docs/tasks/operations/customize-envoyproxy.md b/site/content/en/docs/tasks/operations/customize-envoyproxy.md
index 562237bfc43..892c3496ff0 100644
--- a/site/content/en/docs/tasks/operations/customize-envoyproxy.md
+++ b/site/content/en/docs/tasks/operations/customize-envoyproxy.md
@@ -3,15 +3,68 @@ title: "Customize EnvoyProxy"
---
Envoy Gateway provides an [EnvoyProxy][] CRD that can be linked to the ParametersRef
-in GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and
+in a Gateway and GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and
Service. To learn more about GatewayClass and ParametersRef, please refer to [Gateway API documentation][].
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
-Before you start, you need to add `ParametersRef` in GatewayClass, and refer to EnvoyProxy Config:
+Before you start, you need to add `Infrastructure.ParametersRef` in Gateway, and refer to EnvoyProxy Config:
+**Note**: `MergeGateways` cannot be set to `true` in your EnvoyProxy config if attaching to the Gateway.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+You can also attach the EnvoyProxy resource to the GatewayClass using the `parametersRef` field.
+This configuration is discouraged if you plan on creating multiple Gateways linking to the same
+GatewayClass and would like different infrastructure configurations for each of them.
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
@@ -28,7 +81,7 @@ spec:
group: gateway.envoyproxy.io
kind: EnvoyProxy
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
EOF
```
@@ -48,7 +101,7 @@ spec:
group: gateway.envoyproxy.io
kind: EnvoyProxy
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
```
{{% /tab %}}
@@ -67,7 +120,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -87,7 +140,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -119,7 +172,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -140,7 +193,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -168,7 +221,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -191,7 +244,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -221,7 +274,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -248,7 +301,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -280,7 +333,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -305,7 +358,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -339,7 +392,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -368,7 +421,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -404,7 +457,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -426,7 +479,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -459,7 +512,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
bootstrap:
type: Replace
@@ -547,7 +600,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
bootstrap:
type: Replace
@@ -649,7 +702,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -677,7 +730,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -713,7 +766,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
extraArgs:
- --disable-extensions envoy.access_loggers/envoy.access_loggers.wasm
@@ -730,7 +783,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
extraArgs:
- --disable-extensions envoy.access_loggers/envoy.access_loggers.wasm
@@ -756,7 +809,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -792,7 +845,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -835,7 +888,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -860,7 +913,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -918,7 +971,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
filterOrder:
- name: envoy.filters.http.wasm
@@ -938,7 +991,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
filterOrder:
- name: envoy.filters.http.wasm
diff --git a/site/content/en/docs/tasks/quickstart.md b/site/content/en/docs/tasks/quickstart.md
index 03d7b6de842..802b7989a88 100644
--- a/site/content/en/docs/tasks/quickstart.md
+++ b/site/content/en/docs/tasks/quickstart.md
@@ -92,34 +92,6 @@ curl --verbose --header "Host: www.example.com" http://localhost:8888/get
{{% /tab %}}
{{< /tabpane >}}
-## v1.1 Upgrade Notes
-
-Due to breaking changes in the Gateway API v1.1, some manual migration steps are required to upgrade Envoy Gateway to v1.1.
-
-Delete `BackendTLSPolicy` CRD (and resources):
-
-```shell
-kubectl delete crd backendtlspolicies.gateway.networking.k8s.io
-```
-
-Update Gateway-API and Envoy Gateway CRDs:
-
-```shell
-helm pull oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 --untar
-kubectl apply -f ./gateway-helm/crds/gatewayapi-crds.yaml
-kubectl apply -f ./gateway-helm/crds/generated
-```
-
-Update your `BackendTLSPolicy` and `GRPCRoute` resources according to Gateway-API [v1.1 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v11-upgrade-notes)
-
-Update your Envoy Gateway xPolicy resources: remove the namespace section from targetRef.
-
-Install Envoy Gateway v1.1.0:
-
-```shell
-helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 -n envoy-gateway-system
-```
-
## What to explore next?
In this quickstart, you have:
diff --git a/site/content/en/docs/tasks/security/backend-tls.md b/site/content/en/docs/tasks/security/backend-tls.md
index 53e9ccbd44a..3aadbc34714 100644
--- a/site/content/en/docs/tasks/security/backend-tls.md
+++ b/site/content/en/docs/tasks/security/backend-tls.md
@@ -25,11 +25,30 @@ Create a root certificate and private key to sign certificates:
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout ca.key -out ca.crt
```
-Create a certificate and a private key for `www.example.com`:
+Create a certificate and a private key for `www.example.com`.
+
+First, create an openssl configuration file:
+
+```shell
+cat > openssl.conf <the access logs will be sent. Currently only Service is supported. |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `logName` | _string_ | false | LogName defines the friendly name of the access log to be returned in StreamAccessLogsMessage.Identifier. This allows the access log server to differentiate between different access logs coming from the same Envoy. |
| `type` | _[ALSEnvoyProxyAccessLogType](#alsenvoyproxyaccesslogtype)_ | true | Type defines the type of accesslog. Supported types are "HTTP" and "TCP". |
| `http` | _[ALSEnvoyProxyHTTPAccessLogConfig](#alsenvoyproxyhttpaccesslogconfig)_ | false | HTTP defines additional configuration specific to HTTP access logs. |
@@ -124,6 +126,7 @@ _Appears in:_
| `type` | _[ActiveHealthCheckerType](#activehealthcheckertype)_ | true | Type defines the type of health checker. |
| `http` | _[HTTPActiveHealthChecker](#httpactivehealthchecker)_ | false | HTTP defines the configuration of http health checker. It's required while the health checker type is HTTP. |
| `tcp` | _[TCPActiveHealthChecker](#tcpactivehealthchecker)_ | false | TCP defines the configuration of tcp health checker. It's required while the health checker type is TCP. |
+| `grpc` | _[GRPCActiveHealthChecker](#grpcactivehealthchecker)_ | false | GRPC defines the configuration of the GRPC health checker. It's optional, and can only be used if the specified type is GRPC. |
#### ActiveHealthCheckPayload
@@ -171,6 +174,7 @@ _Appears in:_
| ----- | ----------- |
| `HTTP` | ActiveHealthCheckerTypeHTTP defines the HTTP type of health checking. |
| `TCP` | ActiveHealthCheckerTypeTCP defines the TCP type of health checking. |
+| `GRPC` | ActiveHealthCheckerTypeGRPC defines the GRPC type of health checking. |
#### AppProtocolType
@@ -273,22 +277,34 @@ _Appears in:_
| `status` | _[BackendStatus](#backendstatus)_ | true | Status defines the current status of Backend. |
+#### BackendCluster
+BackendCluster contains all the configuration required for configuring access
+to a backend. This can include multiple endpoints, and settings that apply for
+managing the connection to all these endpoints.
+
+_Appears in:_
+- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)
+- [ExtProc](#extproc)
+- [GRPCExtAuthService](#grpcextauthservice)
+- [HTTPExtAuthService](#httpextauthservice)
+- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog)
+- [ProxyOpenTelemetrySink](#proxyopentelemetrysink)
+- [TracingProvider](#tracingprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
-#### BackendConnection
-BackendConnection allows users to configure connection-level settings of backend
-_Appears in:_
-- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `bufferLimit` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | BufferLimit Soft limit on size of the cluster’s connections read and write buffers. BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space. If unspecified, an implementation defined default is applied (32768 bytes). For example, 20Mi, 1Gi, 256Ki etc. Note: that when the suffix is not provided, the value is interpreted as bytes. |
#### BackendEndpoint
@@ -333,6 +349,7 @@ BackendRef defines how an ObjectReference that is specific to BackendRef.
_Appears in:_
- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)
+- [BackendCluster](#backendcluster)
- [ExtProc](#extproc)
- [GRPCExtAuthService](#grpcextauthservice)
- [HTTPExtAuthService](#httpextauthservice)
@@ -347,6 +364,7 @@ _Appears in:_
| `name` | _[ObjectName](#objectname)_ | true | Name is the name of the referent. |
| `namespace` | _[Namespace](#namespace)_ | false | Namespace is the namespace of the backend. When unspecified, the local namespace is inferred.
Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.
Support: Core |
| `port` | _[PortNumber](#portnumber)_ | false | Port specifies the destination port number to use for this resource. Port is required when the referent is a Kubernetes Service. In this case, the port number is the service port number, not the target port. For other resources, destination port might be derived from the referent resource or this field. |
+| `failover` | _boolean_ | false | Failover This indicates whether the backend is designated as a failover. Multiple failover backends can be configured. It is highly recommended to configure active or passive health checks to ensure that failover can be detected when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again. The overprovisioning factor is set to 1.4, meaning the failover backends will only start receiving traffic when the health of the active backends falls below 72%. |
#### BackendSpec
@@ -447,19 +465,19 @@ _Appears in:_
| `targetRef` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the resource this policy is being attached to. This policy and the TargetRef MUST be in the same namespace for this Policy to have effect
Deprecated: use targetRefs/targetSelectors instead |
| `targetRefs` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName) array_ | true | TargetRefs are the names of the Gateway resources this policy is being attached to. |
| `targetSelectors` | _[TargetSelector](#targetselector) array_ | true | TargetSelectors allow targeting resources for this policy based on labels |
-| `rateLimit` | _[RateLimitSpec](#ratelimitspec)_ | false | RateLimit allows the user to limit the number of incoming requests to a predefined value based on attributes within the traffic flow. |
-| `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to the backend endpoints |
+| `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to the backend endpoints. Defaults to `LeastRequest`. |
| `proxyProtocol` | _[ProxyProtocol](#proxyprotocol)_ | false | ProxyProtocol enables the Proxy Protocol when communicating with the backend. |
| `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the upstream client connection. Disabled by default. |
| `healthCheck` | _[HealthCheck](#healthcheck)_ | false | HealthCheck allows gateway to perform active health checking on backends. |
-| `faultInjection` | _[FaultInjection](#faultinjection)_ | false | FaultInjection defines the fault injection policy to be applied. This configuration can be used to inject delays and abort requests to mimic failure scenarios such as service failures and overloads |
| `circuitBreaker` | _[CircuitBreaker](#circuitbreaker)_ | false | Circuit Breaker settings for the upstream connections and requests. If not set, circuit breakers will be enabled with the default thresholds |
-| `retry` | _[Retry](#retry)_ | false | Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions. If not set, retry will be disabled. |
-| `useClientProtocol` | _boolean_ | false | 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. |
| `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. |
| `connection` | _[BackendConnection](#backendconnection)_ | false | Connection includes backend connection settings. |
| `dns` | _[DNS](#dns)_ | false | DNS includes dns resolution settings. |
| `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration for backend connections. |
+| `rateLimit` | _[RateLimitSpec](#ratelimitspec)_ | false | RateLimit allows the user to limit the number of incoming requests to a predefined value based on attributes within the traffic flow. |
+| `faultInjection` | _[FaultInjection](#faultinjection)_ | false | FaultInjection defines the fault injection policy to be applied. This configuration can be used to inject delays and abort requests to mimic failure scenarios such as service failures and overloads |
+| `retry` | _[Retry](#retry)_ | false | Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions. If not set, retry will be disabled. |
+| `useClientProtocol` | _boolean_ | false | 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. |
#### BasicAuth
@@ -522,22 +540,6 @@ _Appears in:_
| `allowCredentials` | _boolean_ | true | AllowCredentials indicates whether a request can include user credentials like cookies, authentication headers, or TLS client certificates. |
-#### CircuitBreaker
-
-
-
-CircuitBreaker defines the Circuit Breaker configuration.
-
-_Appears in:_
-- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `maxConnections` | _integer_ | false | The maximum number of connections that Envoy will establish to the referenced backend defined within a xRoute rule. |
-| `maxPendingRequests` | _integer_ | false | The maximum number of pending requests that Envoy will queue to the referenced backend defined within a xRoute rule. |
-| `maxParallelRequests` | _integer_ | false | The maximum number of parallel requests that Envoy will make to the referenced backend defined within a xRoute rule. |
-| `maxParallelRetries` | _integer_ | false | The maximum number of parallel retries that Envoy will make to the referenced backend defined within a xRoute rule. |
-| `maxRequestsPerConnection` | _integer_ | false | The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule. Default: unlimited. |
#### ClaimToHeader
@@ -700,6 +702,37 @@ _Appears in:_
| `caCertificateRefs` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference) array_ | false | CACertificateRefs contains one or more references to Kubernetes objects that contain TLS certificates of the Certificate Authorities that can be used as a trust anchor to validate the certificates presented by the client.
A single reference to a Kubernetes ConfigMap or a Kubernetes Secret, with the CA certificate in a key named `ca.crt` is currently supported.
References to a resource in different namespace are invalid UNLESS there is a ReferenceGrant in the target namespace that allows the certificate to be attached. |
+#### ClusterSettings
+
+
+
+ClusterSettings provides the various knobs that can be set to control how traffic to a given
+backend will be configured.
+
+_Appears in:_
+- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)
+- [BackendCluster](#backendcluster)
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ExtProc](#extproc)
+- [GRPCExtAuthService](#grpcextauthservice)
+- [HTTPExtAuthService](#httpextauthservice)
+- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog)
+- [ProxyOpenTelemetrySink](#proxyopentelemetrysink)
+- [TracingProvider](#tracingprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to the backend endpoints. Defaults to `LeastRequest`. |
+| `proxyProtocol` | _[ProxyProtocol](#proxyprotocol)_ | false | ProxyProtocol enables the Proxy Protocol when communicating with the backend. |
+| `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the upstream client connection. Disabled by default. |
+| `healthCheck` | _[HealthCheck](#healthcheck)_ | false | HealthCheck allows gateway to perform active health checking on backends. |
+| `circuitBreaker` | _[CircuitBreaker](#circuitbreaker)_ | false | Circuit Breaker settings for the upstream connections and requests. If not set, circuit breakers will be enabled with the default thresholds |
+| `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. |
+| `connection` | _[BackendConnection](#backendconnection)_ | false | Connection includes backend connection settings. |
+| `dns` | _[DNS](#dns)_ | false | DNS includes dns resolution settings. |
+| `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration for backend connections. |
+
+
#### Compression
@@ -845,19 +878,6 @@ _Appears in:_
| `RequestHeader` | CustomTagTypeRequestHeader adds value from request header to each span. |
-#### DNS
-
-
-
-
-
-_Appears in:_
-- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `dnsRefreshRate` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | DNSRefreshRate specifies the rate at which DNS records should be refreshed. Defaults to 30 seconds. |
-| `respectDnsTtl` | _boolean_ | true | RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected. If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL. Defaults to true. |
#### EnvironmentCustomTag
@@ -945,6 +965,7 @@ _Appears in:_
| `envoy.filters.http.basic_auth` | EnvoyFilterBasicAuth defines the Envoy HTTP basic authentication filter. |
| `envoy.filters.http.oauth2` | EnvoyFilterOAuth2 defines the Envoy HTTP OAuth2 filter. |
| `envoy.filters.http.jwt_authn` | EnvoyFilterJWTAuthn defines the Envoy HTTP JWT authentication filter. |
+| `envoy.filters.http.stateful_session` | EnvoyFilterSessionPersistence defines the Envoy HTTP session persistence filter. |
| `envoy.filters.http.ext_proc` | EnvoyFilterExtProc defines the Envoy HTTP external process filter. |
| `envoy.filters.http.wasm` | EnvoyFilterWasm defines the Envoy HTTP WebAssembly filter. |
| `envoy.filters.http.rbac` | EnvoyFilterRBAC defines the Envoy RBAC filter. |
@@ -1403,7 +1424,7 @@ _Appears in:_
| `extraArgs` | _string array_ | false | ExtraArgs defines additional command line options that are provided to Envoy. More info: https://www.envoyproxy.io/docs/envoy/latest/operations/cli#command-line-options Note: some command line options are used internally(e.g. --log-level) so they cannot be provided here. |
| `mergeGateways` | _boolean_ | false | MergeGateways defines if Gateway resources should be merged onto the same Envoy Proxy Infrastructure. Setting this field to true would merge all Gateway Listeners under the parent Gateway Class. This means that the port, protocol and hostname tuple must be unique for every listener. If a duplicate listener is detected, the newer listener (based on timestamp) will be rejected and its status will be updated with a "Accepted=False" condition. |
| `shutdown` | _[ShutdownConfig](#shutdownconfig)_ | false | Shutdown defines configuration for graceful envoy shutdown process. |
-| `filterOrder` | _[FilterPosition](#filterposition) array_ | false | FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain. The FilterPosition in the list will be applied in the order they are defined. If unspecified, the default filter order is applied. Default filter order is:
- envoy.filters.http.health_check
- envoy.filters.http.fault
- envoy.filters.http.cors
- envoy.filters.http.ext_authz
- envoy.filters.http.basic_auth
- envoy.filters.http.oauth2
- envoy.filters.http.jwt_authn
- envoy.filters.http.ext_proc
- envoy.filters.http.wasm
- envoy.filters.http.rbac
- envoy.filters.http.local_ratelimit
- envoy.filters.http.ratelimit
- envoy.filters.http.router
Note: "envoy.filters.http.router" cannot be reordered, it's always the last filter in the chain. |
+| `filterOrder` | _[FilterPosition](#filterposition) array_ | false | FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain. The FilterPosition in the list will be applied in the order they are defined. If unspecified, the default filter order is applied. Default filter order is:
- envoy.filters.http.health_check
- envoy.filters.http.fault
- envoy.filters.http.cors
- envoy.filters.http.ext_authz
- envoy.filters.http.basic_auth
- envoy.filters.http.oauth2
- envoy.filters.http.jwt_authn
- envoy.filters.http.stateful_session
- envoy.filters.http.ext_proc
- envoy.filters.http.wasm
- envoy.filters.http.rbac
- envoy.filters.http.local_ratelimit
- envoy.filters.http.ratelimit
- envoy.filters.http.router
Note: "envoy.filters.http.router" cannot be reordered, it's always the last filter in the chain. |
| `backendTLS` | _[BackendTLSConfig](#backendtlsconfig)_ | false | BackendTLS is the TLS configuration for the Envoy proxy to use when connecting to backends. These settings are applied on backends for which TLS policies are specified. |
@@ -1464,7 +1485,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `backendRefs` | _[BackendRef](#backendref) array_ | true | BackendRefs defines the configuration of the external processing service |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `messageTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | MessageTimeout is the timeout for a response to be returned from the external processor Default: 200ms |
| `failOpen` | _boolean_ | false | FailOpen defines if requests or responses that cannot be processed due to connectivity to the external processor are terminated or passed-through. Default: false |
| `processingMode` | _[ExtProcProcessingMode](#extprocprocessingmode)_ | false | ProcessingMode defines how request and response body is processed Default: header and body are not sent to the external processor |
@@ -1678,6 +1701,20 @@ _Appears in:_
| `after` | _[EnvoyFilter](#envoyfilter)_ | true | After defines the filter that should come after the filter. Only one of Before or After must be set. |
+#### GRPCActiveHealthChecker
+
+
+
+GRPCActiveHealthChecker defines the settings of the GRPC health check.
+
+_Appears in:_
+- [ActiveHealthCheck](#activehealthcheck)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `service` | _string_ | false | Service to send in the health check request. If this is not specified, then the health check request applies to the entire server and not to a specific service. |
+
+
#### GRPCExtAuthService
@@ -1691,8 +1728,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent. Only Service kind is supported for now.
Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. Only Service kind is supported for now. |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
#### Gateway
@@ -1784,22 +1822,6 @@ _Appears in:_
| `http10` | _[HTTP10Settings](#http10settings)_ | false | HTTP10 turns on support for HTTP/1.0 and HTTP/0.9 requests. |
-#### HTTP2Settings
-
-
-
-HTTP2Settings provides HTTP/2 configuration for listeners and backends.
-
-_Appears in:_
-- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
-- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `initialStreamWindowSize` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | InitialStreamWindowSize sets the initial window size for HTTP/2 streams. If not set, the default value is 64 KiB(64*1024). |
-| `initialConnectionWindowSize` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. If not set, the default value is 1 MiB. |
-| `maxConcurrentStreams` | _integer_ | false | MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. If not set, the default value is 100. |
-| `onInvalidMessage` | _[InvalidMessageAction](#invalidmessageaction)_ | false | OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error It's recommended for L2 Envoy deployments to set this value to TerminateStream. https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two Default: TerminateConnection |
#### HTTP3Settings
@@ -1856,8 +1878,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent. Only Service kind is supported for now.
Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. Only Service kind is supported for now. |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `path` | _string_ | true | Path is the path of the HTTP External Authorization service. If path is specified, the authorization request will be sent to that path, or else the authorization request will be sent to the root path. |
| `headersToBackend` | _string array_ | false | HeadersToBackend are the authorization response headers that will be added to the original client request before sending it to the backend server. Note that coexisting headers will be overridden. If not specified, no authorization response headers will be added to the original client request. |
@@ -1954,22 +1977,9 @@ _Appears in:_
| `xForwardedClientCert` | _[XForwardedClientCert](#xforwardedclientcert)_ | false | XForwardedClientCert configures how Envoy Proxy handle the x-forwarded-client-cert (XFCC) HTTP header.
x-forwarded-client-cert (XFCC) is an HTTP header used to forward the certificate information of part or all of the clients or proxies that a request has flowed through, on its way from the client to the server.
Envoy proxy may choose to sanitize/append/forward the XFCC header before proxying the request.
If not set, the default behavior is sanitizing the XFCC header. |
| `withUnderscoresAction` | _[WithUnderscoresAction](#withunderscoresaction)_ | false | WithUnderscoresAction configures the action to take when an HTTP header with underscores is encountered. The default action is to reject the request. |
| `preserveXRequestID` | _boolean_ | false | PreserveXRequestID configures Envoy to keep the X-Request-ID header if passed for a request that is edge (Edge request is the request from external clients to front Envoy) and not reset it, which is the current Envoy behaviour. It defaults to false. |
+| `earlyRequestHeaders` | _[HTTPHeaderFilter](#httpheaderfilter)_ | false | EarlyRequestHeaders defines settings for early request header modification, before envoy performs routing, tracing and built-in header manipulation. |
-#### HealthCheck
-
-
-
-HealthCheck configuration to decide which endpoints
-are healthy and can be used for routing.
-
-_Appears in:_
-- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `active` | _[ActiveHealthCheck](#activehealthcheck)_ | false | Active health check configuration |
-| `passive` | _[PassiveHealthCheck](#passivehealthcheck)_ | false | Passive passive check configuration |
#### HealthCheckSettings
@@ -2076,7 +2086,8 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `op` | _[JSONPatchOperationType](#jsonpatchoperationtype)_ | true | Op is the type of operation to perform |
-| `path` | _string_ | true | Path is the location of the target document/field where the operation will be performed Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. |
+| `path` | _string_ | false | Path is the location of the target document/field where the operation will be performed Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. |
+| `jsonPath` | _string_ | false | JSONPath specifies the locations of the target document/field where the operation will be performed Refer to https://datatracker.ietf.org/doc/rfc9535/ for more details. |
| `from` | _string_ | false | From is the source location of the value to be copied or moved. Only valid for move or copy operations Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. |
| `value` | _[JSON](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#json-v1-apiextensions-k8s-io)_ | false | Value is the new value of the path location. The value is only used by the `add` and `replace` operations. |
@@ -2384,20 +2395,6 @@ _Appears in:_
| `value` | _string_ | true | Value defines the hard-coded value to add to each span. |
-#### LoadBalancer
-
-
-
-LoadBalancer defines the load balancer policy to be applied.
-
-_Appears in:_
-- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `type` | _[LoadBalancerType](#loadbalancertype)_ | true | Type decides the type of Load Balancer policy. Valid LoadBalancerType values are "ConsistentHash", "LeastRequest", "Random", "RoundRobin". |
-| `consistentHash` | _[ConsistentHash](#consistenthash)_ | false | ConsistentHash defines the configuration when the load balancer type is set to ConsistentHash |
-| `slowStart` | _[SlowStart](#slowstart)_ | false | SlowStart defines the configuration related to the slow start load balancer policy. If set, during slow start window, traffic sent to the newly added hosts will gradually increase. Currently this is only supported for RoundRobin and LeastRequest load balancers |
#### LoadBalancerType
@@ -2533,9 +2530,11 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `host` | _string_ | false | Host define the extension service hostname. Deprecated: Use BackendRefs instead. |
| `port` | _integer_ | false | Port defines the port the extension service is exposed on. Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the access log will be sent. Only Service kind is supported for now. |
| `resources` | _object (keys:string, values:string)_ | false | Resources is a set of labels that describe the source of a log entry, including envoy node info. It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). |
@@ -2890,9 +2889,11 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `host` | _string_ | false | Host define the service hostname. Deprecated: Use BackendRefs instead. |
| `port` | _integer_ | false | Port defines the port the service is exposed on. Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the metric will be sent. Only Service kind is supported for now. |
#### ProxyPrometheusProvider
@@ -2910,19 +2911,6 @@ _Appears in:_
| `compression` | _[Compression](#compression)_ | false | Configure the compression on Prometheus endpoint. Compression is useful in situations when bandwidth is scarce and large payloads can be effectively compressed at the expense of higher CPU load. |
-#### ProxyProtocol
-
-
-
-ProxyProtocol defines the configuration related to the proxy protocol
-when communicating with the backend.
-
-_Appears in:_
-- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `version` | _[ProxyProtocolVersion](#proxyprotocolversion)_ | true | Version of ProxyProtol Valid ProxyProtocolVersion values are "V1" "V2" |
#### ProxyProtocolVersion
@@ -3528,21 +3516,6 @@ _Appears in:_
| `idleTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | IdleTimeout for a TCP connection. Idle time is defined as a period in which there are no bytes sent or received on either the upstream or downstream connection. Default: 1 hour. |
-#### TCPKeepalive
-
-
-
-TCPKeepalive define the TCP Keepalive configuration.
-
-_Appears in:_
-- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
-- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `probes` | _integer_ | false | The total number of unacknowledged probes to send before deciding the connection is dead. Defaults to 9. |
-| `idleTime` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | The duration a connection needs to be idle before keep-alive probes start being sent. The duration format is Defaults to `7200s`. |
-| `interval` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | The duration between keep-alive probes. Defaults to `75s`. |
#### TCPTimeout
@@ -3619,19 +3592,6 @@ _Appears in:_
| `matchLabels` | _object (keys:string, values:string)_ | true | MatchLabels are the set of label selectors for identifying the targeted resource |
-#### Timeout
-
-
-
-Timeout defines configuration for timeouts related to connections.
-
-_Appears in:_
-- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `tcp` | _[TCPTimeout](#tcptimeout)_ | false | Timeout settings for TCP. |
-| `http` | _[HTTPTimeout](#httptimeout)_ | false | Timeout settings for HTTP. |
#### TracingProvider
@@ -3645,10 +3605,12 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `type` | _[TracingProviderType](#tracingprovidertype)_ | true | Type defines the tracing provider type. |
| `host` | _string_ | false | Host define the provider service hostname. Deprecated: Use BackendRefs instead. |
| `port` | _integer_ | false | Port defines the port the provider service is exposed on. Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the trace will be sent. Only Service kind is supported for now. |
| `zipkin` | _[ZipkinTracingProvider](#zipkintracingprovider)_ | false | Zipkin defines the Zipkin tracing provider configuration |
diff --git a/site/content/en/latest/concepts/concepts_overview.md b/site/content/en/latest/concepts/concepts_overview.md
index 31838b520f2..9af9a3fff10 100644
--- a/site/content/en/latest/concepts/concepts_overview.md
+++ b/site/content/en/latest/concepts/concepts_overview.md
@@ -10,13 +10,12 @@ There are several resources that play a part in enabling you to meet your Kubern
There are several resources that play a part in enabling you to meet your Kubernetes ingress traffic handling needs. This page provides a brief overview of the resources you’ll be working with.
-# Overview
-
-## Kubernetes Gateway API Resources
+### Kubernetes Gateway API Resources
- **GatewayClass:** Defines a class of Gateways with common configuration.
- **Gateway:** Specifies how traffic can enter the cluster.
- **Routes:** **HTTPRoute, GRPCRoute, TLSRoute, TCPRoute, UDPRoute:** Define routing rules for different types of traffic.
-## Envoy Gateway (EG) API Resources
+
+### Envoy Gateway (EG) API Resources
- **EnvoyProxy:** Represents the deployment and configuration of the Envoy proxy within a Kubernetes cluster, managing its lifecycle and settings.
- **EnvoyPatchPolicy, ClientTrafficPolicy, SecurityPolicy, BackendTrafficPolicy, EnvoyExtensionPolicy, BackendTLSPolicy:** Additional policies and configurations specific to Envoy Gateway.
- **Backend:** A resource that makes routing to cluster-external backends easier and makes access to external processes via Unix Domain Sockets possible.
diff --git a/site/content/en/latest/install/install-yaml.md b/site/content/en/latest/install/install-yaml.md
index e675f15fbec..c0a8d1caa72 100644
--- a/site/content/en/latest/install/install-yaml.md
+++ b/site/content/en/latest/install/install-yaml.md
@@ -13,7 +13,7 @@ installation, it is recommended that you use helm.
Envoy Gateway is designed to run in Kubernetes for production. The most essential requirements are:
-* Kubernetes 1.25 or later
+* Kubernetes 1.27 or later
* The `kubectl` command-line tool
{{% alert title="Compatibility Matrix" color="warning" %}}
@@ -37,3 +37,31 @@ Refer to the [Developer Guide](../../contributions/develop) to learn more.
2. Next Steps
Envoy Gateway should now be successfully installed and running, but in order to experience more abilities of Envoy Gateway, you can refer to [Tasks](/latest/tasks).
+
+## Upgrading from v1.0
+
+Due to breaking changes in Gateway API v1.1, some manual migration steps are required to upgrade Envoy Gateway to v1.1.
+
+1. Delete `BackendTLSPolicy` CRD (and resources):
+
+```shell
+kubectl delete crd backendtlspolicies.gateway.networking.k8s.io
+```
+
+2. Update Gateway-API and Envoy Gateway CRDs:
+
+```shell
+helm pull oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} --untar
+kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/gatewayapi-crds.yaml
+kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/generated
+```
+
+3. Update your `BackendTLSPolicy` and `GRPCRoute` resources according to Gateway-API [v1.1 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v11-upgrade-notes)
+
+4. Update your Envoy Gateway xPolicy resources: remove the namespace section from targetRef.
+
+5. Install Envoy Gateway {{< yaml-version >}}:
+
+```shell
+helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} -n envoy-gateway-system
+```
diff --git a/site/content/en/latest/install/migrating-to-envoy.md b/site/content/en/latest/install/migrating-to-envoy.md
new file mode 100644
index 00000000000..470c759ab7e
--- /dev/null
+++ b/site/content/en/latest/install/migrating-to-envoy.md
@@ -0,0 +1,143 @@
+---
+title: Migrating from Ingress Resources
+---
+
+## Introduction
+
+Migrating from Ingress to Envoy Gateway involves converting existing Ingress resources into resources compatible with Envoy Gateway. The `ingress2gateway` tool simplifies this migration by transforming Ingress resources into Gateway API resources that Envoy Gateway can use. This guide will walk you through the prerequisites, installation of the `ingress2gateway` tool, and provide an example migration process.
+
+## Prerequisites
+
+Before you start the migration, ensure you have the following:
+
+1. **Envoy Gateway Installed**: You need Envoy Gateway set up in your Kubernetes cluster. Follow the [Envoy Gateway installation guide](../install) for details.
+2. **Kubernetes Cluster Access**: Ensure you have access to your Kubernetes cluster and necessary permissions to manage resources.
+3. **Installation of `ingress2gateway` Tool**: You need to install the `ingress2gateway` tool in your Kubernetes cluster and configure it accordingly. Follow the [ingress2gateway tool installation guide](https://github.com/kubernetes-sigs/ingress2gateway/blob/main/README.md#installation) for details.
+
+## Example Migration
+
+Here’s a step-by-step example of migrating from Ingress to Envoy Gateway using `ingress2gateway`:
+
+### 1. Install and Configure Envoy Gateway
+
+Ensure that Envoy Gateway is installed and running in your cluster. Follow the [official Envoy Gateway installation guide](../install) for setup instructions.
+
+### 2. Create a GatewayClass
+
+To ensure the generated HTTPRoutes are programmed correctly in the Envoy Gateway data plane, create a GatewayClass that links to the Envoy Gateway controller.
+
+Create a `GatewayClass` resource:
+
+```yaml
+apiVersion: gateway.networking.k8s.io/v1beta1
+kind: GatewayClass
+metadata:
+ name: envoy-gateway-class
+spec:
+ controllerName: gateway.envoyproxy.io/controller
+```
+
+Apply this resource:
+
+```sh
+kubectl apply -f gatewayclass.yaml
+```
+
+### 3. Install Ingress2gateway
+
+Ensure you have the Ingress2gateway package installed. If not, follow the package’s installation instructions.
+
+### 4. Run Ingress2gateway
+
+Use Ingress2gateway to read your existing Ingress resources and translate them into Gateway API resources.
+
+```sh
+./ingress2gateway print
+```
+
+This command will:
+1. Read your Kube config file to extract the cluster credentials and the current active namespace.
+2. Search for Ingress and provider-specific resources in that namespace.
+3. Convert them to Gateway API resources (Gateways and HTTPRoutes).
+
+#### Example Ingress Configuration
+
+```yaml
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: example-ingress
+ namespace: default
+ annotations:
+ nginx.ingress.kubernetes.io/rewrite-target: /
+spec:
+ rules:
+ - host: example.com
+ http:
+ paths:
+ - path: /foo
+ pathType: Prefix
+ backend:
+ service:
+ name: foo-service
+ port:
+ number: 80
+```
+
+### 5. Save the Output
+
+The command will output the equivalent Gateway API resources in YAML/JSON format to stdout. Save this output to a file for further use.
+
+```sh
+./ingress2gateway print > gateway-resources.yaml
+```
+
+### 6. Apply the Translated Resources
+
+Apply the translated Gateway API resources to your cluster.
+
+```sh
+kubectl apply -f gateway-resources.yaml
+```
+
+### 7. Create a Gateway Resource
+
+Create a `Gateway` resource specifying the `GatewayClass` created earlier and including the necessary listeners.
+
+```yaml
+apiVersion: gateway.networking.k8s.io/v1beta1
+kind: Gateway
+metadata:
+ name: example-gateway
+ namespace: default
+spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ hostname: example.com
+```
+
+Apply this resource:
+
+```sh
+kubectl apply -f gateway.yaml
+```
+
+### 8. Validate the Migration
+
+Ensure the HTTPRoutes and Gateways are correctly set up and that traffic is being routed as expected. Validate the new configuration by checking the status of the Gateway and HTTPRoute resources.
+
+```sh
+kubectl get gateways
+kubectl get httproutes
+```
+
+### 9. Monitor and Troubleshoot
+
+Monitor the Envoy Gateway logs and metrics to ensure everything is functioning correctly. Troubleshoot any issues by reviewing the Gateway and HTTPRoute statuses and Envoy Gateway controller logs.
+
+## Summary
+
+By following this guide, users can effectively migrate their existing Ingress resources to Envoy Gateway using the Ingress2gateway package. Creating a GatewayClass and linking it to the Envoy Gateway controller ensures that the translated resources are properly programmed in the data plane, providing a seamless transition to the Envoy Gateway environment.
\ No newline at end of file
diff --git a/site/content/en/latest/tasks/extensibility/envoy-patch-policy.md b/site/content/en/latest/tasks/extensibility/envoy-patch-policy.md
index 9626dc93752..36930d73785 100644
--- a/site/content/en/latest/tasks/extensibility/envoy-patch-policy.md
+++ b/site/content/en/latest/tasks/extensibility/envoy-patch-policy.md
@@ -110,7 +110,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -150,7 +149,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -194,7 +192,6 @@ spec:
group: gateway.networking.k8s.io
kind: GatewayClass
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -234,7 +231,6 @@ spec:
group: gateway.networking.k8s.io
kind: GatewayClass
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -321,7 +317,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
status:
conditions:
diff --git a/site/content/en/latest/tasks/extensibility/ext-proc.md b/site/content/en/latest/tasks/extensibility/ext-proc.md
index f6b8b5c741a..910332f4740 100644
--- a/site/content/en/latest/tasks/extensibility/ext-proc.md
+++ b/site/content/en/latest/tasks/extensibility/ext-proc.md
@@ -106,10 +106,10 @@ kind: EnvoyExtensionPolicy
metadata:
name: ext-proc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extProc:
- backendRefs:
- name: grpc-ext-proc
@@ -132,10 +132,10 @@ kind: EnvoyExtensionPolicy
metadata:
name: ext-proc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extProc:
- backendRefs:
- name: grpc-ext-proc
diff --git a/site/content/en/latest/tasks/extensibility/wasm.md b/site/content/en/latest/tasks/extensibility/wasm.md
index 6cb3d1092df..8a640471ee1 100644
--- a/site/content/en/latest/tasks/extensibility/wasm.md
+++ b/site/content/en/latest/tasks/extensibility/wasm.md
@@ -37,8 +37,8 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
wasm:
@@ -63,18 +63,18 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
wasm:
- - name: wasm-filter
- rootID: my_root_id
- code:
- type: HTTP
- http:
- url: https://raw.githubusercontent.com/envoyproxy/envoy/main/examples/wasm-cc/lib/envoy_filter_http_wasm_example.wasm
- sha256: 79c9f85128bb0177b6511afa85d587224efded376ac0ef76df56595f1e6315c0
+ - name: wasm-filter
+ rootID: my_root_id
+ code:
+ type: HTTP
+ http:
+ url: https://raw.githubusercontent.com/envoyproxy/envoy/main/examples/wasm-cc/lib/envoy_filter_http_wasm_example.wasm
+ sha256: 79c9f85128bb0177b6511afa85d587224efded376ac0ef76df56595f1e6315c0
```
{{% /tab %}}
@@ -100,8 +100,8 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
wasm:
@@ -125,17 +125,17 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
wasm:
- - name: wasm-filter
- rootID: my_root_id
- code:
- type: Image
- image:
- url: zhaohuabing/testwasm:v0.0.1
+ - name: wasm-filter
+ rootID: my_root_id
+ code:
+ type: Image
+ image:
+ url: zhaohuabing/testwasm:v0.0.1
```
{{% /tab %}}
diff --git a/site/content/en/latest/tasks/operations/customize-envoyproxy.md b/site/content/en/latest/tasks/operations/customize-envoyproxy.md
index bfcc3d6e07a..892c3496ff0 100644
--- a/site/content/en/latest/tasks/operations/customize-envoyproxy.md
+++ b/site/content/en/latest/tasks/operations/customize-envoyproxy.md
@@ -3,14 +3,68 @@ title: "Customize EnvoyProxy"
---
Envoy Gateway provides an [EnvoyProxy][] CRD that can be linked to the ParametersRef
-in GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and
+in a Gateway and GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and
Service. To learn more about GatewayClass and ParametersRef, please refer to [Gateway API documentation][].
## Prerequisites
{{< boilerplate prerequisites >}}
-Before you start, you need to add `ParametersRef` in GatewayClass, and refer to EnvoyProxy Config:
+Before you start, you need to add `Infrastructure.ParametersRef` in Gateway, and refer to EnvoyProxy Config:
+**Note**: `MergeGateways` cannot be set to `true` in your EnvoyProxy config if attaching to the Gateway.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+You can also attach the EnvoyProxy resource to the GatewayClass using the `parametersRef` field.
+This configuration is discouraged if you plan on creating multiple Gateways linking to the same
+GatewayClass and would like different infrastructure configurations for each of them.
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
@@ -27,7 +81,7 @@ spec:
group: gateway.envoyproxy.io
kind: EnvoyProxy
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
EOF
```
@@ -47,7 +101,7 @@ spec:
group: gateway.envoyproxy.io
kind: EnvoyProxy
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
```
{{% /tab %}}
@@ -66,7 +120,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -86,7 +140,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -118,7 +172,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -139,7 +193,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -167,7 +221,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -190,7 +244,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -220,7 +274,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -247,7 +301,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -279,7 +333,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -304,7 +358,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -338,7 +392,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -367,7 +421,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -403,7 +457,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -425,7 +479,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -458,7 +512,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
bootstrap:
type: Replace
@@ -546,7 +600,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
bootstrap:
type: Replace
@@ -648,7 +702,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -676,7 +730,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -712,7 +766,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
extraArgs:
- --disable-extensions envoy.access_loggers/envoy.access_loggers.wasm
@@ -729,7 +783,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
extraArgs:
- --disable-extensions envoy.access_loggers/envoy.access_loggers.wasm
@@ -755,7 +809,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -791,7 +845,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -834,7 +888,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -859,7 +913,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -917,7 +971,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
filterOrder:
- name: envoy.filters.http.wasm
@@ -937,7 +991,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
filterOrder:
- name: envoy.filters.http.wasm
diff --git a/site/content/en/latest/tasks/quickstart.md b/site/content/en/latest/tasks/quickstart.md
index 03d7b6de842..802b7989a88 100644
--- a/site/content/en/latest/tasks/quickstart.md
+++ b/site/content/en/latest/tasks/quickstart.md
@@ -92,34 +92,6 @@ curl --verbose --header "Host: www.example.com" http://localhost:8888/get
{{% /tab %}}
{{< /tabpane >}}
-## v1.1 Upgrade Notes
-
-Due to breaking changes in the Gateway API v1.1, some manual migration steps are required to upgrade Envoy Gateway to v1.1.
-
-Delete `BackendTLSPolicy` CRD (and resources):
-
-```shell
-kubectl delete crd backendtlspolicies.gateway.networking.k8s.io
-```
-
-Update Gateway-API and Envoy Gateway CRDs:
-
-```shell
-helm pull oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 --untar
-kubectl apply -f ./gateway-helm/crds/gatewayapi-crds.yaml
-kubectl apply -f ./gateway-helm/crds/generated
-```
-
-Update your `BackendTLSPolicy` and `GRPCRoute` resources according to Gateway-API [v1.1 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v11-upgrade-notes)
-
-Update your Envoy Gateway xPolicy resources: remove the namespace section from targetRef.
-
-Install Envoy Gateway v1.1.0:
-
-```shell
-helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 -n envoy-gateway-system
-```
-
## What to explore next?
In this quickstart, you have:
diff --git a/site/content/en/latest/tasks/security/backend-tls.md b/site/content/en/latest/tasks/security/backend-tls.md
index c30777f69f3..7fca5ef8477 100644
--- a/site/content/en/latest/tasks/security/backend-tls.md
+++ b/site/content/en/latest/tasks/security/backend-tls.md
@@ -25,11 +25,30 @@ Create a root certificate and private key to sign certificates:
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout ca.key -out ca.crt
```
-Create a certificate and a private key for `www.example.com`:
+Create a certificate and a private key for `www.example.com`.
+
+First, create an openssl configuration file:
+
+```shell
+cat > openssl.conf <}}
+## Early Header Modification
+
+In some cases, it could be necessary to modify headers before the proxy performs any sort of processing, routing or tracing. Envoy Gateway supports this functionality using the [ClientTrafficPolicy][] API.
+
+A ClientTrafficPolicy resource can be attached to a Gateway resource to configure early header modifications for all its routes. In the following example we will demonstrate how early header modification can be configured.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+
+Querying `headers.example/get` should result in a `200` response from the example Gateway and the output from the
+example app should indicate that the upstream example app received the following headers:
+- `early-added-header` contains early (ClientTrafficPolicy) and late (RouteFilter) values
+- `early-set-header` contains only early (ClientTrafficPolicy) and late (RouteFilter) values, since the early modification overwritten the client value.
+- `early-removed-header` contains only the late (RouteFilter) value, since the early modification deleted the client value.
+
+```console
+$ curl -vvv --header "Host: headers.example" "http://${GATEWAY_HOST}/get" --header "early-added-header: client" --header "early-set-header: client" --header "early-removed-header: client"
+...
+> GET /get HTTP/1.1
+> Host: headers.example
+> User-Agent: curl/7.81.0
+> Accept: */*
+> add-header: something
+>
+* Mark bundle as not supporting multiuse
+< HTTP/1.1 200 OK
+< content-type: application/json
+< x-content-type-options: nosniff
+< content-length: 474
+< x-envoy-upstream-service-time: 0
+< server: envoy
+<
+
+ "headers": {
+ "Accept": [
+ "*/*"
+ ],
+ "Early-Added-Header": [
+ "client",
+ "early",
+ "late"
+ ],
+ "Early-Set-Header": [
+ "early",
+ "late"
+ ],
+ "Early-removed-Header": [
+ "late"
+ ]
+...
+```
+
[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute/
[HTTPRoute filters]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteFilter
[Gateway API documentation]: https://gateway-api.sigs.k8s.io/
[req_filter]: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPHeaderFilter
+[ClientTrafficPolicy]: ../../../api/extension_types#clienttrafficpolicy
diff --git a/site/content/en/latest/tasks/traffic/http-routing.md b/site/content/en/latest/tasks/traffic/http-routing.md
index 705846c6ec9..0f1f3c688fb 100644
--- a/site/content/en/latest/tasks/traffic/http-routing.md
+++ b/site/content/en/latest/tasks/traffic/http-routing.md
@@ -140,10 +140,10 @@ kind: SecurityPolicy
metadata:
name: jwt-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: jwt-claim-routing
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: jwt-claim-routing
jwt:
providers:
- name: example
@@ -208,10 +208,10 @@ kind: SecurityPolicy
metadata:
name: jwt-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: jwt-claim-routing
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: jwt-claim-routing
jwt:
providers:
- name: example
diff --git a/site/content/en/latest/tasks/traffic/http3.md b/site/content/en/latest/tasks/traffic/http3.md
index cb5034284c1..a0fb1594295 100644
--- a/site/content/en/latest/tasks/traffic/http3.md
+++ b/site/content/en/latest/tasks/traffic/http3.md
@@ -69,10 +69,10 @@ metadata:
name: enable-http3
spec:
http3: {}
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
EOF
```
@@ -88,10 +88,10 @@ metadata:
name: enable-http3
spec:
http3: {}
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: eg
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
```
{{% /tab %}}
diff --git a/site/content/en/latest/tasks/traffic/load-balancing.md b/site/content/en/latest/tasks/traffic/load-balancing.md
index b8bdff01af2..3c9a78450b5 100644
--- a/site/content/en/latest/tasks/traffic/load-balancing.md
+++ b/site/content/en/latest/tasks/traffic/load-balancing.md
@@ -13,7 +13,7 @@ Envoy Gateway supports the following load balancing policies:
- **Consistent Hash**: load balancer implements consistent hashing to upstream hosts.
Envoy Gateway introduces a new CRD called [BackendTrafficPolicy][] that allows the user to describe their desired load balancing polices.
-This instantiated resource can be linked to a [Gateway][], [HTTPRoute][] or [GRPCRoute][] resource.
+This instantiated resource can be linked to a [Gateway][], [HTTPRoute][] or [GRPCRoute][] resource. If `loadBalancer` is not specified in [BackendTrafficPolicy][], the default load balancing policy is `Least Request`.
## Prerequisites
diff --git a/site/content/en/latest/tasks/traffic/local-rate-limit.md b/site/content/en/latest/tasks/traffic/local-rate-limit.md
index a7b920db1c4..62e369044a5 100644
--- a/site/content/en/latest/tasks/traffic/local-rate-limit.md
+++ b/site/content/en/latest/tasks/traffic/local-rate-limit.md
@@ -43,8 +43,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -72,8 +72,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -259,8 +259,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
@@ -284,8 +284,8 @@ kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
diff --git a/site/content/en/latest/tasks/traffic/retry.md b/site/content/en/latest/tasks/traffic/retry.md
index 25b7e2519ec..75d151bdff6 100644
--- a/site/content/en/latest/tasks/traffic/retry.md
+++ b/site/content/en/latest/tasks/traffic/retry.md
@@ -56,10 +56,10 @@ kind: BackendTrafficPolicy
metadata:
name: retry-for-route
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
retry:
numRetries: 5
perRetry:
@@ -87,10 +87,10 @@ kind: BackendTrafficPolicy
metadata:
name: retry-for-route
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
retry:
numRetries: 5
perRetry:
diff --git a/site/content/en/v1.0/tasks/security/backend-tls.md b/site/content/en/v1.0/tasks/security/backend-tls.md
index 1f84ea4db81..5ba360e1d58 100644
--- a/site/content/en/v1.0/tasks/security/backend-tls.md
+++ b/site/content/en/v1.0/tasks/security/backend-tls.md
@@ -25,11 +25,30 @@ Create a root certificate and private key to sign certificates:
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout ca.key -out ca.crt
```
-Create a certificate and a private key for `www.example.com`:
+Create a certificate and a private key for `www.example.com`.
+
+First, create an openssl configuration file:
+
+```shell
+cat > openssl.conf <}}
+{{% tab header="kubectl" %}}
+
+```shell
+kubectl get gateway/eg -o yaml
+```
+
+{{% /tab %}}
+{{% tab header="egctl (experimental)" %}}
+
+```shell
+egctl x status gateway -v
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
diff --git a/site/content/en/v1.1/concepts/concepts_overview.md b/site/content/en/v1.1/concepts/concepts_overview.md
index 31838b520f2..9af9a3fff10 100644
--- a/site/content/en/v1.1/concepts/concepts_overview.md
+++ b/site/content/en/v1.1/concepts/concepts_overview.md
@@ -10,13 +10,12 @@ There are several resources that play a part in enabling you to meet your Kubern
There are several resources that play a part in enabling you to meet your Kubernetes ingress traffic handling needs. This page provides a brief overview of the resources you’ll be working with.
-# Overview
-
-## Kubernetes Gateway API Resources
+### Kubernetes Gateway API Resources
- **GatewayClass:** Defines a class of Gateways with common configuration.
- **Gateway:** Specifies how traffic can enter the cluster.
- **Routes:** **HTTPRoute, GRPCRoute, TLSRoute, TCPRoute, UDPRoute:** Define routing rules for different types of traffic.
-## Envoy Gateway (EG) API Resources
+
+### Envoy Gateway (EG) API Resources
- **EnvoyProxy:** Represents the deployment and configuration of the Envoy proxy within a Kubernetes cluster, managing its lifecycle and settings.
- **EnvoyPatchPolicy, ClientTrafficPolicy, SecurityPolicy, BackendTrafficPolicy, EnvoyExtensionPolicy, BackendTLSPolicy:** Additional policies and configurations specific to Envoy Gateway.
- **Backend:** A resource that makes routing to cluster-external backends easier and makes access to external processes via Unix Domain Sockets possible.
diff --git a/site/content/en/v1.1/install/install-yaml.md b/site/content/en/v1.1/install/install-yaml.md
index e675f15fbec..c0a8d1caa72 100644
--- a/site/content/en/v1.1/install/install-yaml.md
+++ b/site/content/en/v1.1/install/install-yaml.md
@@ -13,7 +13,7 @@ installation, it is recommended that you use helm.
Envoy Gateway is designed to run in Kubernetes for production. The most essential requirements are:
-* Kubernetes 1.25 or later
+* Kubernetes 1.27 or later
* The `kubectl` command-line tool
{{% alert title="Compatibility Matrix" color="warning" %}}
@@ -37,3 +37,31 @@ Refer to the [Developer Guide](../../contributions/develop) to learn more.
2. Next Steps
Envoy Gateway should now be successfully installed and running, but in order to experience more abilities of Envoy Gateway, you can refer to [Tasks](/latest/tasks).
+
+## Upgrading from v1.0
+
+Due to breaking changes in Gateway API v1.1, some manual migration steps are required to upgrade Envoy Gateway to v1.1.
+
+1. Delete `BackendTLSPolicy` CRD (and resources):
+
+```shell
+kubectl delete crd backendtlspolicies.gateway.networking.k8s.io
+```
+
+2. Update Gateway-API and Envoy Gateway CRDs:
+
+```shell
+helm pull oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} --untar
+kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/gatewayapi-crds.yaml
+kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/generated
+```
+
+3. Update your `BackendTLSPolicy` and `GRPCRoute` resources according to Gateway-API [v1.1 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v11-upgrade-notes)
+
+4. Update your Envoy Gateway xPolicy resources: remove the namespace section from targetRef.
+
+5. Install Envoy Gateway {{< yaml-version >}}:
+
+```shell
+helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} -n envoy-gateway-system
+```
diff --git a/site/content/en/v1.1/tasks/extensibility/envoy-patch-policy.md b/site/content/en/v1.1/tasks/extensibility/envoy-patch-policy.md
index ff819754d1f..7fe84762189 100644
--- a/site/content/en/v1.1/tasks/extensibility/envoy-patch-policy.md
+++ b/site/content/en/v1.1/tasks/extensibility/envoy-patch-policy.md
@@ -111,7 +111,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -151,7 +150,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -195,7 +193,6 @@ spec:
group: gateway.networking.k8s.io
kind: GatewayClass
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -235,7 +232,6 @@ spec:
group: gateway.networking.k8s.io
kind: GatewayClass
name: eg
- namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
@@ -322,7 +318,6 @@ spec:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
- namespace: default
type: JSONPatch
status:
conditions:
diff --git a/site/content/en/v1.1/tasks/extensibility/ext-proc.md b/site/content/en/v1.1/tasks/extensibility/ext-proc.md
index 9028447ab09..31ad551c63b 100644
--- a/site/content/en/v1.1/tasks/extensibility/ext-proc.md
+++ b/site/content/en/v1.1/tasks/extensibility/ext-proc.md
@@ -113,10 +113,10 @@ kind: EnvoyExtensionPolicy
metadata:
name: ext-proc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extProc:
- backendRefs:
- name: grpc-ext-proc
@@ -139,10 +139,10 @@ kind: EnvoyExtensionPolicy
metadata:
name: ext-proc-example
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: myapp
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: myapp
extProc:
- backendRefs:
- name: grpc-ext-proc
diff --git a/site/content/en/v1.1/tasks/extensibility/wasm.md b/site/content/en/v1.1/tasks/extensibility/wasm.md
index d973de77950..cb2e013dd80 100644
--- a/site/content/en/v1.1/tasks/extensibility/wasm.md
+++ b/site/content/en/v1.1/tasks/extensibility/wasm.md
@@ -44,10 +44,10 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
wasm:
- name: wasm-filter
rootID: my_root_id
@@ -70,10 +70,10 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: backend
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
wasm:
- name: wasm-filter
rootID: my_root_id
@@ -107,8 +107,8 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
wasm:
@@ -132,17 +132,17 @@ kind: EnvoyExtensionPolicy
metadata:
name: wasm-test
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
name: backend
wasm:
- - name: wasm-filter
- rootID: my_root_id
- code:
- type: Image
- image:
- url: zhaohuabing/testwasm:v0.0.1
+ - name: wasm-filter
+ rootID: my_root_id
+ code:
+ type: Image
+ image:
+ url: zhaohuabing/testwasm:v0.0.1
```
{{% /tab %}}
diff --git a/site/content/en/v1.1/tasks/operations/customize-envoyproxy.md b/site/content/en/v1.1/tasks/operations/customize-envoyproxy.md
index 562237bfc43..892c3496ff0 100644
--- a/site/content/en/v1.1/tasks/operations/customize-envoyproxy.md
+++ b/site/content/en/v1.1/tasks/operations/customize-envoyproxy.md
@@ -3,15 +3,68 @@ title: "Customize EnvoyProxy"
---
Envoy Gateway provides an [EnvoyProxy][] CRD that can be linked to the ParametersRef
-in GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and
+in a Gateway and GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and
Service. To learn more about GatewayClass and ParametersRef, please refer to [Gateway API documentation][].
## Prerequisites
-Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest.
-Before proceeding, you should be able to query the example backend using HTTP.
+{{< boilerplate prerequisites >}}
-Before you start, you need to add `ParametersRef` in GatewayClass, and refer to EnvoyProxy Config:
+Before you start, you need to add `Infrastructure.ParametersRef` in Gateway, and refer to EnvoyProxy Config:
+**Note**: `MergeGateways` cannot be set to `true` in your EnvoyProxy config if attaching to the Gateway.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+You can also attach the EnvoyProxy resource to the GatewayClass using the `parametersRef` field.
+This configuration is discouraged if you plan on creating multiple Gateways linking to the same
+GatewayClass and would like different infrastructure configurations for each of them.
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
@@ -28,7 +81,7 @@ spec:
group: gateway.envoyproxy.io
kind: EnvoyProxy
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
EOF
```
@@ -48,7 +101,7 @@ spec:
group: gateway.envoyproxy.io
kind: EnvoyProxy
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
```
{{% /tab %}}
@@ -67,7 +120,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -87,7 +140,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -119,7 +172,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -140,7 +193,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -168,7 +221,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -191,7 +244,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -221,7 +274,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -248,7 +301,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -280,7 +333,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -305,7 +358,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -339,7 +392,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -368,7 +421,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -404,7 +457,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -426,7 +479,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -459,7 +512,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
bootstrap:
type: Replace
@@ -547,7 +600,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
bootstrap:
type: Replace
@@ -649,7 +702,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -677,7 +730,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -713,7 +766,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
extraArgs:
- --disable-extensions envoy.access_loggers/envoy.access_loggers.wasm
@@ -730,7 +783,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
extraArgs:
- --disable-extensions envoy.access_loggers/envoy.access_loggers.wasm
@@ -756,7 +809,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -792,7 +845,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -835,7 +888,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -860,7 +913,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: eg
- namespace: envoy-gateway-system
+ namespace: default
spec:
provider:
type: Kubernetes
@@ -918,7 +971,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
filterOrder:
- name: envoy.filters.http.wasm
@@ -938,7 +991,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
name: custom-proxy-config
- namespace: envoy-gateway-system
+ namespace: default
spec:
filterOrder:
- name: envoy.filters.http.wasm
diff --git a/site/content/en/v1.1/tasks/quickstart.md b/site/content/en/v1.1/tasks/quickstart.md
index 03d7b6de842..802b7989a88 100644
--- a/site/content/en/v1.1/tasks/quickstart.md
+++ b/site/content/en/v1.1/tasks/quickstart.md
@@ -92,34 +92,6 @@ curl --verbose --header "Host: www.example.com" http://localhost:8888/get
{{% /tab %}}
{{< /tabpane >}}
-## v1.1 Upgrade Notes
-
-Due to breaking changes in the Gateway API v1.1, some manual migration steps are required to upgrade Envoy Gateway to v1.1.
-
-Delete `BackendTLSPolicy` CRD (and resources):
-
-```shell
-kubectl delete crd backendtlspolicies.gateway.networking.k8s.io
-```
-
-Update Gateway-API and Envoy Gateway CRDs:
-
-```shell
-helm pull oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 --untar
-kubectl apply -f ./gateway-helm/crds/gatewayapi-crds.yaml
-kubectl apply -f ./gateway-helm/crds/generated
-```
-
-Update your `BackendTLSPolicy` and `GRPCRoute` resources according to Gateway-API [v1.1 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v11-upgrade-notes)
-
-Update your Envoy Gateway xPolicy resources: remove the namespace section from targetRef.
-
-Install Envoy Gateway v1.1.0:
-
-```shell
-helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 -n envoy-gateway-system
-```
-
## What to explore next?
In this quickstart, you have:
diff --git a/site/content/en/v1.1/tasks/security/backend-tls.md b/site/content/en/v1.1/tasks/security/backend-tls.md
index 53e9ccbd44a..3aadbc34714 100644
--- a/site/content/en/v1.1/tasks/security/backend-tls.md
+++ b/site/content/en/v1.1/tasks/security/backend-tls.md
@@ -25,11 +25,30 @@ Create a root certificate and private key to sign certificates:
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout ca.key -out ca.crt
```
-Create a certificate and a private key for `www.example.com`:
+Create a certificate and a private key for `www.example.com`.
+
+First, create an openssl configuration file:
+
+```shell
+cat > openssl.conf <the access logs will be sent. Currently only Service is supported. |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `logName` | _string_ | false | LogName defines the friendly name of the access log to be returned in StreamAccessLogsMessage.Identifier. This allows the access log server to differentiate between different access logs coming from the same Envoy. |
| `type` | _[ALSEnvoyProxyAccessLogType](#alsenvoyproxyaccesslogtype)_ | true | Type defines the type of accesslog. Supported types are "HTTP" and "TCP". |
| `http` | _[ALSEnvoyProxyHTTPAccessLogConfig](#alsenvoyproxyhttpaccesslogconfig)_ | false | HTTP defines additional configuration specific to HTTP access logs. |
@@ -124,6 +126,7 @@ _Appears in:_
| `type` | _[ActiveHealthCheckerType](#activehealthcheckertype)_ | true | Type defines the type of health checker. |
| `http` | _[HTTPActiveHealthChecker](#httpactivehealthchecker)_ | false | HTTP defines the configuration of http health checker. It's required while the health checker type is HTTP. |
| `tcp` | _[TCPActiveHealthChecker](#tcpactivehealthchecker)_ | false | TCP defines the configuration of tcp health checker. It's required while the health checker type is TCP. |
+| `grpc` | _[GRPCActiveHealthChecker](#grpcactivehealthchecker)_ | false | GRPC defines the configuration of the GRPC health checker. It's optional, and can only be used if the specified type is GRPC. |
#### ActiveHealthCheckPayload
@@ -171,6 +174,7 @@ _Appears in:_
| ----- | ----------- |
| `HTTP` | ActiveHealthCheckerTypeHTTP defines the HTTP type of health checking. |
| `TCP` | ActiveHealthCheckerTypeTCP defines the TCP type of health checking. |
+| `GRPC` | ActiveHealthCheckerTypeGRPC defines the GRPC type of health checking. |
#### AppProtocolType
@@ -273,22 +277,34 @@ _Appears in:_
| `status` | _[BackendStatus](#backendstatus)_ | true | Status defines the current status of Backend. |
+#### BackendCluster
+BackendCluster contains all the configuration required for configuring access
+to a backend. This can include multiple endpoints, and settings that apply for
+managing the connection to all these endpoints.
+
+_Appears in:_
+- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)
+- [ExtProc](#extproc)
+- [GRPCExtAuthService](#grpcextauthservice)
+- [HTTPExtAuthService](#httpextauthservice)
+- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog)
+- [ProxyOpenTelemetrySink](#proxyopentelemetrysink)
+- [TracingProvider](#tracingprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
-#### BackendConnection
-BackendConnection allows users to configure connection-level settings of backend
-_Appears in:_
-- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `bufferLimit` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | BufferLimit Soft limit on size of the cluster’s connections read and write buffers. BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space. If unspecified, an implementation defined default is applied (32768 bytes). For example, 20Mi, 1Gi, 256Ki etc. Note: that when the suffix is not provided, the value is interpreted as bytes. |
#### BackendEndpoint
@@ -333,6 +349,7 @@ BackendRef defines how an ObjectReference that is specific to BackendRef.
_Appears in:_
- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)
+- [BackendCluster](#backendcluster)
- [ExtProc](#extproc)
- [GRPCExtAuthService](#grpcextauthservice)
- [HTTPExtAuthService](#httpextauthservice)
@@ -347,6 +364,7 @@ _Appears in:_
| `name` | _[ObjectName](#objectname)_ | true | Name is the name of the referent. |
| `namespace` | _[Namespace](#namespace)_ | false | Namespace is the namespace of the backend. When unspecified, the local namespace is inferred.
Note that when a namespace different than the local namespace is specified, a ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details.
Support: Core |
| `port` | _[PortNumber](#portnumber)_ | false | Port specifies the destination port number to use for this resource. Port is required when the referent is a Kubernetes Service. In this case, the port number is the service port number, not the target port. For other resources, destination port might be derived from the referent resource or this field. |
+| `failover` | _boolean_ | false | Failover This indicates whether the backend is designated as a failover. Multiple failover backends can be configured. It is highly recommended to configure active or passive health checks to ensure that failover can be detected when the active backends become unhealthy and to automatically readjust once the primary backends are healthy again. The overprovisioning factor is set to 1.4, meaning the failover backends will only start receiving traffic when the health of the active backends falls below 72%. |
#### BackendSpec
@@ -447,19 +465,19 @@ _Appears in:_
| `targetRef` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the resource this policy is being attached to. This policy and the TargetRef MUST be in the same namespace for this Policy to have effect
Deprecated: use targetRefs/targetSelectors instead |
| `targetRefs` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName) array_ | true | TargetRefs are the names of the Gateway resources this policy is being attached to. |
| `targetSelectors` | _[TargetSelector](#targetselector) array_ | true | TargetSelectors allow targeting resources for this policy based on labels |
-| `rateLimit` | _[RateLimitSpec](#ratelimitspec)_ | false | RateLimit allows the user to limit the number of incoming requests to a predefined value based on attributes within the traffic flow. |
-| `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to the backend endpoints |
+| `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to the backend endpoints. Defaults to `LeastRequest`. |
| `proxyProtocol` | _[ProxyProtocol](#proxyprotocol)_ | false | ProxyProtocol enables the Proxy Protocol when communicating with the backend. |
| `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the upstream client connection. Disabled by default. |
| `healthCheck` | _[HealthCheck](#healthcheck)_ | false | HealthCheck allows gateway to perform active health checking on backends. |
-| `faultInjection` | _[FaultInjection](#faultinjection)_ | false | FaultInjection defines the fault injection policy to be applied. This configuration can be used to inject delays and abort requests to mimic failure scenarios such as service failures and overloads |
| `circuitBreaker` | _[CircuitBreaker](#circuitbreaker)_ | false | Circuit Breaker settings for the upstream connections and requests. If not set, circuit breakers will be enabled with the default thresholds |
-| `retry` | _[Retry](#retry)_ | false | Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions. If not set, retry will be disabled. |
-| `useClientProtocol` | _boolean_ | false | 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. |
| `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. |
| `connection` | _[BackendConnection](#backendconnection)_ | false | Connection includes backend connection settings. |
| `dns` | _[DNS](#dns)_ | false | DNS includes dns resolution settings. |
| `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration for backend connections. |
+| `rateLimit` | _[RateLimitSpec](#ratelimitspec)_ | false | RateLimit allows the user to limit the number of incoming requests to a predefined value based on attributes within the traffic flow. |
+| `faultInjection` | _[FaultInjection](#faultinjection)_ | false | FaultInjection defines the fault injection policy to be applied. This configuration can be used to inject delays and abort requests to mimic failure scenarios such as service failures and overloads |
+| `retry` | _[Retry](#retry)_ | false | Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions. If not set, retry will be disabled. |
+| `useClientProtocol` | _boolean_ | false | 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. |
#### BasicAuth
@@ -522,22 +540,6 @@ _Appears in:_
| `allowCredentials` | _boolean_ | true | AllowCredentials indicates whether a request can include user credentials like cookies, authentication headers, or TLS client certificates. |
-#### CircuitBreaker
-
-
-
-CircuitBreaker defines the Circuit Breaker configuration.
-
-_Appears in:_
-- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `maxConnections` | _integer_ | false | The maximum number of connections that Envoy will establish to the referenced backend defined within a xRoute rule. |
-| `maxPendingRequests` | _integer_ | false | The maximum number of pending requests that Envoy will queue to the referenced backend defined within a xRoute rule. |
-| `maxParallelRequests` | _integer_ | false | The maximum number of parallel requests that Envoy will make to the referenced backend defined within a xRoute rule. |
-| `maxParallelRetries` | _integer_ | false | The maximum number of parallel retries that Envoy will make to the referenced backend defined within a xRoute rule. |
-| `maxRequestsPerConnection` | _integer_ | false | The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule. Default: unlimited. |
#### ClaimToHeader
@@ -700,6 +702,37 @@ _Appears in:_
| `caCertificateRefs` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference) array_ | false | CACertificateRefs contains one or more references to Kubernetes objects that contain TLS certificates of the Certificate Authorities that can be used as a trust anchor to validate the certificates presented by the client.
A single reference to a Kubernetes ConfigMap or a Kubernetes Secret, with the CA certificate in a key named `ca.crt` is currently supported.
References to a resource in different namespace are invalid UNLESS there is a ReferenceGrant in the target namespace that allows the certificate to be attached. |
+#### ClusterSettings
+
+
+
+ClusterSettings provides the various knobs that can be set to control how traffic to a given
+backend will be configured.
+
+_Appears in:_
+- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog)
+- [BackendCluster](#backendcluster)
+- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
+- [ExtProc](#extproc)
+- [GRPCExtAuthService](#grpcextauthservice)
+- [HTTPExtAuthService](#httpextauthservice)
+- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog)
+- [ProxyOpenTelemetrySink](#proxyopentelemetrysink)
+- [TracingProvider](#tracingprovider)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to the backend endpoints. Defaults to `LeastRequest`. |
+| `proxyProtocol` | _[ProxyProtocol](#proxyprotocol)_ | false | ProxyProtocol enables the Proxy Protocol when communicating with the backend. |
+| `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the upstream client connection. Disabled by default. |
+| `healthCheck` | _[HealthCheck](#healthcheck)_ | false | HealthCheck allows gateway to perform active health checking on backends. |
+| `circuitBreaker` | _[CircuitBreaker](#circuitbreaker)_ | false | Circuit Breaker settings for the upstream connections and requests. If not set, circuit breakers will be enabled with the default thresholds |
+| `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. |
+| `connection` | _[BackendConnection](#backendconnection)_ | false | Connection includes backend connection settings. |
+| `dns` | _[DNS](#dns)_ | false | DNS includes dns resolution settings. |
+| `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration for backend connections. |
+
+
#### Compression
@@ -845,19 +878,6 @@ _Appears in:_
| `RequestHeader` | CustomTagTypeRequestHeader adds value from request header to each span. |
-#### DNS
-
-
-
-
-
-_Appears in:_
-- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `dnsRefreshRate` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | DNSRefreshRate specifies the rate at which DNS records should be refreshed. Defaults to 30 seconds. |
-| `respectDnsTtl` | _boolean_ | true | RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected. If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL. Defaults to true. |
#### EnvironmentCustomTag
@@ -945,6 +965,7 @@ _Appears in:_
| `envoy.filters.http.basic_auth` | EnvoyFilterBasicAuth defines the Envoy HTTP basic authentication filter. |
| `envoy.filters.http.oauth2` | EnvoyFilterOAuth2 defines the Envoy HTTP OAuth2 filter. |
| `envoy.filters.http.jwt_authn` | EnvoyFilterJWTAuthn defines the Envoy HTTP JWT authentication filter. |
+| `envoy.filters.http.stateful_session` | EnvoyFilterSessionPersistence defines the Envoy HTTP session persistence filter. |
| `envoy.filters.http.ext_proc` | EnvoyFilterExtProc defines the Envoy HTTP external process filter. |
| `envoy.filters.http.wasm` | EnvoyFilterWasm defines the Envoy HTTP WebAssembly filter. |
| `envoy.filters.http.rbac` | EnvoyFilterRBAC defines the Envoy RBAC filter. |
@@ -1403,7 +1424,7 @@ _Appears in:_
| `extraArgs` | _string array_ | false | ExtraArgs defines additional command line options that are provided to Envoy. More info: https://www.envoyproxy.io/docs/envoy/latest/operations/cli#command-line-options Note: some command line options are used internally(e.g. --log-level) so they cannot be provided here. |
| `mergeGateways` | _boolean_ | false | MergeGateways defines if Gateway resources should be merged onto the same Envoy Proxy Infrastructure. Setting this field to true would merge all Gateway Listeners under the parent Gateway Class. This means that the port, protocol and hostname tuple must be unique for every listener. If a duplicate listener is detected, the newer listener (based on timestamp) will be rejected and its status will be updated with a "Accepted=False" condition. |
| `shutdown` | _[ShutdownConfig](#shutdownconfig)_ | false | Shutdown defines configuration for graceful envoy shutdown process. |
-| `filterOrder` | _[FilterPosition](#filterposition) array_ | false | FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain. The FilterPosition in the list will be applied in the order they are defined. If unspecified, the default filter order is applied. Default filter order is:
- envoy.filters.http.health_check
- envoy.filters.http.fault
- envoy.filters.http.cors
- envoy.filters.http.ext_authz
- envoy.filters.http.basic_auth
- envoy.filters.http.oauth2
- envoy.filters.http.jwt_authn
- envoy.filters.http.ext_proc
- envoy.filters.http.wasm
- envoy.filters.http.rbac
- envoy.filters.http.local_ratelimit
- envoy.filters.http.ratelimit
- envoy.filters.http.router
Note: "envoy.filters.http.router" cannot be reordered, it's always the last filter in the chain. |
+| `filterOrder` | _[FilterPosition](#filterposition) array_ | false | FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain. The FilterPosition in the list will be applied in the order they are defined. If unspecified, the default filter order is applied. Default filter order is:
- envoy.filters.http.health_check
- envoy.filters.http.fault
- envoy.filters.http.cors
- envoy.filters.http.ext_authz
- envoy.filters.http.basic_auth
- envoy.filters.http.oauth2
- envoy.filters.http.jwt_authn
- envoy.filters.http.stateful_session
- envoy.filters.http.ext_proc
- envoy.filters.http.wasm
- envoy.filters.http.rbac
- envoy.filters.http.local_ratelimit
- envoy.filters.http.ratelimit
- envoy.filters.http.router
Note: "envoy.filters.http.router" cannot be reordered, it's always the last filter in the chain. |
| `backendTLS` | _[BackendTLSConfig](#backendtlsconfig)_ | false | BackendTLS is the TLS configuration for the Envoy proxy to use when connecting to backends. These settings are applied on backends for which TLS policies are specified. |
@@ -1464,7 +1485,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `backendRefs` | _[BackendRef](#backendref) array_ | true | BackendRefs defines the configuration of the external processing service |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `messageTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | MessageTimeout is the timeout for a response to be returned from the external processor Default: 200ms |
| `failOpen` | _boolean_ | false | FailOpen defines if requests or responses that cannot be processed due to connectivity to the external processor are terminated or passed-through. Default: false |
| `processingMode` | _[ExtProcProcessingMode](#extprocprocessingmode)_ | false | ProcessingMode defines how request and response body is processed Default: header and body are not sent to the external processor |
@@ -1678,6 +1701,20 @@ _Appears in:_
| `after` | _[EnvoyFilter](#envoyfilter)_ | true | After defines the filter that should come after the filter. Only one of Before or After must be set. |
+#### GRPCActiveHealthChecker
+
+
+
+GRPCActiveHealthChecker defines the settings of the GRPC health check.
+
+_Appears in:_
+- [ActiveHealthCheck](#activehealthcheck)
+
+| Field | Type | Required | Description |
+| --- | --- | --- | --- |
+| `service` | _string_ | false | Service to send in the health check request. If this is not specified, then the health check request applies to the entire server and not to a specific service. |
+
+
#### GRPCExtAuthService
@@ -1691,8 +1728,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent. Only Service kind is supported for now.
Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. Only Service kind is supported for now. |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
#### Gateway
@@ -1784,22 +1822,6 @@ _Appears in:_
| `http10` | _[HTTP10Settings](#http10settings)_ | false | HTTP10 turns on support for HTTP/1.0 and HTTP/0.9 requests. |
-#### HTTP2Settings
-
-
-
-HTTP2Settings provides HTTP/2 configuration for listeners and backends.
-
-_Appears in:_
-- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
-- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `initialStreamWindowSize` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | InitialStreamWindowSize sets the initial window size for HTTP/2 streams. If not set, the default value is 64 KiB(64*1024). |
-| `initialConnectionWindowSize` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. If not set, the default value is 1 MiB. |
-| `maxConcurrentStreams` | _integer_ | false | MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. If not set, the default value is 100. |
-| `onInvalidMessage` | _[InvalidMessageAction](#invalidmessageaction)_ | false | OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error It's recommended for L2 Envoy deployments to set this value to TerminateStream. https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two Default: TerminateConnection |
#### HTTP3Settings
@@ -1856,8 +1878,9 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
-| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent. Only Service kind is supported for now.
Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. Only Service kind is supported for now. |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `path` | _string_ | true | Path is the path of the HTTP External Authorization service. If path is specified, the authorization request will be sent to that path, or else the authorization request will be sent to the root path. |
| `headersToBackend` | _string array_ | false | HeadersToBackend are the authorization response headers that will be added to the original client request before sending it to the backend server. Note that coexisting headers will be overridden. If not specified, no authorization response headers will be added to the original client request. |
@@ -1954,22 +1977,9 @@ _Appears in:_
| `xForwardedClientCert` | _[XForwardedClientCert](#xforwardedclientcert)_ | false | XForwardedClientCert configures how Envoy Proxy handle the x-forwarded-client-cert (XFCC) HTTP header.
x-forwarded-client-cert (XFCC) is an HTTP header used to forward the certificate information of part or all of the clients or proxies that a request has flowed through, on its way from the client to the server.
Envoy proxy may choose to sanitize/append/forward the XFCC header before proxying the request.
If not set, the default behavior is sanitizing the XFCC header. |
| `withUnderscoresAction` | _[WithUnderscoresAction](#withunderscoresaction)_ | false | WithUnderscoresAction configures the action to take when an HTTP header with underscores is encountered. The default action is to reject the request. |
| `preserveXRequestID` | _boolean_ | false | PreserveXRequestID configures Envoy to keep the X-Request-ID header if passed for a request that is edge (Edge request is the request from external clients to front Envoy) and not reset it, which is the current Envoy behaviour. It defaults to false. |
+| `earlyRequestHeaders` | _[HTTPHeaderFilter](#httpheaderfilter)_ | false | EarlyRequestHeaders defines settings for early request header modification, before envoy performs routing, tracing and built-in header manipulation. |
-#### HealthCheck
-
-
-
-HealthCheck configuration to decide which endpoints
-are healthy and can be used for routing.
-
-_Appears in:_
-- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `active` | _[ActiveHealthCheck](#activehealthcheck)_ | false | Active health check configuration |
-| `passive` | _[PassiveHealthCheck](#passivehealthcheck)_ | false | Passive passive check configuration |
#### HealthCheckSettings
@@ -2076,7 +2086,8 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `op` | _[JSONPatchOperationType](#jsonpatchoperationtype)_ | true | Op is the type of operation to perform |
-| `path` | _string_ | true | Path is the location of the target document/field where the operation will be performed Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. |
+| `path` | _string_ | false | Path is the location of the target document/field where the operation will be performed Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. |
+| `jsonPath` | _string_ | false | JSONPath specifies the locations of the target document/field where the operation will be performed Refer to https://datatracker.ietf.org/doc/rfc9535/ for more details. |
| `from` | _string_ | false | From is the source location of the value to be copied or moved. Only valid for move or copy operations Refer to https://datatracker.ietf.org/doc/html/rfc6901 for more details. |
| `value` | _[JSON](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#json-v1-apiextensions-k8s-io)_ | false | Value is the new value of the path location. The value is only used by the `add` and `replace` operations. |
@@ -2384,20 +2395,6 @@ _Appears in:_
| `value` | _string_ | true | Value defines the hard-coded value to add to each span. |
-#### LoadBalancer
-
-
-
-LoadBalancer defines the load balancer policy to be applied.
-
-_Appears in:_
-- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `type` | _[LoadBalancerType](#loadbalancertype)_ | true | Type decides the type of Load Balancer policy. Valid LoadBalancerType values are "ConsistentHash", "LeastRequest", "Random", "RoundRobin". |
-| `consistentHash` | _[ConsistentHash](#consistenthash)_ | false | ConsistentHash defines the configuration when the load balancer type is set to ConsistentHash |
-| `slowStart` | _[SlowStart](#slowstart)_ | false | SlowStart defines the configuration related to the slow start load balancer policy. If set, during slow start window, traffic sent to the newly added hosts will gradually increase. Currently this is only supported for RoundRobin and LeastRequest load balancers |
#### LoadBalancerType
@@ -2533,9 +2530,11 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `host` | _string_ | false | Host define the extension service hostname. Deprecated: Use BackendRefs instead. |
| `port` | _integer_ | false | Port defines the port the extension service is exposed on. Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the access log will be sent. Only Service kind is supported for now. |
| `resources` | _object (keys:string, values:string)_ | false | Resources is a set of labels that describe the source of a log entry, including envoy node info. It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). |
@@ -2890,9 +2889,11 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.
Deprecated: Use BackendRefs instead. |
+| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. |
+| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection to the backend. |
| `host` | _string_ | false | Host define the service hostname. Deprecated: Use BackendRefs instead. |
| `port` | _integer_ | false | Port defines the port the service is exposed on. Deprecated: Use BackendRefs instead. |
-| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the backend server to which the metric will be sent. Only Service kind is supported for now. |
#### ProxyPrometheusProvider
@@ -2910,19 +2911,6 @@ _Appears in:_
| `compression` | _[Compression](#compression)_ | false | Configure the compression on Prometheus endpoint. Compression is useful in situations when bandwidth is scarce and large payloads can be effectively compressed at the expense of higher CPU load. |
-#### ProxyProtocol
-
-
-
-ProxyProtocol defines the configuration related to the proxy protocol
-when communicating with the backend.
-
-_Appears in:_
-- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `version` | _[ProxyProtocolVersion](#proxyprotocolversion)_ | true | Version of ProxyProtol Valid ProxyProtocolVersion values are "V1" "V2" |
#### ProxyProtocolVersion
@@ -3528,21 +3516,6 @@ _Appears in:_
| `idleTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | IdleTimeout for a TCP connection. Idle time is defined as a period in which there are no bytes sent or received on either the upstream or downstream connection. Default: 1 hour. |
-#### TCPKeepalive
-
-
-
-TCPKeepalive define the TCP Keepalive configuration.
-
-_Appears in:_
-- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
-- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `probes` | _integer_ | false | The total number of unacknowledged probes to send before deciding the connection is dead. Defaults to 9. |
-| `idleTime` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | The duration a connection needs to be idle before keep-alive probes start being sent. The duration format is Defaults to `7200s`. |
-| `interval` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | The duration between keep-alive probes. Defaults to `75s`. |
#### TCPTimeout
@@ -3619,19 +3592,6 @@ _Appears in:_
| `matchLabels` | _object (keys:string, values:string)_ | true | MatchLabels are the set of label selectors for identifying the targeted resource |
-#### Timeout
-
-
-
-Timeout defines configuration for timeouts related to connections.
-
-_Appears in:_
-- [BackendTrafficPolicySpec](#backendtrafficpolicyspec)
-
-| Field | Type | Required | Description |
-| --- | --- | --- | --- |
-| `tcp` | _[TCPTimeout](#tcptimeout)_ | false | Timeout settings for TCP. |
-| `http` | _[HTTPTimeout](#httptimeout)_ | false | Timeout settings for HTTP. |
#### TracingProvider
@@ -3645,10 +3605,12 @@ _Appears in:_
| Field | Type | Required | Description |
| --- | --- | --- | --- |
+| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | false | BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent.