diff --git a/VERSION b/VERSION
index b8db7fc27e..2e7bd91085 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-v1.5.0-rc.1
+v1.5.0
diff --git a/api/v1alpha1/backendtrafficpolicy_types.go b/api/v1alpha1/backendtrafficpolicy_types.go
index c107e3cf57..c975b122cc 100644
--- a/api/v1alpha1/backendtrafficpolicy_types.go
+++ b/api/v1alpha1/backendtrafficpolicy_types.go
@@ -74,8 +74,11 @@ type BackendTrafficPolicySpec struct {
// The compression config for the http streams.
//
+ // +patchMergeKey=type
+ // +patchStrategy=merge
+ //
// +optional
- Compression []*Compression `json:"compression,omitempty"`
+ Compression []*Compression `json:"compression,omitempty" patchMergeKey:"type" patchStrategy:"merge"`
// ResponseOverride defines the configuration to override specific responses with a custom one.
// If multiple configurations are specified, the first one to match wins.
diff --git a/api/v1alpha1/clienttrafficpolicy_types.go b/api/v1alpha1/clienttrafficpolicy_types.go
index 649b4b635f..abc7d59dfb 100644
--- a/api/v1alpha1/clienttrafficpolicy_types.go
+++ b/api/v1alpha1/clienttrafficpolicy_types.go
@@ -7,7 +7,6 @@ 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"
)
@@ -159,7 +158,7 @@ type HeaderSettings struct {
// routing, tracing and built-in header manipulation.
//
// +optional
- EarlyRequestHeaders *gwapiv1.HTTPHeaderFilter `json:"earlyRequestHeaders,omitempty"`
+ EarlyRequestHeaders *HTTPHeaderFilter `json:"earlyRequestHeaders,omitempty"`
}
// WithUnderscoresAction configures the action to take when an HTTP header with underscores
diff --git a/api/v1alpha1/cors_types.go b/api/v1alpha1/cors_types.go
index 26c87bd8a0..c3d2067511 100644
--- a/api/v1alpha1/cors_types.go
+++ b/api/v1alpha1/cors_types.go
@@ -5,7 +5,7 @@
package v1alpha1
-import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+import gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
// Origin is defined by the scheme (protocol), hostname (domain), and port of
// the URL used to access it. The hostname can be "precise" which is just the
@@ -61,7 +61,7 @@ type CORS struct {
// It specifies the value in the Access-Control-Max-Age CORS response header..
//
// +optional
- MaxAge *metav1.Duration `json:"maxAge,omitempty"`
+ MaxAge *gwapiv1.Duration `json:"maxAge,omitempty"`
// AllowCredentials indicates whether a request can include user credentials
// like cookies, authentication headers, or TLS client certificates.
diff --git a/api/v1alpha1/dns_types.go b/api/v1alpha1/dns_types.go
index ed99a6ca0e..2dbfd272e5 100644
--- a/api/v1alpha1/dns_types.go
+++ b/api/v1alpha1/dns_types.go
@@ -5,7 +5,7 @@
package v1alpha1
-import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+import gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
// DNSLookupFamily defines the behavior of Envoy when resolving DNS for hostnames
// +enum
@@ -31,10 +31,14 @@ const (
type DNS struct {
// DNSRefreshRate specifies the rate at which DNS records should be refreshed.
// Defaults to 30 seconds.
- DNSRefreshRate *metav1.Duration `json:"dnsRefreshRate,omitempty"`
+ //
+ // +optional
+ DNSRefreshRate *gwapiv1.Duration `json:"dnsRefreshRate,omitempty"`
// 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.
+ //
+ // +optional
RespectDNSTTL *bool `json:"respectDnsTtl,omitempty"`
// LookupFamily determines how Envoy would resolve DNS for Routes where the backend is specified as a fully qualified domain name (FQDN).
// If set, this configuration overrides other defaults.
diff --git a/api/v1alpha1/envoygateway_helpers.go b/api/v1alpha1/envoygateway_helpers.go
index 05a58fcbdc..f33875ce0c 100644
--- a/api/v1alpha1/envoygateway_helpers.go
+++ b/api/v1alpha1/envoygateway_helpers.go
@@ -109,6 +109,16 @@ func (e *EnvoyGateway) GatewayNamespaceMode() bool {
*e.Provider.Kubernetes.Deploy.Type == KubernetesDeployModeTypeGatewayNamespace
}
+// TopologyInjectorDisabled checks whether the provided EnvoyGateway disables TopologyInjector
+func (e *EnvoyGateway) TopologyInjectorDisabled() bool {
+ if e.Provider != nil &&
+ e.Provider.Kubernetes != nil &&
+ e.Provider.Kubernetes.TopologyInjector != nil {
+ return ptr.Deref(e.Provider.Kubernetes.TopologyInjector.Disable, false)
+ }
+ return false
+}
+
// defaultRuntimeFlags are the default runtime flags for Envoy Gateway.
var defaultRuntimeFlags = map[RuntimeFlag]bool{
XDSNameSchemeV2: false,
diff --git a/api/v1alpha1/envoygateway_types.go b/api/v1alpha1/envoygateway_types.go
index 86a6c1f4ea..a59a35658e 100644
--- a/api/v1alpha1/envoygateway_types.go
+++ b/api/v1alpha1/envoygateway_types.go
@@ -143,13 +143,21 @@ type KubernetesClientRateLimit struct {
// LeaderElection defines the desired leader election settings.
type LeaderElection struct {
// LeaseDuration defines the time non-leader contenders will wait before attempting to claim leadership.
- // It's based on the timestamp of the last acknowledged signal. The default setting is 15 seconds.
+ // It's based on the timestamp of the last acknowledged signal.
+ // The default setting is 15 seconds.
+ //
+ // +optional
LeaseDuration *gwapiv1.Duration `json:"leaseDuration,omitempty"`
// RenewDeadline represents the time frame within which the current leader will attempt to renew its leadership
- // status before relinquishing its position. The default setting is 10 seconds.
+ // status before relinquishing its position.
+ // The default setting is 10 seconds.
+ //
+ // +optional
RenewDeadline *gwapiv1.Duration `json:"renewDeadline,omitempty"`
// RetryPeriod denotes the interval at which LeaderElector clients should perform action retries.
// The default setting is 2 seconds.
+ //
+ // +optional
RetryPeriod *gwapiv1.Duration `json:"retryPeriod,omitempty"`
// Disable provides the option to turn off leader election, which is enabled by default.
Disable *bool `json:"disable,omitempty"`
@@ -173,7 +181,7 @@ type EnvoyGatewayLogging struct {
}
// EnvoyGatewayLogComponent defines a component that supports a configured logging level.
-// +kubebuilder:validation:Enum=default;provider;gateway-api;xds-translator;xds-server;infrastructure;global-ratelimit
+// +kubebuilder:validation:Enum=default;provider;gateway-api;xds-translator;xds-server;xds;infrastructure;global-ratelimit
type EnvoyGatewayLogComponent string
const (
@@ -193,6 +201,9 @@ const (
// LogComponentXdsServerRunner defines the "xds-server" runner component.
LogComponentXdsServerRunner EnvoyGatewayLogComponent = "xds-server"
+ // LogComponentXdsRunner defines the "xds" runner component.
+ LogComponentXdsRunner EnvoyGatewayLogComponent = "xds"
+
// LogComponentInfrastructureRunner defines the "infrastructure" runner component.
LogComponentInfrastructureRunner EnvoyGatewayLogComponent = "infrastructure"
@@ -432,9 +443,9 @@ type RateLimit struct {
// Timeout specifies the timeout period for the proxy to access the ratelimit server
// If not set, timeout is 20ms.
+ //
// +optional
- // +kubebuilder:validation:Format=duration
- Timeout *metav1.Duration `json:"timeout,omitempty"`
+ Timeout *gwapiv1.Duration `json:"timeout,omitempty"`
// FailClosed is a switch used to control the flow of traffic
// when the response from the ratelimit server cannot be obtained.
diff --git a/api/v1alpha1/envoyproxy_types.go b/api/v1alpha1/envoyproxy_types.go
index 20baa32df2..8eeabc6427 100644
--- a/api/v1alpha1/envoyproxy_types.go
+++ b/api/v1alpha1/envoyproxy_types.go
@@ -272,6 +272,12 @@ const (
// EnvoyFilterRateLimit defines the Envoy HTTP rate limit filter.
EnvoyFilterRateLimit EnvoyFilter = "envoy.filters.http.ratelimit"
+ // EnvoyFilterGRPCWeb defines the Envoy HTTP gRPC-web filter.
+ EnvoyFilterGRPCWeb EnvoyFilter = "envoy.filters.http.grpc_web"
+
+ // EnvoyFilterGRPCStats defines the Envoy HTTP gRPC stats filter.
+ EnvoyFilterGRPCStats EnvoyFilter = "envoy.filters.http.grpc_stats"
+
// EnvoyFilterCustomResponse defines the Envoy HTTP custom response filter.
EnvoyFilterCustomResponse EnvoyFilter = "envoy.filters.http.custom_response"
@@ -344,12 +350,12 @@ type ShutdownConfig struct {
// If unspecified, defaults to 60 seconds.
//
// +optional
- DrainTimeout *metav1.Duration `json:"drainTimeout,omitempty"`
+ DrainTimeout *gwapiv1.Duration `json:"drainTimeout,omitempty"`
// MinDrainDuration defines the minimum drain duration allowing time for endpoint deprogramming to complete.
// If unspecified, defaults to 10 seconds.
//
// +optional
- MinDrainDuration *metav1.Duration `json:"minDrainDuration,omitempty"`
+ MinDrainDuration *gwapiv1.Duration `json:"minDrainDuration,omitempty"`
}
// +kubebuilder:validation:XValidation:rule="((has(self.envoyDeployment) && !has(self.envoyDaemonSet)) || (!has(self.envoyDeployment) && has(self.envoyDaemonSet))) || (!has(self.envoyDeployment) && !has(self.envoyDaemonSet))",message="only one of envoyDeployment or envoyDaemonSet can be specified"
diff --git a/api/v1alpha1/fault_injection.go b/api/v1alpha1/fault_injection.go
index a8b7e1f541..eab92714c5 100644
--- a/api/v1alpha1/fault_injection.go
+++ b/api/v1alpha1/fault_injection.go
@@ -5,7 +5,7 @@
package v1alpha1
-import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+import gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
// 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
@@ -29,7 +29,7 @@ type FaultInjectionDelay struct {
// FixedDelay specifies the fixed delay duration
//
// +required
- FixedDelay *metav1.Duration `json:"fixedDelay"`
+ FixedDelay *gwapiv1.Duration `json:"fixedDelay"`
// Percentage specifies the percentage of requests to be delayed. Default 100%, if set 0, no requests will be delayed. Accuracy to 0.0001%.
// +optional
diff --git a/api/v1alpha1/healthcheck_types.go b/api/v1alpha1/healthcheck_types.go
index 772e781664..d0893e7cf5 100644
--- a/api/v1alpha1/healthcheck_types.go
+++ b/api/v1alpha1/healthcheck_types.go
@@ -5,10 +5,7 @@
package v1alpha1
-import (
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
-)
+import gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
// HealthCheck configuration to decide which endpoints
// are healthy and can be used for routing.
@@ -42,10 +39,9 @@ type PassiveHealthCheck struct {
// Interval defines the time between passive health checks.
//
- // +kubebuilder:validation:Format=duration
// +kubebuilder:default="3s"
// +optional
- Interval *metav1.Duration `json:"interval,omitempty"`
+ Interval *gwapiv1.Duration `json:"interval,omitempty"`
// 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.
@@ -68,10 +64,9 @@ type PassiveHealthCheck struct {
// BaseEjectionTime defines the base duration for which a host will be ejected on consecutive failures.
//
- // +kubebuilder:validation:Format=duration
// +kubebuilder:default="30s"
// +optional
- BaseEjectionTime *metav1.Duration `json:"baseEjectionTime,omitempty"`
+ BaseEjectionTime *gwapiv1.Duration `json:"baseEjectionTime,omitempty"`
// MaxEjectionPercent sets the maximum percentage of hosts in a cluster that can be ejected.
//
@@ -90,22 +85,19 @@ type PassiveHealthCheck struct {
type ActiveHealthCheck struct {
// Timeout defines the time to wait for a health check response.
//
- // +kubebuilder:validation:Format=duration
// +kubebuilder:default="1s"
// +optional
- Timeout *metav1.Duration `json:"timeout"`
+ Timeout *gwapiv1.Duration `json:"timeout"`
// Interval defines the time between active health checks.
//
- // +kubebuilder:validation:Format=duration
// +kubebuilder:default="3s"
// +optional
- Interval *metav1.Duration `json:"interval"`
+ Interval *gwapiv1.Duration `json:"interval"`
// InitialJitter defines the maximum time Envoy will wait before the first health check.
// Envoy will randomly select a value between 0 and the initial jitter value.
//
- // +kubebuilder:validation:Format=duration
// +optional
InitialJitter *gwapiv1.Duration `json:"initialJitter,omitempty"`
diff --git a/api/v1alpha1/loadbalancer_types.go b/api/v1alpha1/loadbalancer_types.go
index fd52391505..2b177d49da 100644
--- a/api/v1alpha1/loadbalancer_types.go
+++ b/api/v1alpha1/loadbalancer_types.go
@@ -5,7 +5,7 @@
package v1alpha1
-import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+import gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
// LoadBalancer defines the load balancer policy to be applied.
// +union
@@ -47,7 +47,6 @@ type LoadBalancer struct {
// ZoneAware defines the configuration related to the distribution of requests between locality zones.
//
// +optional
- // +notImplementedHide
ZoneAware *ZoneAware `json:"zoneAware,omitempty"`
}
@@ -120,7 +119,7 @@ type Cookie struct {
// Max-Age attribute value.
//
// +optional
- TTL *metav1.Duration `json:"ttl,omitempty"`
+ TTL *gwapiv1.Duration `json:"ttl,omitempty"`
// Additional Attributes to set for the generated cookie.
//
// +optional
@@ -147,7 +146,7 @@ type SlowStart struct {
// 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
// +kubebuilder:validation:Required
- Window *metav1.Duration `json:"window"`
+ Window *gwapiv1.Duration `json:"window"`
// TODO: Add support for non-linear traffic increases based on user usage.
}
@@ -156,7 +155,6 @@ type ZoneAware struct {
// PreferLocalZone configures zone-aware routing to prefer sending traffic to the local locality zone.
//
// +optional
- // +notImplementedHide
PreferLocal *PreferLocalZone `json:"preferLocal,omitempty"`
}
@@ -166,13 +164,11 @@ type PreferLocalZone struct {
// which maintains equal distribution among upstream endpoints while sending as much traffic as possible locally.
//
// +optional
- // +notImplementedHide
Force *ForceLocalZone `json:"force,omitempty"`
// MinEndpointsThreshold is the minimum number of total upstream endpoints across all zones required to enable zone-aware routing.
//
// +optional
- // +notImplementedHide
MinEndpointsThreshold *uint64 `json:"minEndpointsThreshold,omitempty"`
}
diff --git a/api/v1alpha1/oidc_types.go b/api/v1alpha1/oidc_types.go
index 64ec47b1d2..23f84ae2b9 100644
--- a/api/v1alpha1/oidc_types.go
+++ b/api/v1alpha1/oidc_types.go
@@ -6,7 +6,6 @@
package v1alpha1
import (
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
)
@@ -110,7 +109,7 @@ type OIDC struct {
// OAuth flow will fail.
//
// +optional
- DefaultTokenTTL *metav1.Duration `json:"defaultTokenTTL,omitempty"`
+ DefaultTokenTTL *gwapiv1.Duration `json:"defaultTokenTTL,omitempty"`
// RefreshToken indicates whether the Envoy should automatically refresh the
// id token and access token when they expire.
@@ -127,8 +126,9 @@ type OIDC struct {
//
// If not specified, defaults to 604800s (one week).
// Note: this field is only applicable when the "refreshToken" field is set to true.
+ //
// +optional
- DefaultRefreshTokenTTL *metav1.Duration `json:"defaultRefreshTokenTTL,omitempty"`
+ DefaultRefreshTokenTTL *gwapiv1.Duration `json:"defaultRefreshTokenTTL,omitempty"`
// Skips OIDC authentication when the request contains a header that will be extracted by the JWT filter. Unless
// explicitly stated otherwise in the extractFrom field, this will be the "Authorization: Bearer ..." header.
@@ -232,6 +232,5 @@ const (
type OIDCCookieConfig struct {
// +optional
// +kubebuilder:validation:Enum=Lax;Strict;None
- // +kubebuilder:default=Strict
SameSite *string `json:"sameSite,omitempty"`
}
diff --git a/api/v1alpha1/ratelimit_types.go b/api/v1alpha1/ratelimit_types.go
index d3cd36bca2..acf55c9ca7 100644
--- a/api/v1alpha1/ratelimit_types.go
+++ b/api/v1alpha1/ratelimit_types.go
@@ -285,9 +285,9 @@ type RateLimitValue struct {
}
// RateLimitUnit specifies the intervals for setting rate limits.
-// Valid RateLimitUnit values are "Second", "Minute", "Hour", and "Day".
+// Valid RateLimitUnit values are "Second", "Minute", "Hour", "Day", "Month" and "Year".
//
-// +kubebuilder:validation:Enum=Second;Minute;Hour;Day
+// +kubebuilder:validation:Enum=Second;Minute;Hour;Day;Month;Year
type RateLimitUnit string
// RateLimitUnit constants.
@@ -303,4 +303,10 @@ const (
// RateLimitUnitDay specifies the rate limit interval to be 1 day.
RateLimitUnitDay RateLimitUnit = "Day"
+
+ // RateLimitUnitMonth specifies the rate limit interval to be 1 month.
+ RateLimitUnitMonth RateLimitUnit = "Month"
+
+ // RateLimitUnitYear specifies the rate limit interval to be 1 year.
+ RateLimitUnitYear RateLimitUnit = "Year"
)
diff --git a/api/v1alpha1/retry_types.go b/api/v1alpha1/retry_types.go
index d5f3eb24d3..17439c7fae 100644
--- a/api/v1alpha1/retry_types.go
+++ b/api/v1alpha1/retry_types.go
@@ -6,7 +6,7 @@
package v1alpha1
import (
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
)
// Retry defines the retry strategy to be applied.
@@ -96,8 +96,7 @@ type PerRetryPolicy struct {
// Timeout is the timeout per retry attempt.
//
// +optional
- // +kubebuilder:validation:Format=duration
- Timeout *metav1.Duration `json:"timeout,omitempty"`
+ Timeout *gwapiv1.Duration `json:"timeout,omitempty"`
// Backoff is the backoff policy to be applied per retry attempt. gateway uses a fully jittered exponential
// back-off algorithm for retries. For additional details,
// see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#config-http-filters-router-x-envoy-max-retries
@@ -109,13 +108,12 @@ type PerRetryPolicy struct {
type BackOffPolicy struct {
// BaseInterval is the base interval between retries.
//
- // +kubebuilder:validation:Format=duration
- BaseInterval *metav1.Duration `json:"baseInterval,omitempty"`
+ // +optional
+ BaseInterval *gwapiv1.Duration `json:"baseInterval,omitempty"`
// MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
// The default is 10 times the base_interval
//
// +optional
- // +kubebuilder:validation:Format=duration
- MaxInterval *metav1.Duration `json:"maxInterval,omitempty"`
+ MaxInterval *gwapiv1.Duration `json:"maxInterval,omitempty"`
// we can add rate limited based backoff config here if we want to.
}
diff --git a/api/v1alpha1/shared_types.go b/api/v1alpha1/shared_types.go
index 08ca30976d..de0e778577 100644
--- a/api/v1alpha1/shared_types.go
+++ b/api/v1alpha1/shared_types.go
@@ -24,7 +24,7 @@ const (
// DefaultDeploymentMemoryResourceRequests for deployment memory resource
DefaultDeploymentMemoryResourceRequests = "512Mi"
// DefaultEnvoyProxyImage is the default image used by envoyproxy
- DefaultEnvoyProxyImage = "docker.io/envoyproxy/envoy:distroless-dev"
+ DefaultEnvoyProxyImage = "docker.io/envoyproxy/envoy:distroless-v1.35.3"
// DefaultShutdownManagerCPUResourceRequests for shutdown manager cpu resource
DefaultShutdownManagerCPUResourceRequests = "10m"
// DefaultShutdownManagerMemoryResourceRequests for shutdown manager memory resource
@@ -32,7 +32,7 @@ const (
// DefaultShutdownManagerImage is the default image used for the shutdown manager.
DefaultShutdownManagerImage = "docker.io/envoyproxy/gateway-dev:latest"
// DefaultRateLimitImage is the default image used by ratelimit.
- DefaultRateLimitImage = "docker.io/envoyproxy/ratelimit:master"
+ DefaultRateLimitImage = "docker.io/envoyproxy/ratelimit:e74a664a"
// HTTPProtocol is the common-used http protocol.
HTTPProtocol = "http"
// GRPCProtocol is the common-used grpc protocol.
@@ -231,7 +231,7 @@ type KubernetesContainerSpec struct {
// Image specifies the EnvoyProxy container image to be used including a tag, instead of the default image.
// This field is mutually exclusive with ImageRepository.
//
- // +kubebuilder:validation:XValidation:rule="self.matches('^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$')",message="Image must include a tag and allowed characters only (e.g., 'repo:tag')."
+ // +kubebuilder:validation:XValidation:rule="self.matches('^[a-zA-Z0-9._-]+(:[0-9]+)?(/[a-zA-Z0-9._/-]+)?(:[a-zA-Z0-9._-]+)?(@sha256:[a-z0-9]+)?$')",message="Image must include a tag and allowed characters only (e.g., 'repo:tag')."
// +optional
Image *string `json:"image,omitempty"`
@@ -239,7 +239,7 @@ type KubernetesContainerSpec struct {
// The default tag will be used.
// This field is mutually exclusive with Image.
//
- // +kubebuilder:validation:XValidation:rule="self.matches('^[a-zA-Z0-9._/-]+$')",message="ImageRepository must contain only allowed characters and must not include a tag or any colons."
+ // +kubebuilder:validation:XValidation:rule="self.matches('^[a-zA-Z0-9._-]+(:[0-9]+)?[a-zA-Z0-9._/-]+$')",message="ImageRepository must contain only allowed characters and must not include a tag."
// +optional
ImageRepository *string `json:"imageRepository,omitempty"`
@@ -516,8 +516,7 @@ type KubernetesHorizontalPodAutoscalerSpec struct {
// HTTPStatus defines the http status code.
// +kubebuilder:validation:Minimum=100
-// +kubebuilder:validation:Maximum=600
-// +kubebuilder:validation:ExclusiveMaximum=true
+// +kubebuilder:validation:Maximum=599
type HTTPStatus int
// MergeType defines the type of merge operation
@@ -871,3 +870,84 @@ type CustomRedirect struct {
// +kubebuilder:validation:Enum=301;302
StatusCode *int `json:"statusCode,omitempty"`
}
+
+// HTTPHeaderFilter has been copied from the upstream Gateway API project
+// https://github.com/kubernetes-sigs/gateway-api/blob/main/apis/v1/httproute_types.go
+// and edited to increase the maxItems from 16 to 64
+// Remove this definition and reuse the upstream one once it supports items more than 64
+
+// HTTPHeaderFilter defines a filter that modifies the headers of an HTTP
+// request or response. Only one action for a given header name is
+// permitted. Filters specifying multiple actions of the same or different
+// type for any one header name are invalid. Configuration to set or add
+// multiple values for a header must use RFC 7230 header value formatting,
+// separating each value with a comma.
+type HTTPHeaderFilter struct {
+ // 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
+ //
+ // +optional
+ // +listType=map
+ // +listMapKey=name
+ // +kubebuilder:validation:MaxItems=64
+ Set []gwapiv1.HTTPHeader `json:"set,omitempty"`
+
+ // 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
+ //
+ // +optional
+ // +listType=map
+ // +listMapKey=name
+ // +kubebuilder:validation:MaxItems=64
+ Add []gwapiv1.HTTPHeader `json:"add,omitempty"`
+
+ // 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
+ //
+ // +optional
+ // +listType=set
+ // +kubebuilder:validation:MaxItems=64
+ Remove []string `json:"remove,omitempty"`
+}
diff --git a/api/v1alpha1/validation/envoygateway_validate.go b/api/v1alpha1/validation/envoygateway_validate.go
index 3814b78fa4..37d9b63b5a 100644
--- a/api/v1alpha1/validation/envoygateway_validate.go
+++ b/api/v1alpha1/validation/envoygateway_validate.go
@@ -144,6 +144,7 @@ func validateEnvoyGatewayLogging(logging *egv1a1.EnvoyGatewayLogging) error {
egv1a1.LogComponentGatewayAPIRunner,
egv1a1.LogComponentXdsTranslatorRunner,
egv1a1.LogComponentXdsServerRunner,
+ egv1a1.LogComponentXdsRunner,
egv1a1.LogComponentInfrastructureRunner,
egv1a1.LogComponentGlobalRateLimitRunner:
switch logLevel {
@@ -152,7 +153,7 @@ func validateEnvoyGatewayLogging(logging *egv1a1.EnvoyGatewayLogging) error {
return fmt.Errorf("envoy gateway logging level invalid. valid options: info/debug/warn/error")
}
default:
- return fmt.Errorf("envoy gateway logging components invalid. valid options: system/provider/gateway-api/xds-translator/xds-server/infrastructure")
+ return fmt.Errorf("envoy gateway logging components invalid. valid options: system/provider/gateway-api/xds-translator/xds-server/xds/infrastructure")
}
}
return nil
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 4ec48585c8..cdbb72f622 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -126,12 +126,12 @@ func (in *ActiveHealthCheck) DeepCopyInto(out *ActiveHealthCheck) {
*out = *in
if in.Timeout != nil {
in, out := &in.Timeout, &out.Timeout
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.Interval != nil {
in, out := &in.Interval, &out.Interval
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.InitialJitter != nil {
@@ -279,12 +279,12 @@ func (in *BackOffPolicy) DeepCopyInto(out *BackOffPolicy) {
*out = *in
if in.BaseInterval != nil {
in, out := &in.BaseInterval, &out.BaseInterval
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.MaxInterval != nil {
in, out := &in.MaxInterval, &out.MaxInterval
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
}
@@ -826,7 +826,7 @@ func (in *CORS) DeepCopyInto(out *CORS) {
}
if in.MaxAge != nil {
in, out := &in.MaxAge, &out.MaxAge
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.AllowCredentials != nil {
@@ -1379,7 +1379,7 @@ func (in *Cookie) DeepCopyInto(out *Cookie) {
*out = *in
if in.TTL != nil {
in, out := &in.TTL, &out.TTL
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.Attributes != nil {
@@ -1578,7 +1578,7 @@ func (in *DNS) DeepCopyInto(out *DNS) {
*out = *in
if in.DNSRefreshRate != nil {
in, out := &in.DNSRefreshRate, &out.DNSRefreshRate
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.RespectDNSTTL != nil {
@@ -2934,7 +2934,7 @@ func (in *FaultInjectionDelay) DeepCopyInto(out *FaultInjectionDelay) {
*out = *in
if in.FixedDelay != nil {
in, out := &in.FixedDelay, &out.FixedDelay
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.Percentage != nil {
@@ -3364,6 +3364,36 @@ func (in *HTTPExtAuthService) DeepCopy() *HTTPExtAuthService {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *HTTPHeaderFilter) DeepCopyInto(out *HTTPHeaderFilter) {
+ *out = *in
+ if in.Set != nil {
+ in, out := &in.Set, &out.Set
+ *out = make([]v1.HTTPHeader, len(*in))
+ copy(*out, *in)
+ }
+ if in.Add != nil {
+ in, out := &in.Add, &out.Add
+ *out = make([]v1.HTTPHeader, len(*in))
+ copy(*out, *in)
+ }
+ if in.Remove != nil {
+ in, out := &in.Remove, &out.Remove
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPHeaderFilter.
+func (in *HTTPHeaderFilter) DeepCopy() *HTTPHeaderFilter {
+ if in == nil {
+ return nil
+ }
+ out := new(HTTPHeaderFilter)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HTTPHostnameModifier) DeepCopyInto(out *HTTPHostnameModifier) {
*out = *in
@@ -3652,7 +3682,7 @@ func (in *HeaderSettings) DeepCopyInto(out *HeaderSettings) {
}
if in.EarlyRequestHeaders != nil {
in, out := &in.EarlyRequestHeaders, &out.EarlyRequestHeaders
- *out = new(v1.HTTPHeaderFilter)
+ *out = new(HTTPHeaderFilter)
(*in).DeepCopyInto(*out)
}
}
@@ -4723,7 +4753,7 @@ func (in *OIDC) DeepCopyInto(out *OIDC) {
}
if in.DefaultTokenTTL != nil {
in, out := &in.DefaultTokenTTL, &out.DefaultTokenTTL
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.RefreshToken != nil {
@@ -4733,7 +4763,7 @@ func (in *OIDC) DeepCopyInto(out *OIDC) {
}
if in.DefaultRefreshTokenTTL != nil {
in, out := &in.DefaultRefreshTokenTTL, &out.DefaultRefreshTokenTTL
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.PassThroughAuthHeader != nil {
@@ -4941,7 +4971,7 @@ func (in *PassiveHealthCheck) DeepCopyInto(out *PassiveHealthCheck) {
}
if in.Interval != nil {
in, out := &in.Interval, &out.Interval
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.ConsecutiveLocalOriginFailures != nil {
@@ -4961,7 +4991,7 @@ func (in *PassiveHealthCheck) DeepCopyInto(out *PassiveHealthCheck) {
}
if in.BaseEjectionTime != nil {
in, out := &in.BaseEjectionTime, &out.BaseEjectionTime
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.MaxEjectionPercent != nil {
@@ -5031,7 +5061,7 @@ func (in *PerRetryPolicy) DeepCopyInto(out *PerRetryPolicy) {
*out = *in
if in.Timeout != nil {
in, out := &in.Timeout, &out.Timeout
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.BackOff != nil {
@@ -5581,7 +5611,7 @@ func (in *RateLimit) DeepCopyInto(out *RateLimit) {
in.Backend.DeepCopyInto(&out.Backend)
if in.Timeout != nil {
in, out := &in.Timeout, &out.Timeout
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.Telemetry != nil {
@@ -6309,12 +6339,12 @@ func (in *ShutdownConfig) DeepCopyInto(out *ShutdownConfig) {
*out = *in
if in.DrainTimeout != nil {
in, out := &in.DrainTimeout, &out.DrainTimeout
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
if in.MinDrainDuration != nil {
in, out := &in.MinDrainDuration, &out.MinDrainDuration
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
}
@@ -6354,7 +6384,7 @@ func (in *SlowStart) DeepCopyInto(out *SlowStart) {
*out = *in
if in.Window != nil {
in, out := &in.Window, &out.Window
- *out = new(metav1.Duration)
+ *out = new(v1.Duration)
**out = **in
}
}
diff --git a/charts/gateway-crds-helm/Chart.yaml b/charts/gateway-crds-helm/Chart.yaml
index 4c2095aa7a..72b321dba8 100644
--- a/charts/gateway-crds-helm/Chart.yaml
+++ b/charts/gateway-crds-helm/Chart.yaml
@@ -1,24 +1,25 @@
apiVersion: v2
name: gateway-crds-helm
-description: A Helm chart for Kubernetes
-
-# A chart can be either an 'application' or a 'library' chart.
-#
-# Application charts are a collection of templates that can be packaged into versioned archives
-# to be deployed.
-#
-# Library charts provide useful utilities or functions for the chart developer. They're included as
-# a dependency of application charts to inject those utilities and functions into the rendering
-# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+description: A Helm chart for Envoy Gateway CRDs
type: application
-# This is the chart version. This version number should be incremented each time you make changes
-# to the chart and its templates, including the app version.
-# Versions are expected to follow Semantic Versioning (https://semver.org/)
-version: 0.1.0
+version: v0.0.0-latest
+appVersion: "latest"
+icon: https://raw.githubusercontent.com/envoyproxy/gateway/main/site/assets/icons/logo.svg
+
+maintainers:
+ - name: envoy-gateway-steering-committee
+ url: https://github.com/envoyproxy/gateway/blob/main/GOVERNANCE.md
+ - name: envoy-gateway-maintainers
+ url: https://github.com/envoyproxy/gateway/blob/main/CODEOWNERS
+
+keywords:
+ - gateway-api
+ - envoyproxy
+ - envoy-gateway
+ - eg
+
+home: https://gateway.envoyproxy.io/
-# This is the version number of the application being deployed. This version number should be
-# incremented each time you make changes to the application. Versions are not expected to
-# follow Semantic Versioning. They should reflect the version the application is using.
-# It is recommended to use it with quotes.
-appVersion: "1.16.0"
+sources:
+ - https://github.com/envoyproxy/gateway
diff --git a/charts/gateway-crds-helm/README.md b/charts/gateway-crds-helm/README.md
index a729d50b2d..e54913a3d8 100644
--- a/charts/gateway-crds-helm/README.md
+++ b/charts/gateway-crds-helm/README.md
@@ -1,8 +1,21 @@
# gateway-crds-helm
-  
+  
-A Helm chart for Kubernetes
+A Helm chart for Envoy Gateway CRDs
+
+**Homepage:**
+
+## Maintainers
+
+| Name | Email | Url |
+| ---- | ------ | --- |
+| envoy-gateway-steering-committee | | |
+| envoy-gateway-maintainers | | |
+
+## Source Code
+
+*
## Usage
diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml
index 4be80d9bc6..2adaa4916f 100644
--- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml
+++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml
@@ -177,6 +177,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -235,6 +236,7 @@ spec:
properties:
fixedDelay:
description: FixedDelay specifies the fixed delay duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
percentage:
default: 100
@@ -318,8 +320,7 @@ spec:
Defaults to 200 only
items:
description: HTTPStatus defines the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -349,14 +350,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between active health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -430,7 +430,7 @@ spec:
default: 1s
description: Timeout defines the time to wait for a health
check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -481,7 +481,7 @@ spec:
default: 30s
description: BaseEjectionTime defines the base duration for
which a host will be ejected on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -506,7 +506,7 @@ spec:
default: 3s
description: Interval defines the time between passive health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -625,6 +625,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -708,6 +709,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -1028,12 +1030,14 @@ spec:
unit:
description: |-
RateLimitUnit specifies the intervals for setting rate limits.
- Valid RateLimitUnit values are "Second", "Minute", "Hour", and "Day".
+ Valid RateLimitUnit values are "Second", "Minute", "Hour", "Day", "Month" and "Year".
enum:
- Second
- Minute
- Hour
- Day
+ - Month
+ - Year
type: string
required:
- requests
@@ -1277,12 +1281,14 @@ spec:
unit:
description: |-
RateLimitUnit specifies the intervals for setting rate limits.
- Valid RateLimitUnit values are "Second", "Minute", "Hour", and "Day".
+ Valid RateLimitUnit values are "Second", "Minute", "Hour", "Day", "Month" and "Year".
enum:
- Second
- Minute
- Hour
- Day
+ - Month
+ - Year
type: string
required:
- requests
@@ -1643,18 +1649,18 @@ spec:
baseInterval:
description: BaseInterval is the base interval between
retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -1669,8 +1675,7 @@ spec:
The retriable-status-codes trigger must also be configured for these status codes to trigger a retry.
items:
description: HTTPStatus defines the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml
index 311faf9cef..f23d6b2442 100644
--- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml
+++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml
@@ -244,7 +244,7 @@ spec:
- name
- value
type: object
- maxItems: 16
+ maxItems: 64
type: array
x-kubernetes-list-map-keys:
- name
@@ -270,7 +270,7 @@ spec:
my-header2: bar
items:
type: string
- maxItems: 16
+ maxItems: 64
type: array
x-kubernetes-list-type: set
set:
@@ -318,7 +318,7 @@ spec:
- name
- value
type: object
- maxItems: 16
+ maxItems: 64
type: array
x-kubernetes-list-map-keys:
- name
diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml
index 73556e46e8..2c4a3d8a2b 100644
--- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml
+++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml
@@ -324,6 +324,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -416,8 +417,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -447,14 +447,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between active
health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -533,7 +532,7 @@ spec:
default: 1s
description: Timeout defines the time to wait for
a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -586,7 +585,7 @@ spec:
description: BaseEjectionTime defines the base duration
for which a host will be ejected on consecutive
failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -611,7 +610,7 @@ spec:
default: 3s
description: Interval defines the time between passive
health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -701,6 +700,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -787,6 +787,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -899,18 +900,18 @@ spec:
baseInterval:
description: BaseInterval is the base interval
between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -926,8 +927,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml
index 5cb364725c..1d3fe914b7 100644
--- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml
+++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml
@@ -614,7 +614,7 @@ spec:
x-kubernetes-validations:
- message: Image must include a tag and allowed characters
only (e.g., 'repo:tag').
- rule: self.matches('^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$')
+ rule: self.matches('^[a-zA-Z0-9._-]+(:[0-9]+)?(/[a-zA-Z0-9._/-]+)?(:[a-zA-Z0-9._-]+)?(@sha256:[a-z0-9]+)?$')
imageRepository:
description: |-
ImageRepository specifies the container image repository to be used without specifying a tag.
@@ -623,8 +623,8 @@ spec:
type: string
x-kubernetes-validations:
- message: ImageRepository must contain only allowed
- characters and must not include a tag or any colons.
- rule: self.matches('^[a-zA-Z0-9._/-]+$')
+ characters and must not include a tag.
+ rule: self.matches('^[a-zA-Z0-9._-]+(:[0-9]+)?[a-zA-Z0-9._/-]+$')
resources:
description: |-
Resources required by this container.
@@ -4459,7 +4459,7 @@ spec:
x-kubernetes-validations:
- message: Image must include a tag and allowed characters
only (e.g., 'repo:tag').
- rule: self.matches('^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$')
+ rule: self.matches('^[a-zA-Z0-9._-]+(:[0-9]+)?(/[a-zA-Z0-9._/-]+)?(:[a-zA-Z0-9._-]+)?(@sha256:[a-z0-9]+)?$')
imageRepository:
description: |-
ImageRepository specifies the container image repository to be used without specifying a tag.
@@ -4468,8 +4468,8 @@ spec:
type: string
x-kubernetes-validations:
- message: ImageRepository must contain only allowed
- characters and must not include a tag or any colons.
- rule: self.matches('^[a-zA-Z0-9._/-]+$')
+ characters and must not include a tag.
+ rule: self.matches('^[a-zA-Z0-9._-]+(:[0-9]+)?[a-zA-Z0-9._/-]+$')
resources:
description: |-
Resources required by this container.
@@ -10516,11 +10516,13 @@ spec:
description: |-
DrainTimeout defines the graceful drain timeout. This should be less than the pod's terminationGracePeriodSeconds.
If unspecified, defaults to 60 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
minDrainDuration:
description: |-
MinDrainDuration defines the minimum drain duration allowing time for endpoint deprogramming to complete.
If unspecified, defaults to 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
telemetry:
@@ -10874,6 +10876,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -10974,8 +10977,7 @@ spec:
description: HTTPStatus
defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -11007,7 +11009,6 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
@@ -11015,7 +11016,7 @@ spec:
description: Interval defines
the time between active health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -11104,7 +11105,7 @@ spec:
description: Timeout defines the
time to wait for a health check
response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -11167,7 +11168,7 @@ spec:
defines the base duration for
which a host will be ejected
on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -11195,7 +11196,7 @@ spec:
description: Interval defines
the time between passive health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -11290,6 +11291,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -11384,6 +11386,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -11505,19 +11508,19 @@ spec:
description: BaseInterval
is the base interval between
retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout
per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -11533,8 +11536,7 @@ spec:
items:
description: HTTPStatus defines
the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -11985,6 +11987,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -12085,8 +12088,7 @@ spec:
description: HTTPStatus
defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -12118,7 +12120,6 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
@@ -12126,7 +12127,7 @@ spec:
description: Interval defines
the time between active health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -12215,7 +12216,7 @@ spec:
description: Timeout defines the
time to wait for a health check
response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -12278,7 +12279,7 @@ spec:
defines the base duration for
which a host will be ejected
on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -12306,7 +12307,7 @@ spec:
description: Interval defines
the time between passive health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -12401,6 +12402,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -12495,6 +12497,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -12616,19 +12619,19 @@ spec:
description: BaseInterval
is the base interval between
retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout
per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -12644,8 +12647,7 @@ spec:
items:
description: HTTPStatus defines
the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -13204,6 +13206,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -13300,8 +13303,7 @@ spec:
items:
description: HTTPStatus defines
the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -13332,14 +13334,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time
between active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -13423,7 +13424,7 @@ spec:
default: 1s
description: Timeout defines the time
to wait for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -13481,7 +13482,7 @@ spec:
description: BaseEjectionTime defines
the base duration for which a host
will be ejected on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -13508,7 +13509,7 @@ spec:
default: 3s
description: Interval defines the time
between passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -13600,6 +13601,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -13690,6 +13692,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -13806,19 +13809,19 @@ spec:
baseInterval:
description: BaseInterval is the
base interval between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout
per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -13834,8 +13837,7 @@ spec:
items:
description: HTTPStatus defines the
http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -14320,6 +14322,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -14415,8 +14418,7 @@ spec:
items:
description: HTTPStatus defines the
http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -14447,14 +14449,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -14538,7 +14539,7 @@ spec:
default: 1s
description: Timeout defines the time to wait
for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -14595,7 +14596,7 @@ spec:
description: BaseEjectionTime defines the
base duration for which a host will be ejected
on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -14622,7 +14623,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -14714,6 +14715,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -14803,6 +14805,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -14917,19 +14920,19 @@ spec:
baseInterval:
description: BaseInterval is the base
interval between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry
attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -14945,8 +14948,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml
index 79af9ce40c..6934fd3cd5 100644
--- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml
+++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml
@@ -522,6 +522,7 @@ spec:
description: |-
MaxAge defines how long the results of a preflight request can be cached.
It specifies the value in the Access-Control-Max-Age CORS response header..
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
extAuth:
@@ -828,6 +829,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -920,8 +922,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -951,14 +952,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -1037,7 +1037,7 @@ spec:
default: 1s
description: Timeout defines the time to wait
for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -1092,7 +1092,7 @@ spec:
description: BaseEjectionTime defines the base
duration for which a host will be ejected on
consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -1118,7 +1118,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -1210,6 +1210,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -1297,6 +1298,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -1411,19 +1413,19 @@ spec:
baseInterval:
description: BaseInterval is the base interval
between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry
attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -1439,8 +1441,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -1835,6 +1836,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -1927,8 +1929,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -1958,14 +1959,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -2044,7 +2044,7 @@ spec:
default: 1s
description: Timeout defines the time to wait
for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -2099,7 +2099,7 @@ spec:
description: BaseEjectionTime defines the base
duration for which a host will be ejected on
consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -2125,7 +2125,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -2217,6 +2217,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -2304,6 +2305,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -2418,19 +2420,19 @@ spec:
baseInterval:
description: BaseInterval is the base interval
between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry
attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -2446,8 +2448,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -3034,6 +3035,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -3129,8 +3131,7 @@ spec:
items:
description: HTTPStatus defines the
http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -3161,14 +3162,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -3252,7 +3252,7 @@ spec:
default: 1s
description: Timeout defines the time to
wait for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -3310,7 +3310,7 @@ spec:
description: BaseEjectionTime defines the
base duration for which a host will be
ejected on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -3337,7 +3337,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -3429,6 +3429,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -3518,6 +3519,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -3633,19 +3635,19 @@ spec:
baseInterval:
description: BaseInterval is the base
interval between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per
retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -3661,8 +3663,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -3902,7 +3903,6 @@ spec:
By default, its unset.
properties:
sameSite:
- default: Strict
enum:
- Lax
- Strict
@@ -3944,6 +3944,7 @@ spec:
If not specified, defaults to 604800s (one week).
Note: this field is only applicable when the "refreshToken" field is set to true.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
defaultTokenTTL:
description: |-
@@ -3955,6 +3956,7 @@ spec:
If not specified, defaults to 0. In this case, the "expires_in" field in
the authorization response must be set by the authorization server, or the
OAuth flow will fail.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
denyRedirect:
description: |-
@@ -4297,6 +4299,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -4389,8 +4392,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -4420,14 +4422,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -4506,7 +4507,7 @@ spec:
default: 1s
description: Timeout defines the time to wait
for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -4561,7 +4562,7 @@ spec:
description: BaseEjectionTime defines the base
duration for which a host will be ejected on
consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -4587,7 +4588,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -4679,6 +4680,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -4766,6 +4768,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -4880,19 +4883,19 @@ spec:
baseInterval:
description: BaseInterval is the base interval
between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry
attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -4908,8 +4911,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
diff --git a/charts/gateway-helm/README.md b/charts/gateway-helm/README.md
index 7d95097567..6c32abe1b1 100644
--- a/charts/gateway-helm/README.md
+++ b/charts/gateway-helm/README.md
@@ -103,7 +103,7 @@ helm uninstall eg -n envoy-gateway-system
| global.images.envoyGateway.image | string | `nil` | |
| global.images.envoyGateway.pullPolicy | string | `nil` | |
| global.images.envoyGateway.pullSecrets | list | `[]` | |
-| global.images.ratelimit.image | string | `"docker.io/envoyproxy/ratelimit:master"` | |
+| global.images.ratelimit.image | string | `"docker.io/envoyproxy/ratelimit:e74a664a"` | |
| global.images.ratelimit.pullPolicy | string | `"IfNotPresent"` | |
| global.images.ratelimit.pullSecrets | list | `[]` | |
| hpa.behavior | object | `{}` | |
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 f87cb95968..aee0777332 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml
@@ -176,6 +176,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -234,6 +235,7 @@ spec:
properties:
fixedDelay:
description: FixedDelay specifies the fixed delay duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
percentage:
default: 100
@@ -317,8 +319,7 @@ spec:
Defaults to 200 only
items:
description: HTTPStatus defines the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -348,14 +349,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between active health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -429,7 +429,7 @@ spec:
default: 1s
description: Timeout defines the time to wait for a health
check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -480,7 +480,7 @@ spec:
default: 30s
description: BaseEjectionTime defines the base duration for
which a host will be ejected on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -505,7 +505,7 @@ spec:
default: 3s
description: Interval defines the time between passive health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -624,6 +624,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -707,6 +708,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -1027,12 +1029,14 @@ spec:
unit:
description: |-
RateLimitUnit specifies the intervals for setting rate limits.
- Valid RateLimitUnit values are "Second", "Minute", "Hour", and "Day".
+ Valid RateLimitUnit values are "Second", "Minute", "Hour", "Day", "Month" and "Year".
enum:
- Second
- Minute
- Hour
- Day
+ - Month
+ - Year
type: string
required:
- requests
@@ -1276,12 +1280,14 @@ spec:
unit:
description: |-
RateLimitUnit specifies the intervals for setting rate limits.
- Valid RateLimitUnit values are "Second", "Minute", "Hour", and "Day".
+ Valid RateLimitUnit values are "Second", "Minute", "Hour", "Day", "Month" and "Year".
enum:
- Second
- Minute
- Hour
- Day
+ - Month
+ - Year
type: string
required:
- requests
@@ -1642,18 +1648,18 @@ spec:
baseInterval:
description: BaseInterval is the base interval between
retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -1668,8 +1674,7 @@ spec:
The retriable-status-codes trigger must also be configured for these status codes to trigger a retry.
items:
description: HTTPStatus defines the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
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 85e91f5882..f3ba0cdd22 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml
@@ -243,7 +243,7 @@ spec:
- name
- value
type: object
- maxItems: 16
+ maxItems: 64
type: array
x-kubernetes-list-map-keys:
- name
@@ -269,7 +269,7 @@ spec:
my-header2: bar
items:
type: string
- maxItems: 16
+ maxItems: 64
type: array
x-kubernetes-list-type: set
set:
@@ -317,7 +317,7 @@ spec:
- name
- value
type: object
- maxItems: 16
+ maxItems: 64
type: array
x-kubernetes-list-map-keys:
- name
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 2ed348e214..c84cf5b1e3 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml
@@ -323,6 +323,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -415,8 +416,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -446,14 +446,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between active
health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -532,7 +531,7 @@ spec:
default: 1s
description: Timeout defines the time to wait for
a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -585,7 +584,7 @@ spec:
description: BaseEjectionTime defines the base duration
for which a host will be ejected on consecutive
failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -610,7 +609,7 @@ spec:
default: 3s
description: Interval defines the time between passive
health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -700,6 +699,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -786,6 +786,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -898,18 +899,18 @@ spec:
baseInterval:
description: BaseInterval is the base interval
between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -925,8 +926,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
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 6302ee4716..d8f4e217bd 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
@@ -613,7 +613,7 @@ spec:
x-kubernetes-validations:
- message: Image must include a tag and allowed characters
only (e.g., 'repo:tag').
- rule: self.matches('^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$')
+ rule: self.matches('^[a-zA-Z0-9._-]+(:[0-9]+)?(/[a-zA-Z0-9._/-]+)?(:[a-zA-Z0-9._-]+)?(@sha256:[a-z0-9]+)?$')
imageRepository:
description: |-
ImageRepository specifies the container image repository to be used without specifying a tag.
@@ -622,8 +622,8 @@ spec:
type: string
x-kubernetes-validations:
- message: ImageRepository must contain only allowed
- characters and must not include a tag or any colons.
- rule: self.matches('^[a-zA-Z0-9._/-]+$')
+ characters and must not include a tag.
+ rule: self.matches('^[a-zA-Z0-9._-]+(:[0-9]+)?[a-zA-Z0-9._/-]+$')
resources:
description: |-
Resources required by this container.
@@ -4458,7 +4458,7 @@ spec:
x-kubernetes-validations:
- message: Image must include a tag and allowed characters
only (e.g., 'repo:tag').
- rule: self.matches('^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$')
+ rule: self.matches('^[a-zA-Z0-9._-]+(:[0-9]+)?(/[a-zA-Z0-9._/-]+)?(:[a-zA-Z0-9._-]+)?(@sha256:[a-z0-9]+)?$')
imageRepository:
description: |-
ImageRepository specifies the container image repository to be used without specifying a tag.
@@ -4467,8 +4467,8 @@ spec:
type: string
x-kubernetes-validations:
- message: ImageRepository must contain only allowed
- characters and must not include a tag or any colons.
- rule: self.matches('^[a-zA-Z0-9._/-]+$')
+ characters and must not include a tag.
+ rule: self.matches('^[a-zA-Z0-9._-]+(:[0-9]+)?[a-zA-Z0-9._/-]+$')
resources:
description: |-
Resources required by this container.
@@ -10515,11 +10515,13 @@ spec:
description: |-
DrainTimeout defines the graceful drain timeout. This should be less than the pod's terminationGracePeriodSeconds.
If unspecified, defaults to 60 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
minDrainDuration:
description: |-
MinDrainDuration defines the minimum drain duration allowing time for endpoint deprogramming to complete.
If unspecified, defaults to 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
telemetry:
@@ -10873,6 +10875,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -10973,8 +10976,7 @@ spec:
description: HTTPStatus
defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -11006,7 +11008,6 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
@@ -11014,7 +11015,7 @@ spec:
description: Interval defines
the time between active health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -11103,7 +11104,7 @@ spec:
description: Timeout defines the
time to wait for a health check
response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -11166,7 +11167,7 @@ spec:
defines the base duration for
which a host will be ejected
on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -11194,7 +11195,7 @@ spec:
description: Interval defines
the time between passive health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -11289,6 +11290,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -11383,6 +11385,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -11504,19 +11507,19 @@ spec:
description: BaseInterval
is the base interval between
retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout
per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -11532,8 +11535,7 @@ spec:
items:
description: HTTPStatus defines
the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -11984,6 +11986,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -12084,8 +12087,7 @@ spec:
description: HTTPStatus
defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -12117,7 +12119,6 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
@@ -12125,7 +12126,7 @@ spec:
description: Interval defines
the time between active health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -12214,7 +12215,7 @@ spec:
description: Timeout defines the
time to wait for a health check
response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -12277,7 +12278,7 @@ spec:
defines the base duration for
which a host will be ejected
on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -12305,7 +12306,7 @@ spec:
description: Interval defines
the time between passive health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -12400,6 +12401,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -12494,6 +12496,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -12615,19 +12618,19 @@ spec:
description: BaseInterval
is the base interval between
retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout
per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -12643,8 +12646,7 @@ spec:
items:
description: HTTPStatus defines
the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -13203,6 +13205,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -13299,8 +13302,7 @@ spec:
items:
description: HTTPStatus defines
the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -13331,14 +13333,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time
between active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -13422,7 +13423,7 @@ spec:
default: 1s
description: Timeout defines the time
to wait for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -13480,7 +13481,7 @@ spec:
description: BaseEjectionTime defines
the base duration for which a host
will be ejected on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -13507,7 +13508,7 @@ spec:
default: 3s
description: Interval defines the time
between passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -13599,6 +13600,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -13689,6 +13691,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -13805,19 +13808,19 @@ spec:
baseInterval:
description: BaseInterval is the
base interval between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout
per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -13833,8 +13836,7 @@ spec:
items:
description: HTTPStatus defines the
http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -14319,6 +14321,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -14414,8 +14417,7 @@ spec:
items:
description: HTTPStatus defines the
http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -14446,14 +14448,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -14537,7 +14538,7 @@ spec:
default: 1s
description: Timeout defines the time to wait
for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -14594,7 +14595,7 @@ spec:
description: BaseEjectionTime defines the
base duration for which a host will be ejected
on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -14621,7 +14622,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -14713,6 +14714,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -14802,6 +14804,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -14916,19 +14919,19 @@ spec:
baseInterval:
description: BaseInterval is the base
interval between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry
attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -14944,8 +14947,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
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 ea1b263aca..19fbc299b5 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
@@ -521,6 +521,7 @@ spec:
description: |-
MaxAge defines how long the results of a preflight request can be cached.
It specifies the value in the Access-Control-Max-Age CORS response header..
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
extAuth:
@@ -827,6 +828,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -919,8 +921,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -950,14 +951,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -1036,7 +1036,7 @@ spec:
default: 1s
description: Timeout defines the time to wait
for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -1091,7 +1091,7 @@ spec:
description: BaseEjectionTime defines the base
duration for which a host will be ejected on
consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -1117,7 +1117,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -1209,6 +1209,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -1296,6 +1297,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -1410,19 +1412,19 @@ spec:
baseInterval:
description: BaseInterval is the base interval
between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry
attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -1438,8 +1440,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -1834,6 +1835,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -1926,8 +1928,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -1957,14 +1958,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -2043,7 +2043,7 @@ spec:
default: 1s
description: Timeout defines the time to wait
for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -2098,7 +2098,7 @@ spec:
description: BaseEjectionTime defines the base
duration for which a host will be ejected on
consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -2124,7 +2124,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -2216,6 +2216,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -2303,6 +2304,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -2417,19 +2419,19 @@ spec:
baseInterval:
description: BaseInterval is the base interval
between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry
attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -2445,8 +2447,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -3033,6 +3034,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -3128,8 +3130,7 @@ spec:
items:
description: HTTPStatus defines the
http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -3160,14 +3161,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -3251,7 +3251,7 @@ spec:
default: 1s
description: Timeout defines the time to
wait for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -3309,7 +3309,7 @@ spec:
description: BaseEjectionTime defines the
base duration for which a host will be
ejected on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -3336,7 +3336,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -3428,6 +3428,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -3517,6 +3518,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -3632,19 +3634,19 @@ spec:
baseInterval:
description: BaseInterval is the base
interval between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per
retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -3660,8 +3662,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -3901,7 +3902,6 @@ spec:
By default, its unset.
properties:
sameSite:
- default: Strict
enum:
- Lax
- Strict
@@ -3943,6 +3943,7 @@ spec:
If not specified, defaults to 604800s (one week).
Note: this field is only applicable when the "refreshToken" field is set to true.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
defaultTokenTTL:
description: |-
@@ -3954,6 +3955,7 @@ spec:
If not specified, defaults to 0. In this case, the "expires_in" field in
the authorization response must be set by the authorization server, or the
OAuth flow will fail.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
denyRedirect:
description: |-
@@ -4296,6 +4298,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -4388,8 +4391,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -4419,14 +4421,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -4505,7 +4506,7 @@ spec:
default: 1s
description: Timeout defines the time to wait
for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -4560,7 +4561,7 @@ spec:
description: BaseEjectionTime defines the base
duration for which a host will be ejected on
consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -4586,7 +4587,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -4678,6 +4679,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -4765,6 +4767,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -4879,19 +4882,19 @@ spec:
baseInterval:
description: BaseInterval is the base interval
between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry
attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -4907,8 +4910,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
diff --git a/charts/gateway-helm/values.tmpl.yaml b/charts/gateway-helm/values.tmpl.yaml
index 41ec30edc0..5a0977f9c7 100644
--- a/charts/gateway-helm/values.tmpl.yaml
+++ b/charts/gateway-helm/values.tmpl.yaml
@@ -19,7 +19,7 @@ global:
pullSecrets: []
ratelimit:
# This is the full image name including the hub, repo, and tag.
- image: "docker.io/envoyproxy/ratelimit:master"
+ image: "docker.io/envoyproxy/ratelimit:e74a664a"
# Specify image pull policy if default behavior isn't desired.
# Default behavior: latest images will be Always else IfNotPresent.
pullPolicy: IfNotPresent
diff --git a/examples/envoy-ext-auth/Dockerfile b/examples/envoy-ext-auth/Dockerfile
index 5966950814..64a85c41bf 100644
--- a/examples/envoy-ext-auth/Dockerfile
+++ b/examples/envoy-ext-auth/Dockerfile
@@ -1,4 +1,4 @@
-FROM golang:1.24.4 AS builder
+FROM golang:1.24.7 AS builder
ARG GO_LDFLAGS=""
diff --git a/examples/envoy-ext-auth/go.mod b/examples/envoy-ext-auth/go.mod
index c9f1ed6584..c6a099b470 100644
--- a/examples/envoy-ext-auth/go.mod
+++ b/examples/envoy-ext-auth/go.mod
@@ -1,6 +1,6 @@
module github.com/envoyproxy/gateway-grcp-ext-auth
-go 1.24.4
+go 1.24.7
require (
github.com/envoyproxy/go-control-plane/envoy v1.32.4
diff --git a/examples/extension-server/go.mod b/examples/extension-server/go.mod
index c86026e17b..d3207a42e7 100644
--- a/examples/extension-server/go.mod
+++ b/examples/extension-server/go.mod
@@ -1,6 +1,6 @@
module github.com/exampleorg/envoygateway-extension
-go 1.24.4
+go 1.24.7
require (
github.com/envoyproxy/gateway v1.3.1
@@ -45,8 +45,8 @@ require (
golang.org/x/text v0.27.0 // indirect
golang.org/x/tools v0.35.0 // indirect
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
diff --git a/examples/extension-server/go.sum b/examples/extension-server/go.sum
index d17ae39070..7abb864d9d 100644
--- a/examples/extension-server/go.sum
+++ b/examples/extension-server/go.sum
@@ -37,8 +37,8 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a h1://KbezygeMJZCSHH+HgUZiTeSoiuFspbMg1ge+eFj18=
-github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
+github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
+github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
@@ -160,10 +160,10 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
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-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY=
-google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
+google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0 h1:0UOBWO4dC+e51ui0NFKSPbkHHiQ4TmrEfEZMLDyRmY8=
+google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0/go.mod h1:8ytArBbtOy2xfht+y2fqKd5DRDJRUQhqbyEnQ4bDChs=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0 h1:MAKi5q709QWfnkkpNQ0M12hYJ1+e8qYVDyowc4U1XZM=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=
google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
diff --git a/examples/grpc-ext-proc/Dockerfile b/examples/grpc-ext-proc/Dockerfile
index 1ed6430ec3..8cf7eb1137 100644
--- a/examples/grpc-ext-proc/Dockerfile
+++ b/examples/grpc-ext-proc/Dockerfile
@@ -1,4 +1,4 @@
-FROM golang:1.24.4 AS builder
+FROM golang:1.24.7 AS builder
ARG GO_LDFLAGS=""
diff --git a/examples/grpc-ext-proc/go.mod b/examples/grpc-ext-proc/go.mod
index afb804c86f..584b047430 100644
--- a/examples/grpc-ext-proc/go.mod
+++ b/examples/grpc-ext-proc/go.mod
@@ -1,6 +1,6 @@
module github.com/envoyproxy/gateway-grpc-ext-proc
-go 1.24.4
+go 1.24.7
require (
github.com/envoyproxy/go-control-plane/envoy v1.32.4
diff --git a/examples/preserve-case-backend/Dockerfile b/examples/preserve-case-backend/Dockerfile
index 734637564b..4976a63806 100644
--- a/examples/preserve-case-backend/Dockerfile
+++ b/examples/preserve-case-backend/Dockerfile
@@ -1,4 +1,4 @@
-FROM golang:1.24.4 AS builder
+FROM golang:1.24.7 AS builder
ARG GO_LDFLAGS=""
diff --git a/examples/preserve-case-backend/go.mod b/examples/preserve-case-backend/go.mod
index 2e6b968d8b..55573da549 100644
--- a/examples/preserve-case-backend/go.mod
+++ b/examples/preserve-case-backend/go.mod
@@ -1,6 +1,6 @@
module github.com/envoyproxy/gateway-preserve-case-backend
-go 1.24.4
+go 1.24.7
require github.com/valyala/fasthttp v1.64.0
diff --git a/examples/simple-extension-server/Dockerfile b/examples/simple-extension-server/Dockerfile
index 4c3f88c160..42172f685d 100644
--- a/examples/simple-extension-server/Dockerfile
+++ b/examples/simple-extension-server/Dockerfile
@@ -1,4 +1,4 @@
-FROM golang:1.24.4 AS builder
+FROM golang:1.24.7 AS builder
ARG GO_LDFLAGS=""
diff --git a/examples/simple-extension-server/go.mod b/examples/simple-extension-server/go.mod
index ae99dc0cfc..5f771d0f3b 100644
--- a/examples/simple-extension-server/go.mod
+++ b/examples/simple-extension-server/go.mod
@@ -1,6 +1,6 @@
module github.com/envoyproxy/gateway-simple-extension-server
-go 1.24.4
+go 1.24.7
require (
github.com/envoyproxy/gateway v1.4.2
diff --git a/examples/static-file-server/Dockerfile b/examples/static-file-server/Dockerfile
index 8c715b1f29..e53ff75545 100644
--- a/examples/static-file-server/Dockerfile
+++ b/examples/static-file-server/Dockerfile
@@ -1,4 +1,4 @@
-FROM golang:1.24.4 AS builder
+FROM golang:1.24.7 AS builder
ARG GO_LDFLAGS=""
diff --git a/examples/static-file-server/go.mod b/examples/static-file-server/go.mod
index 9018de8794..092e99e5e9 100644
--- a/examples/static-file-server/go.mod
+++ b/examples/static-file-server/go.mod
@@ -1,3 +1,3 @@
module github.com/envoyproxy/static-file-server
-go 1.24.4
+go 1.24.7
diff --git a/go.mod b/go.mod
index c235913318..396c54fcb0 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
module github.com/envoyproxy/gateway
-go 1.24.4
+go 1.24.7
// Replace the otelgrpc version because of k8s.io/client-go v0.33.3
replace go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 => go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0
@@ -21,7 +21,7 @@ require (
github.com/envoyproxy/go-control-plane v0.13.5-0.20250622153809-434b6986176d
github.com/envoyproxy/go-control-plane/contrib v1.32.5-0.20250430092421-68a532e11403
github.com/envoyproxy/go-control-plane/envoy v1.32.5-0.20250622153809-434b6986176d
- github.com/envoyproxy/go-control-plane/ratelimit v0.1.0
+ github.com/envoyproxy/go-control-plane/ratelimit v0.1.1-0.20250805143705-d51f8590a549
github.com/envoyproxy/ratelimit v1.4.1-0.20230427142404-e2a87f41d3a7
github.com/evanphx/json-patch v5.9.11+incompatible
github.com/evanphx/json-patch/v5 v5.9.11
@@ -34,16 +34,16 @@ require (
github.com/go-openapi/strfmt v0.23.0
github.com/go-openapi/validate v0.24.0
github.com/golang/protobuf v1.5.4
- github.com/google/cel-go v0.25.0
+ github.com/google/cel-go v0.26.0
github.com/google/go-cmp v0.7.0
github.com/google/go-containerregistry v0.20.6
- github.com/miekg/dns v1.1.67
+ github.com/miekg/dns v1.1.68
github.com/ohler55/ojg v1.26.8
github.com/pkg/errors v0.9.1
- github.com/prometheus/client_golang v1.22.0
+ github.com/prometheus/client_golang v1.23.0
github.com/prometheus/client_model v0.6.2
github.com/prometheus/common v0.65.0
- github.com/quic-go/quic-go v0.52.0
+ github.com/quic-go/quic-go v0.54.0
github.com/replicatedhq/troubleshoot v0.121.2
github.com/shopspring/decimal v1.4.0
github.com/spf13/cobra v1.9.1
@@ -61,12 +61,12 @@ require (
go.opentelemetry.io/otel/metric v1.37.0
go.opentelemetry.io/otel/sdk v1.37.0
go.opentelemetry.io/otel/sdk/metric v1.37.0
- go.opentelemetry.io/proto/otlp v1.7.0
+ go.opentelemetry.io/proto/otlp v1.7.1
go.uber.org/zap v1.27.0
- golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476
+ golang.org/x/exp v0.0.0-20250718183923-645b1fa84792
golang.org/x/net v0.42.0
gomodules.xyz/jsonpatch/v2 v2.5.0
- google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822
+ google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0
google.golang.org/grpc v1.74.2
google.golang.org/grpc/security/advancedtls v1.0.0
google.golang.org/protobuf v1.36.6
@@ -93,15 +93,15 @@ require (
4d63.com/gocheckcompilerdirectives v1.3.0 // indirect
4d63.com/gochecknoglobals v0.2.2 // indirect
al.essio.dev/pkg/shellescape v1.5.1 // indirect
- buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.6-20250121211742-6d880cc6cc8d.1 // indirect
- buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250613105001-9f2d3c737feb.1 // indirect
- buf.build/gen/go/bufbuild/registry/connectrpc/go v1.18.1-20250606164443-9d1800bf4ccc.1 // indirect
- buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.6-20250606164443-9d1800bf4ccc.1 // indirect
+ buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.6-20250718181942-e35f9b667443.1 // indirect
+ buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250717185734-6c6e0d3c608e.1 // indirect
+ buf.build/gen/go/bufbuild/registry/connectrpc/go v1.18.1-20250721151928-2b7ae473b098.1 // indirect
+ buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.6-20250721151928-2b7ae473b098.1 // indirect
buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.36.6-20241007202033-cf42259fcbfc.1 // indirect
buf.build/go/app v0.1.0 // indirect
buf.build/go/bufplugin v0.9.0 // indirect
buf.build/go/interrupt v1.1.0 // indirect
- buf.build/go/protovalidate v0.13.1 // indirect
+ buf.build/go/protovalidate v0.14.0 // indirect
buf.build/go/protoyaml v0.6.0 // indirect
buf.build/go/spdx v0.2.0 // indirect
buf.build/go/standard v0.1.0 // indirect
@@ -160,7 +160,7 @@ require (
github.com/bombsimon/wsl/v5 v5.1.0 // indirect
github.com/breml/bidichk v0.3.3 // indirect
github.com/breml/errchkjson v0.4.1 // indirect
- github.com/bufbuild/buf v1.55.1 // indirect
+ github.com/bufbuild/buf v1.56.0 // indirect
github.com/bufbuild/protocompile v0.14.1 // indirect
github.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1 // indirect
github.com/butuzov/ireturn v0.4.0 // indirect
@@ -185,7 +185,7 @@ require (
github.com/containerd/errdefs/pkg v0.3.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.16.3 // indirect
+ github.com/containerd/stargz-snapshotter/estargz v0.17.0 // indirect
github.com/containerd/typeurl/v2 v2.2.3 // indirect
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect
github.com/containers/ocicrypt v1.2.1 // indirect
@@ -234,7 +234,6 @@ require (
github.com/go-openapi/swag v0.23.1 // indirect
github.com/go-redis/redis/v7 v7.4.1 // indirect
github.com/go-sql-driver/mysql v1.9.3 // indirect
- github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/go-toolsmith/astcast v1.1.0 // indirect
github.com/go-toolsmith/astcopy v1.1.0 // indirect
github.com/go-toolsmith/astequal v1.2.0 // indirect
@@ -268,7 +267,6 @@ require (
github.com/google/go-intervals v0.0.2 // indirect
github.com/google/go-jsonnet v0.20.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
- github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gordonklaus/ineffassign v0.1.0 // indirect
@@ -372,7 +370,6 @@ require (
github.com/norwoodj/helm-docs v1.14.2 // indirect
github.com/nunnatsa/ginkgolinter v0.20.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
- github.com/onsi/ginkgo/v2 v2.23.4 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/opencontainers/runtime-spec v1.2.1 // indirect
@@ -408,7 +405,7 @@ require (
github.com/sashamelentyev/usestdlibvars v1.29.0 // indirect
github.com/securego/gosec/v2 v2.22.6 // indirect
github.com/segmentio/asm v1.2.0 // indirect
- github.com/segmentio/encoding v0.5.1 // indirect
+ github.com/segmentio/encoding v0.5.3 // indirect
github.com/segmentio/ksuid v1.0.4 // indirect
github.com/shirou/gopsutil/v4 v4.25.6 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
@@ -422,7 +419,7 @@ require (
github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect
github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
github.com/stbenjam/no-sprintf-host-port v0.2.0 // indirect
- github.com/stoewer/go-strcase v1.3.0 // indirect
+ github.com/stoewer/go-strcase v1.3.1 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/sylabs/sif/v2 v2.21.1 // indirect
@@ -437,7 +434,7 @@ require (
github.com/tomarrell/wrapcheck/v2 v2.11.0 // indirect
github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
github.com/tsaarni/x500dn v1.0.0 // indirect
- github.com/ulikunitz/xz v0.5.12 // indirect
+ github.com/ulikunitz/xz v0.5.15 // indirect
github.com/ultraware/funlen v0.2.0 // indirect
github.com/ultraware/whitespace v0.2.0 // indirect
github.com/uudashr/gocognit v1.2.0 // indirect
@@ -473,8 +470,8 @@ require (
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
- go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
- go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect
+ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect
go.opentelemetry.io/otel/trace v1.37.0 // indirect
go.uber.org/automaxprocs v1.6.0 // indirect
@@ -494,7 +491,7 @@ require (
golang.org/x/time v0.12.0 // indirect
golang.org/x/tools v0.35.0 // indirect
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0 // indirect
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 // indirect
gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
diff --git a/go.sum b/go.sum
index 68fe833348..3c8e39b2cd 100644
--- a/go.sum
+++ b/go.sum
@@ -4,14 +4,14 @@
4d63.com/gochecknoglobals v0.2.2/go.mod h1:lLxwTQjL5eIesRbvnzIP3jZtG140FnTdz+AlMa+ogt0=
al.essio.dev/pkg/shellescape v1.5.1 h1:86HrALUujYS/h+GtqoB26SBEdkWfmMI6FubjXlsXyho=
al.essio.dev/pkg/shellescape v1.5.1/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890=
-buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.6-20250121211742-6d880cc6cc8d.1 h1:f6miF8tK6H+Ktad24WpnNfpHO75GRGk0rhJ1mxPXqgA=
-buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.6-20250121211742-6d880cc6cc8d.1/go.mod h1:rvbyamNtvJ4o3ExeCmaG5/6iHnu0vy0E+UQ+Ph0om8s=
-buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250613105001-9f2d3c737feb.1 h1:AUL6VF5YWL01j/1H/DQbPUSDkEwYqwVCNw7yhbpOxSQ=
-buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250613105001-9f2d3c737feb.1/go.mod h1:avRlCjnFzl98VPaeCtJ24RrV/wwHFzB8sWXhj26+n/U=
-buf.build/gen/go/bufbuild/registry/connectrpc/go v1.18.1-20250606164443-9d1800bf4ccc.1 h1:x7juyChlm/fXZyuJTdBeMzHwAMhPJkP0qE4/IpwpGX4=
-buf.build/gen/go/bufbuild/registry/connectrpc/go v1.18.1-20250606164443-9d1800bf4ccc.1/go.mod h1:vi8xjh+6SQRvLQYnyVFZ7kOBrFevwFudusxWVc6E58A=
-buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.6-20250606164443-9d1800bf4ccc.1 h1:iiP7EL8EWrWmxn9qPDQTFdVSu04qIrmglpyjC10K4IU=
-buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.6-20250606164443-9d1800bf4ccc.1/go.mod h1:bUPpZtzAkcnTA7OLfKCvkvkxEAC6dG/ZIlbnbUJicL4=
+buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.6-20250718181942-e35f9b667443.1 h1:8kSz6PsTC64z3itQqwMgswSGR/QpB3ShZGycu+zq+58=
+buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.6-20250718181942-e35f9b667443.1/go.mod h1:TsmeaGU5CZAF7zRM05vIKgXh56GgwaoMS8X+a77RV5Q=
+buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250717185734-6c6e0d3c608e.1 h1:Lg6klmCi3v7VvpqeeLEER9/m5S8y9e9DjhqQnSCNy4k=
+buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250717185734-6c6e0d3c608e.1/go.mod h1:avRlCjnFzl98VPaeCtJ24RrV/wwHFzB8sWXhj26+n/U=
+buf.build/gen/go/bufbuild/registry/connectrpc/go v1.18.1-20250721151928-2b7ae473b098.1 h1:icgV8NMRNi31JwLZ8OJQK1HNIX3RTBdhjvpRPJF4fyI=
+buf.build/gen/go/bufbuild/registry/connectrpc/go v1.18.1-20250721151928-2b7ae473b098.1/go.mod h1:/MMEAJmz7PEmksjkSxhWXell82FXiG7BLUPBJRmKBsA=
+buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.6-20250721151928-2b7ae473b098.1 h1:fgiFo9f0jCni7kb5QxQ78CccZv6WLTH5Iea2B+AvSKY=
+buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.6-20250721151928-2b7ae473b098.1/go.mod h1:RsJBKYlgzsbl5LAhIu0cNrPPzBNenMLTAAykRxFidtw=
buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.36.6-20241007202033-cf42259fcbfc.1 h1:trcsXBDm8exui7mvndZnvworCyBq1xuMnod2N0j79K8=
buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.36.6-20241007202033-cf42259fcbfc.1/go.mod h1:OUbhXurY+VHFGn9FBxcRy8UB7HXk9NvJ2qCgifOMypQ=
buf.build/go/app v0.1.0 h1:nlqD/h0rhIN73ZoiDElprrPiO2N6JV+RmNK34K29Ihg=
@@ -20,8 +20,8 @@ buf.build/go/bufplugin v0.9.0 h1:ktZJNP3If7ldcWVqh46XKeiYJVPxHQxCfjzVQDzZ/lo=
buf.build/go/bufplugin v0.9.0/go.mod h1:Z0CxA3sKQ6EPz/Os4kJJneeRO6CjPeidtP1ABh5jPPY=
buf.build/go/interrupt v1.1.0 h1:olBuhgv9Sav4/9pkSLoxgiOsZDgM5VhRhvRpn3DL0lE=
buf.build/go/interrupt v1.1.0/go.mod h1:ql56nXPG1oHlvZa6efNC7SKAQ/tUjS6z0mhJl0gyeRM=
-buf.build/go/protovalidate v0.13.1 h1:6loHDTWdY/1qmqmt1MijBIKeN4T9Eajrqb9isT1W1s8=
-buf.build/go/protovalidate v0.13.1/go.mod h1:C/QcOn/CjXRn5udUwYBiLs8y1TGy7RS+GOSKqjS77aU=
+buf.build/go/protovalidate v0.14.0 h1:kr/rC/no+DtRyYX+8KXLDxNnI1rINz0imk5K44ZpZ3A=
+buf.build/go/protovalidate v0.14.0/go.mod h1:+F/oISho9MO7gJQNYC2VWLzcO1fTPmaTA08SDYJZncA=
buf.build/go/protoyaml v0.6.0 h1:Nzz1lvcXF8YgNZXk+voPPwdU8FjDPTUV4ndNTXN0n2w=
buf.build/go/protoyaml v0.6.0/go.mod h1:RgUOsBu/GYKLDSIRgQXniXbNgFlGEZnQpRAUdLAFV2Q=
buf.build/go/spdx v0.2.0 h1:IItqM0/cMxvFJJumcBuP8NrsIzMs/UYjp/6WSpq8LTw=
@@ -176,8 +176,8 @@ github.com/breml/errchkjson v0.4.1 h1:keFSS8D7A2T0haP9kzZTi7o26r7kE3vymjZNeNDRDw
github.com/breml/errchkjson v0.4.1/go.mod h1:a23OvR6Qvcl7DG/Z4o0el6BRAjKnaReoPQFciAl9U3s=
github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70=
github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
-github.com/bufbuild/buf v1.55.1 h1:yaRXO9YmtgyEhiqT/gwuJWhHN9xBBbqlQvXVnPauvCk=
-github.com/bufbuild/buf v1.55.1/go.mod h1:bvDF6WkvObC+ca9gmP++/oCAWeVVX7MspMcTFznqF7k=
+github.com/bufbuild/buf v1.56.0 h1:Z0eK+npK01FB924rtDVMOJtvBh9c421mYLo9QhUP3pM=
+github.com/bufbuild/buf v1.56.0/go.mod h1:uDNMYshCJIXL99OQc71SDeFiDqOse9sSHXPpZlrqElw=
github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
github.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1 h1:V1xulAoqLqVg44rY97xOR+mQpD2N+GzhMHVwJ030WEU=
@@ -233,8 +233,8 @@ 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.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8=
-github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU=
+github.com/containerd/stargz-snapshotter/estargz v0.17.0 h1:+TyQIsR/zSFI1Rm31EQBwpAA1ovYgIKHy7kctL3sLcE=
+github.com/containerd/stargz-snapshotter/estargz v0.17.0/go.mod h1:s06tWAiJcXQo9/8AReBCIo/QxcXFZ2n4qfsRnpl71SM=
github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=
github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
github.com/containers/image/v5 v5.36.0 h1:Zh+xFcLjRmicnOT5AFPHH/xj+e3s9ojDN/9X2Kx1+Jo=
@@ -317,8 +317,8 @@ github.com/envoyproxy/go-control-plane/contrib v1.32.5-0.20250430092421-68a532e1
github.com/envoyproxy/go-control-plane/contrib v1.32.5-0.20250430092421-68a532e11403/go.mod h1:Xkwx/TGvEKRCL2mitdiuQWOD1ECvfM5krWWVo2vI2Zk=
github.com/envoyproxy/go-control-plane/envoy v1.32.5-0.20250622153809-434b6986176d h1:mbxMT8XP3hEorIeTp4Yvcz5qKzE2n2q4IMU3SxuikaQ=
github.com/envoyproxy/go-control-plane/envoy v1.32.5-0.20250622153809-434b6986176d/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs=
-github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI=
-github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4=
+github.com/envoyproxy/go-control-plane/ratelimit v0.1.1-0.20250805143705-d51f8590a549 h1:5K0vH5H4dtCIO8+w/yq6vDaMcGn9RoPrHfmPAFAztwU=
+github.com/envoyproxy/go-control-plane/ratelimit v0.1.1-0.20250805143705-d51f8590a549/go.mod h1:KxtyvDAPIEkqUUvF9ooo5gSGVOtQ08wUTnQe5LsJC6c=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
@@ -492,8 +492,8 @@ github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e h1:gD6P7NEo7Eqt
github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e/go.mod h1:h+wZwLjUTJnm/P2rwlbJdRPZXOzaT36/FwnPnY2inzc=
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
-github.com/google/cel-go v0.25.0 h1:jsFw9Fhn+3y2kBbltZR4VEz5xKkcIFRPDnuEzAGv5GY=
-github.com/google/cel-go v0.25.0/go.mod h1:hjEb6r5SuOSlhCHmFoLzu8HGCERvIsDAbxDAyNU/MmI=
+github.com/google/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI=
+github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM=
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -718,8 +718,8 @@ github.com/mgechev/revive v1.11.0 h1:b/gLLpBE427o+Xmd8G58gSA+KtBwxWinH/A565Awh0w
github.com/mgechev/revive v1.11.0/go.mod h1:tI0oLF/2uj+InHCBLrrqfTKfjtFTBCFFfG05auyzgdw=
github.com/microsoft/go-mssqldb v1.9.2 h1:nY8TmFMQOHpm2qVWo6y4I2mAmVdZqlGiMGAYt64Ibbs=
github.com/microsoft/go-mssqldb v1.9.2/go.mod h1:GBbW9ASTiDC+mpgWDGKdm3FnFLTUsLYN3iFL90lQ+PA=
-github.com/miekg/dns v1.1.67 h1:kg0EHj0G4bfT5/oOys6HhZw4vmMlnoZ+gDu8tJ/AlI0=
-github.com/miekg/dns v1.1.67/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps=
+github.com/miekg/dns v1.1.68 h1:jsSRkNozw7G/mnmXULynzMNIsgY2dHC8LO6U6Ij2JEA=
+github.com/miekg/dns v1.1.68/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps=
github.com/mistifyio/go-zfs/v3 v3.0.1 h1:YaoXgBePoMA12+S1u/ddkv+QqxcfiZK4prI6HPnkFiU=
github.com/mistifyio/go-zfs/v3 v3.0.1/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
@@ -840,8 +840,8 @@ github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY=
github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
-github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
-github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
+github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
+github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
@@ -863,8 +863,8 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ=
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
-github.com/quic-go/quic-go v0.52.0 h1:/SlHrCRElyaU6MaEPKqKr9z83sBg2v4FLLvWM+Z47pA=
-github.com/quic-go/quic-go v0.52.0/go.mod h1:MFlGGpcpJqRAfmYi6NC2cptDPSxRWTOGNuP4wqrWmzQ=
+github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg=
+github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
github.com/raeperd/recvcheck v0.2.0 h1:GnU+NsbiCqdC2XX5+vMZzP+jAJC5fht7rcVTAhX74UI=
github.com/raeperd/recvcheck v0.2.0/go.mod h1:n04eYkwIR0JbgD73wT8wL4JjPC3wm0nFtzBnWNocnYU=
github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 h1:EaDatTxkdHG+U3Bk4EUr+DZ7fOGwTfezUiUJMaIcaho=
@@ -906,8 +906,8 @@ github.com/securego/gosec/v2 v2.22.6 h1:mixR+X+Z5fT6QddWY8jyU9gs43CyW0SnADHB6kJm
github.com/securego/gosec/v2 v2.22.6/go.mod h1:510TFNDMrIPytokyHQAVLvPeDr41Yihn2ak8P+XQfNE=
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
-github.com/segmentio/encoding v0.5.1 h1:LhmgXA5/alniiqfc4cYYrxF6DbUQ3m8MVz4/LQIU1mg=
-github.com/segmentio/encoding v0.5.1/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0=
+github.com/segmentio/encoding v0.5.3 h1:OjMgICtcSFuNvQCdwqMCv9Tg7lEOXGwm1J5RPQccx6w=
+github.com/segmentio/encoding v0.5.3/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0=
github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=
github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
@@ -949,8 +949,8 @@ github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YE
github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I=
github.com/stbenjam/no-sprintf-host-port v0.2.0 h1:i8pxvGrt1+4G0czLr/WnmyH7zbZ8Bg8etvARQ1rpyl4=
github.com/stbenjam/no-sprintf-host-port v0.2.0/go.mod h1:eL0bQ9PasS0hsyTyfTjjG+E80QIyPnBVQbYZyv20Jfk=
-github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
-github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
+github.com/stoewer/go-strcase v1.3.1 h1:iS0MdW+kVTxgMoE1LAZyMiYJFKlOzLooE4MxjirtkAs=
+github.com/stoewer/go-strcase v1.3.1/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
@@ -1007,8 +1007,8 @@ github.com/tsaarni/certyaml v0.10.0 h1:8ZWHO4Zg4VHUf7YblZNju44PcG5M+YtlJawiArYUH
github.com/tsaarni/certyaml v0.10.0/go.mod h1:rI1wDTE/VQIglHOyGbjfvqb+5mWTVT5uLFVDDcT1sq8=
github.com/tsaarni/x500dn v1.0.0 h1:LvaWTkqRpse4VHBhB5uwf3wytokK4vF9IOyNAEyiA+U=
github.com/tsaarni/x500dn v1.0.0/go.mod h1:QaHa3EcUKC4dfCAZmj8+ZRGLKukWgpGv9H3oOCsAbcE=
-github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
-github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
+github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY=
+github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ultraware/funlen v0.2.0 h1:gCHmCn+d2/1SemTdYMiKLAHFYxTYz7z9VIDRaTGyLkI=
github.com/ultraware/funlen v0.2.0/go.mod h1:ZE0q4TsJ8T1SQcjmkhN/w+MceuatI6pBFSxxyteHIJA=
github.com/ultraware/whitespace v0.2.0 h1:TYowo2m9Nfj1baEQBjuHzvMRbp19i+RCcRYrSWoFa+g=
@@ -1109,8 +1109,8 @@ go.opentelemetry.io/contrib/exporters/autoexport v0.57.0 h1:jmTVJ86dP60C01K3slFQ
go.opentelemetry.io/contrib/exporters/autoexport v0.57.0/go.mod h1:EJBheUMttD/lABFyLXhce47Wr6DPWYReCzaZiXadH7g=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 h1:PS8wXpbyaDJQ2VDHHncMe9Vct0Zn1fEjpsjrLxGJoSc=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0/go.mod h1:HDBUsEjOuRC0EzKZ1bSaRGZWUBAzo+MhAcUUORSr4D0=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY=
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0 h1:WzNab7hOOLzdDF/EoWCt4glhrbMPVMOO5JYTmpz36Ls=
@@ -1121,8 +1121,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 h1:zG8
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0/go.mod h1:hOfBCz8kv/wuq73Mx2H2QnWokh/kHZxkh6SNF2bdKtw=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0 h1:9PgnL3QNlj10uGxExowIDIZu66aVBwWhXmbOp1pa6RA=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0/go.mod h1:0ineDcLELf6JmKfuo0wvvhAVMuxWFYvkTin2iV4ydPQ=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 h1:dNzwXjZKpMpE2JhmO+9HsPl42NIXFIFSUSSs0fiqra0=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0/go.mod h1:90PoxvaEB5n6AOdZvi+yWJQoE95U8Dhhw2bSyRqnTD0=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg=
@@ -1147,8 +1147,8 @@ go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFh
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
-go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os=
-go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo=
+go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4=
+go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE=
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
@@ -1175,8 +1175,8 @@ golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+Zdx
golang.org/x/crypto/x509roots/fallback v0.0.0-20250406160420-959f8f3db0fb h1:Iu0p/klM0SM7atONioa/bPhLS7cjhnip99x1OIGibwg=
golang.org/x/crypto/x509roots/fallback v0.0.0-20250406160420-959f8f3db0fb/go.mod h1:lxN5T34bK4Z/i6cMaU7frUU57VkDXFD4Kamfl/cp9oU=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 h1:bsqhLWFR6G6xiQcb+JoGqdKdRU6WzPWmK8E0jxTjzo4=
-golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
+golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 h1:R9PFI6EUdfVKgwKjZef7QIwGcBKu86OEFpJ9nUEP2l4=
+golang.org/x/exp v0.0.0-20250718183923-645b1fa84792/go.mod h1:A+z0yzpGtvnG90cToK5n2tu8UJVP2XUATh+r+sfOOOc=
golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/exp/typeparams v0.0.0-20250620022241-b7579e27df2b h1:KdrhdYPDUvJTvrDK9gdjfFd6JTk8vA1WJoldYSi0kHo=
@@ -1330,10 +1330,10 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk=
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697/go.mod h1:JJrvXBWRZaFMxBufik1a4RpFw4HhgVtBBWQeQgUj2cc=
-google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY=
-google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
+google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0 h1:0UOBWO4dC+e51ui0NFKSPbkHHiQ4TmrEfEZMLDyRmY8=
+google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0/go.mod h1:8ytArBbtOy2xfht+y2fqKd5DRDJRUQhqbyEnQ4bDChs=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0 h1:MAKi5q709QWfnkkpNQ0M12hYJ1+e8qYVDyowc4U1XZM=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
diff --git a/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml b/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml
index 997bb75a1d..cec1825257 100644
--- a/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml
@@ -1214,14 +1214,14 @@ xds:
initialStreamWindowSize: 65536
maxConcurrentStreams: 100
httpFilters:
+ - name: envoy.filters.http.grpc_web
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
- name: envoy.filters.http.grpc_stats
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig
emitFilterState: true
statsForAllMethods: true
- - name: envoy.filters.http.grpc_web
- typedConfig:
- '@type': type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
- name: envoy.filters.http.router
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json
index b31e8aed56..84d7174948 100644
--- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json
+++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json
@@ -1090,17 +1090,17 @@
},
"httpFilters": [
{
- "name": "envoy.filters.http.grpc_stats",
+ "name": "envoy.filters.http.grpc_web",
"typedConfig": {
- "@type": "type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig",
- "emitFilterState": true,
- "statsForAllMethods": true
+ "@type": "type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb"
}
},
{
- "name": "envoy.filters.http.grpc_web",
+ "name": "envoy.filters.http.grpc_stats",
"typedConfig": {
- "@type": "type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb"
+ "@type": "type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig",
+ "emitFilterState": true,
+ "statsForAllMethods": true
}
},
{
diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml
index b6467311ec..2bf22747eb 100644
--- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml
@@ -667,14 +667,14 @@ xds:
initialStreamWindowSize: 65536
maxConcurrentStreams: 100
httpFilters:
+ - name: envoy.filters.http.grpc_web
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
- name: envoy.filters.http.grpc_stats
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig
emitFilterState: true
statsForAllMethods: true
- - name: envoy.filters.http.grpc_web
- typedConfig:
- '@type': type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
- name: envoy.filters.http.router
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.listener.yaml b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.listener.yaml
index 1c8fba4d1d..c0fa7da7c8 100644
--- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.listener.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.listener.yaml
@@ -230,14 +230,14 @@ xds:
initialStreamWindowSize: 65536
maxConcurrentStreams: 100
httpFilters:
+ - name: envoy.filters.http.grpc_web
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
- name: envoy.filters.http.grpc_stats
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig
emitFilterState: true
statsForAllMethods: true
- - name: envoy.filters.http.grpc_web
- typedConfig:
- '@type': type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
- name: envoy.filters.http.router
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
diff --git a/internal/cmd/egctl/translate_test.go b/internal/cmd/egctl/translate_test.go
index f7c401a9a0..bcca5377b4 100644
--- a/internal/cmd/egctl/translate_test.go
+++ b/internal/cmd/egctl/translate_test.go
@@ -22,7 +22,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/yaml"
- "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/utils/field"
"github.com/envoyproxy/gateway/internal/utils/file"
"github.com/envoyproxy/gateway/internal/utils/test"
@@ -377,7 +376,6 @@ func TestTranslate(t *testing.T) {
opts := []cmp.Option{
cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime"),
- cmpopts.IgnoreFields(resource.Resources{}, "serviceMap"),
}
require.Empty(t, cmp.Diff(want, got, opts...))
diff --git a/internal/cmd/server.go b/internal/cmd/server.go
index 6ba9f77b96..c4924d7149 100644
--- a/internal/cmd/server.go
+++ b/internal/cmd/server.go
@@ -24,8 +24,7 @@ import (
"github.com/envoyproxy/gateway/internal/message"
"github.com/envoyproxy/gateway/internal/metrics"
providerrunner "github.com/envoyproxy/gateway/internal/provider/runner"
- xdsserverrunner "github.com/envoyproxy/gateway/internal/xds/server/runner"
- xdstranslatorrunner "github.com/envoyproxy/gateway/internal/xds/translator/runner"
+ xdsrunner "github.com/envoyproxy/gateway/internal/xds/runner"
)
type Runner interface {
@@ -138,12 +137,10 @@ func startRunners(ctx context.Context, cfg *config.Server) (err error) {
pResources *message.ProviderResources
xdsIR *message.XdsIR
infraIR *message.InfraIR
- xds *message.Xds
}{
pResources: new(message.ProviderResources),
xdsIR: new(message.XdsIR),
infraIR: new(message.InfraIR),
- xds: new(message.Xds),
}
// The Elected channel is used to block the tasks that are waiting for the leader to be elected.
@@ -183,13 +180,13 @@ func startRunners(ctx context.Context, cfg *config.Server) (err error) {
}),
},
{
- // Start the Xds Translator Service
- // It subscribes to the xdsIR, translates it into xds Resources and publishes it.
+ // Start the Xds Service
+ // It subscribes to the xdsIR, translates it into xds Resources
+ // and publishes it into the xDS Cache.
// It also computes the EnvoyPatchPolicy statuses and publishes it.
- runner: xdstranslatorrunner.New(&xdstranslatorrunner.Config{
+ runner: xdsrunner.New(&xdsrunner.Config{
Server: *cfg,
XdsIR: channels.xdsIR,
- Xds: channels.xds,
ExtensionManager: extMgr,
ProviderResources: channels.pResources,
}),
@@ -203,15 +200,6 @@ func startRunners(ctx context.Context, cfg *config.Server) (err error) {
InfraIR: channels.infraIR,
}),
},
- {
- // Start the xDS Server
- // It subscribes to the xds Resources and configures the remote Envoy Proxy
- // via the xDS Protocol.
- runner: xdsserverrunner.New(&xdsserverrunner.Config{
- Server: *cfg,
- Xds: channels.xds,
- }),
- },
{
// Start the Admin Server
// It provides admin endpoints including pprof for debugging.
@@ -254,7 +242,6 @@ func startRunners(ctx context.Context, cfg *config.Server) (err error) {
channels.pResources,
channels.xdsIR,
channels.infraIR,
- channels.xds,
}
for _, ch := range closeChannels {
ch.Close()
diff --git a/internal/envoygateway/config/decoder_test.go b/internal/envoygateway/config/decoder_test.go
index cd49d89ff2..568a08b6f0 100644
--- a/internal/envoygateway/config/decoder_test.go
+++ b/internal/envoygateway/config/decoder_test.go
@@ -195,9 +195,7 @@ func TestDecode(t *testing.T) {
Provider: egv1a1.DefaultEnvoyGatewayProvider(),
Gateway: egv1a1.DefaultGateway(),
RateLimit: &egv1a1.RateLimit{
- Timeout: &metav1.Duration{
- Duration: 10000000,
- },
+ Timeout: ptr.To(gwapiv1.Duration("10ms")),
FailClosed: true,
Backend: egv1a1.RateLimitDatabaseBackend{
Type: egv1a1.RedisBackendType,
diff --git a/internal/gatewayapi/backend.go b/internal/gatewayapi/backend.go
index 300bac024a..d1772428a0 100644
--- a/internal/gatewayapi/backend.go
+++ b/internal/gatewayapi/backend.go
@@ -22,8 +22,6 @@ import (
func (t *Translator) ProcessBackends(backends []*egv1a1.Backend, backendTLSPolicies []*gwapiv1a3.BackendTLSPolicy) []*egv1a1.Backend {
var res []*egv1a1.Backend
for _, backend := range backends {
- backend := backend.DeepCopy()
-
// Ensure Backends are enabled
if !t.BackendEnabled {
status.UpdateBackendStatusAcceptedCondition(backend, false,
diff --git a/internal/gatewayapi/backendtrafficpolicy.go b/internal/gatewayapi/backendtrafficpolicy.go
index 7b10a951fe..c62d21bc9c 100644
--- a/internal/gatewayapi/backendtrafficpolicy.go
+++ b/internal/gatewayapi/backendtrafficpolicy.go
@@ -12,6 +12,7 @@ import (
"sort"
"strconv"
"strings"
+ "time"
perr "github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -41,19 +42,7 @@ func (t *Translator) ProcessBackendTrafficPolicies(resources *resource.Resources
res := make([]*egv1a1.BackendTrafficPolicy, 0, len(resources.BackendTrafficPolicies))
backendTrafficPolicies := resources.BackendTrafficPolicies
-
- // Initially, backendTrafficPolicies sort by creation timestamp
- // or sort alphabetically by “{namespace}/{name}” if multiple policies share same timestamp.
- sort.Slice(backendTrafficPolicies, func(i, j int) bool {
- if backendTrafficPolicies[i].CreationTimestamp.Equal(&(backendTrafficPolicies[j].CreationTimestamp)) {
- policyKeyI := fmt.Sprintf("%s/%s", backendTrafficPolicies[i].Namespace, backendTrafficPolicies[i].Name)
- policyKeyJ := fmt.Sprintf("%s/%s", backendTrafficPolicies[j].Namespace, backendTrafficPolicies[j].Name)
- return policyKeyI < policyKeyJ
- }
- // Not identical CreationTimestamps
-
- return backendTrafficPolicies[i].CreationTimestamp.Before(&(backendTrafficPolicies[j].CreationTimestamp))
- })
+ // BackendTrafficPolicies are already sorted by the provider layer
// First build a map out of the routes and gateways for faster lookup since users might have thousands of routes or more.
routeMap := map[policyTargetRouteKey]*policyRouteTargetContext{}
@@ -88,7 +77,7 @@ func (t *Translator) ProcessBackendTrafficPolicies(resources *resource.Resources
// TODO: This loop is similar to the one 'Process the policies targeting Gateways', we may want to
// merge them into one if possible.
for _, currPolicy := range backendTrafficPolicies {
- targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways)
+ targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways, currPolicy.Namespace)
for _, currTarget := range targetRefs {
if currTarget.Kind == resource.KindGateway {
// Check if the gateway exists
@@ -115,12 +104,12 @@ func (t *Translator) ProcessBackendTrafficPolicies(resources *resource.Resources
// Process the policies targeting xRoutes
for _, currPolicy := range backendTrafficPolicies {
policyName := utils.NamespacedName(currPolicy)
- targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, routes)
+ targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, routes, currPolicy.Namespace)
for _, currTarget := range targetRefs {
if currTarget.Kind != resource.KindGateway {
policy, found := handledPolicies[policyName]
if !found {
- policy = currPolicy.DeepCopy()
+ policy = currPolicy
handledPolicies[policyName] = policy
res = append(res, policy)
}
@@ -243,12 +232,12 @@ func (t *Translator) ProcessBackendTrafficPolicies(resources *resource.Resources
// Process the policies targeting Gateways
for _, currPolicy := range backendTrafficPolicies {
policyName := utils.NamespacedName(currPolicy)
- targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways)
+ targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways, currPolicy.Namespace)
for _, currTarget := range targetRefs {
if currTarget.Kind == resource.KindGateway {
policy, found := handledPolicies[policyName]
if !found {
- policy = currPolicy.DeepCopy()
+ policy = currPolicy
handledPolicies[policyName] = policy
res = append(res, policy)
}
@@ -556,7 +545,7 @@ func applyTrafficFeatureToRoute(route RouteContext,
func mergeBackendTrafficPolicy(routePolicy, gwPolicy *egv1a1.BackendTrafficPolicy) (*egv1a1.BackendTrafficPolicy, error) {
if routePolicy.Spec.MergeType == nil || gwPolicy == nil {
- return routePolicy.DeepCopy(), nil
+ return routePolicy, nil
}
return utils.Merge[*egv1a1.BackendTrafficPolicy](gwPolicy, routePolicy, *routePolicy.Spec.MergeType)
@@ -974,14 +963,24 @@ func int64ToUint32(in int64) (uint32, bool) {
}
func (t *Translator) buildFaultInjection(policy *egv1a1.BackendTrafficPolicy) *ir.FaultInjection {
- var fi *ir.FaultInjection
+ var (
+ fi *ir.FaultInjection
+ d time.Duration
+ err error
+ )
if policy.Spec.FaultInjection != nil {
fi = &ir.FaultInjection{}
if policy.Spec.FaultInjection.Delay != nil {
+ if policy.Spec.FaultInjection.Delay.FixedDelay != nil {
+ d, err = time.ParseDuration(string(*policy.Spec.FaultInjection.Delay.FixedDelay))
+ if err != nil {
+ return nil
+ }
+ }
fi.Delay = &ir.FaultInjectionDelay{
Percentage: policy.Spec.FaultInjection.Delay.Percentage,
- FixedDelay: policy.Spec.FaultInjection.Delay.FixedDelay,
+ FixedDelay: ir.MetaV1DurationPtr(d),
}
}
if policy.Spec.FaultInjection.Abort != nil {
diff --git a/internal/gatewayapi/clienttrafficpolicy.go b/internal/gatewayapi/clienttrafficpolicy.go
index 40e37fdf0a..6b214bdf0f 100644
--- a/internal/gatewayapi/clienttrafficpolicy.go
+++ b/internal/gatewayapi/clienttrafficpolicy.go
@@ -18,7 +18,6 @@ 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"
@@ -46,19 +45,7 @@ func (t *Translator) ProcessClientTrafficPolicies(
var res []*egv1a1.ClientTrafficPolicy
clientTrafficPolicies := resources.ClientTrafficPolicies
-
- // Initially, clientTrafficPolicies sort by creation timestamp
- // or sort alphabetically by “{namespace}/{name}” if multiple policies share same timestamp.
- sort.Slice(clientTrafficPolicies, func(i, j int) bool {
- if clientTrafficPolicies[i].CreationTimestamp.Equal(&(clientTrafficPolicies[j].CreationTimestamp)) {
- policyKeyI := fmt.Sprintf("%s/%s", clientTrafficPolicies[i].Namespace, clientTrafficPolicies[i].Name)
- policyKeyJ := fmt.Sprintf("%s/%s", clientTrafficPolicies[j].Namespace, clientTrafficPolicies[j].Name)
- return policyKeyI < policyKeyJ
- }
- // Not identical CreationTimestamps
-
- return clientTrafficPolicies[i].CreationTimestamp.Before(&(clientTrafficPolicies[j].CreationTimestamp))
- })
+ // ClientTrafficPolicies are already sorted by the provider layer
policyMap := make(map[types.NamespacedName]sets.Set[string])
@@ -85,7 +72,7 @@ func (t *Translator) ProcessClientTrafficPolicies(
if hasSectionName(&currTarget) {
policy, found := handledPolicies[policyName]
if !found {
- policy = currPolicy.DeepCopy()
+ policy = currPolicy
handledPolicies[policyName] = policy
res = append(res, policy)
}
@@ -176,13 +163,13 @@ func (t *Translator) ProcessClientTrafficPolicies(
// Policy with no section set (targeting all sections)
for _, currPolicy := range clientTrafficPolicies {
policyName := utils.NamespacedName(currPolicy)
- targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways)
+ targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways, currPolicy.Namespace)
for _, currTarget := range targetRefs {
if !hasSectionName(&currTarget) {
policy, found := handledPolicies[policyName]
if !found {
- policy = currPolicy.DeepCopy()
+ policy = currPolicy
res = append(res, policy)
handledPolicies[policyName] = policy
}
@@ -601,9 +588,7 @@ func buildClientTimeout(clientTimeout *egv1a1.ClientTimeout) (*ir.ClientTimeout,
if err != nil {
return nil, fmt.Errorf("invalid TCP IdleTimeout value %s", *clientTimeout.TCP.IdleTimeout)
}
- irTCPTimeout.IdleTimeout = &metav1.Duration{
- Duration: d,
- }
+ irTCPTimeout.IdleTimeout = ir.MetaV1DurationPtr(d)
}
irClientTimeout.TCP = irTCPTimeout
}
@@ -615,9 +600,7 @@ func buildClientTimeout(clientTimeout *egv1a1.ClientTimeout) (*ir.ClientTimeout,
if err != nil {
return nil, fmt.Errorf("invalid HTTP RequestReceivedTimeout value %s", *clientTimeout.HTTP.RequestReceivedTimeout)
}
- irHTTPTimeout.RequestReceivedTimeout = &metav1.Duration{
- Duration: d,
- }
+ irHTTPTimeout.RequestReceivedTimeout = ir.MetaV1DurationPtr(d)
}
if clientTimeout.HTTP.IdleTimeout != nil {
@@ -625,9 +608,7 @@ func buildClientTimeout(clientTimeout *egv1a1.ClientTimeout) (*ir.ClientTimeout,
if err != nil {
return nil, fmt.Errorf("invalid HTTP IdleTimeout value %s", *clientTimeout.HTTP.IdleTimeout)
}
- irHTTPTimeout.IdleTimeout = &metav1.Duration{
- Duration: d,
- }
+ irHTTPTimeout.IdleTimeout = ir.MetaV1DurationPtr(d)
}
if clientTimeout.HTTP.StreamIdleTimeout != nil {
@@ -635,9 +616,7 @@ func buildClientTimeout(clientTimeout *egv1a1.ClientTimeout) (*ir.ClientTimeout,
if err != nil {
return nil, fmt.Errorf("invalid HTTP StreamIdleTimeout value %s", *clientTimeout.HTTP.StreamIdleTimeout)
}
- irHTTPTimeout.StreamIdleTimeout = &metav1.Duration{
- Duration: d,
- }
+ irHTTPTimeout.StreamIdleTimeout = ir.MetaV1DurationPtr(d)
}
irClientTimeout.HTTP = irHTTPTimeout
}
@@ -962,7 +941,7 @@ func buildConnection(connection *egv1a1.ClientConnection) (*ir.ClientConnection,
if err != nil {
return nil, fmt.Errorf("invalid CloseDelay value %s", *connection.ConnectionLimit.CloseDelay)
}
- irConnectionLimit.CloseDelay = ptr.To(metav1.Duration{Duration: d})
+ irConnectionLimit.CloseDelay = ir.MetaV1DurationPtr(d)
}
irConnection.ConnectionLimit = irConnectionLimit
@@ -980,10 +959,14 @@ func buildConnection(connection *egv1a1.ClientConnection) (*ir.ClientConnection,
irConnection.BufferLimitBytes = ptr.To(uint32(bufferLimit))
}
+ if connection.MaxAcceptPerSocketEvent != nil {
+ irConnection.MaxAcceptPerSocketEvent = ptr.To(*connection.MaxAcceptPerSocketEvent)
+ }
+
return irConnection, nil
}
-func translateEarlyRequestHeaders(headerModifier *gwapiv1.HTTPHeaderFilter) ([]ir.AddHeader, []string, error) {
+func translateEarlyRequestHeaders(headerModifier *egv1a1.HTTPHeaderFilter) ([]ir.AddHeader, []string, error) {
// Make sure the header modifier config actually exists
if headerModifier == nil {
return nil, nil, nil
diff --git a/internal/gatewayapi/clustersettings.go b/internal/gatewayapi/clustersettings.go
index 6473e9b9dd..42de49bad8 100644
--- a/internal/gatewayapi/clustersettings.go
+++ b/internal/gatewayapi/clustersettings.go
@@ -104,7 +104,7 @@ func buildClusterSettingsTimeout(policy egv1a1.ClusterSettings) (*ir.Timeout, er
errs = errors.Join(errs, fmt.Errorf("invalid ConnectTimeout value %s", *pto.TCP.ConnectTimeout))
} else {
to.TCP = &ir.TCPTimeout{
- ConnectTimeout: ptr.To(metav1.Duration{Duration: d}),
+ ConnectTimeout: ir.MetaV1DurationPtr(d),
}
}
}
@@ -119,7 +119,7 @@ func buildClusterSettingsTimeout(policy egv1a1.ClusterSettings) (*ir.Timeout, er
if err != nil {
errs = errors.Join(errs, fmt.Errorf("invalid ConnectionIdleTimeout value %s", *pto.HTTP.ConnectionIdleTimeout))
} else {
- cit = ptr.To(metav1.Duration{Duration: d})
+ cit = ir.MetaV1DurationPtr(d)
}
}
@@ -128,7 +128,7 @@ func buildClusterSettingsTimeout(policy egv1a1.ClusterSettings) (*ir.Timeout, er
if err != nil {
errs = errors.Join(errs, fmt.Errorf("invalid MaxConnectionDuration value %s", *pto.HTTP.MaxConnectionDuration))
} else {
- mcd = ptr.To(metav1.Duration{Duration: d})
+ mcd = ir.MetaV1DurationPtr(d)
}
}
@@ -137,7 +137,7 @@ func buildClusterSettingsTimeout(policy egv1a1.ClusterSettings) (*ir.Timeout, er
if err != nil {
errs = errors.Join(errs, fmt.Errorf("invalid RequestTimeout value %s", *pto.HTTP.RequestTimeout))
} else {
- rt = ptr.To(metav1.Duration{Duration: d})
+ rt = ir.MetaV1DurationPtr(d)
}
}
@@ -293,8 +293,12 @@ func buildLoadBalancer(policy egv1a1.ClusterSettings) (*ir.LoadBalancer, error)
LeastRequest: &ir.LeastRequest{},
}
if policy.LoadBalancer.SlowStart != nil && policy.LoadBalancer.SlowStart.Window != nil {
+ d, err := time.ParseDuration(string(*policy.LoadBalancer.SlowStart.Window))
+ if err != nil {
+ return nil, err
+ }
lb.LeastRequest.SlowStart = &ir.SlowStart{
- Window: policy.LoadBalancer.SlowStart.Window,
+ Window: ir.MetaV1DurationPtr(d),
}
}
case egv1a1.RandomLoadBalancerType:
@@ -306,8 +310,25 @@ func buildLoadBalancer(policy egv1a1.ClusterSettings) (*ir.LoadBalancer, error)
RoundRobin: &ir.RoundRobin{},
}
if policy.LoadBalancer.SlowStart != nil && policy.LoadBalancer.SlowStart.Window != nil {
+ d, err := time.ParseDuration(string(*policy.LoadBalancer.SlowStart.Window))
+ if err != nil {
+ return nil, err
+ }
lb.RoundRobin.SlowStart = &ir.SlowStart{
- Window: policy.LoadBalancer.SlowStart.Window,
+ Window: ir.MetaV1DurationPtr(d),
+ }
+ }
+ }
+
+ // Add ZoneAware loadbalancer settings
+ if policy.LoadBalancer.ZoneAware != nil && policy.LoadBalancer.ZoneAware.PreferLocal != nil {
+ preferLocal := policy.LoadBalancer.ZoneAware.PreferLocal
+ lb.PreferLocal = &ir.PreferLocalZone{
+ MinEndpointsThreshold: preferLocal.MinEndpointsThreshold,
+ }
+ if preferLocal.Force != nil {
+ lb.PreferLocal.Force = &ir.ForceLocalZone{
+ MinEndpointsInZoneThreshold: preferLocal.Force.MinEndpointsInZoneThreshold,
}
}
}
@@ -402,14 +423,28 @@ func buildPassiveHealthCheck(policy egv1a1.HealthCheck) *ir.OutlierDetection {
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,
}
+
+ if hc.Interval != nil {
+ d, err := time.ParseDuration(string(*hc.Interval))
+ if err != nil {
+ return nil
+ }
+ irOD.Interval = ir.MetaV1DurationPtr(d)
+ }
+
+ if hc.BaseEjectionTime != nil {
+ d, err := time.ParseDuration(string(*hc.BaseEjectionTime))
+ if err != nil {
+ return nil
+ }
+ irOD.BaseEjectionTime = ir.MetaV1DurationPtr(d)
+ }
return irOD
}
@@ -420,12 +455,22 @@ func buildActiveHealthCheck(policy egv1a1.HealthCheck) *ir.ActiveHealthCheck {
hc := policy.Active
irHC := &ir.ActiveHealthCheck{
- Timeout: hc.Timeout,
- Interval: hc.Interval,
InitialJitter: hc.InitialJitter,
UnhealthyThreshold: hc.UnhealthyThreshold,
HealthyThreshold: hc.HealthyThreshold,
}
+
+ if hc.Timeout != nil {
+ if d, err := time.ParseDuration(string(*hc.Timeout)); err == nil {
+ irHC.Timeout = ir.MetaV1DurationPtr(d)
+ }
+ }
+
+ if hc.Interval != nil {
+ if d, err := time.ParseDuration(string(*hc.Interval)); err == nil {
+ irHC.Interval = ir.MetaV1DurationPtr(d)
+ }
+ }
switch hc.Type {
case egv1a1.ActiveHealthCheckerTypeHTTP:
irHC.HTTP = buildHTTPActiveHealthChecker(hc.HTTP)
@@ -509,11 +554,18 @@ func translateDNS(policy egv1a1.ClusterSettings) *ir.DNS {
if policy.DNS == nil {
return nil
}
- return &ir.DNS{
- LookupFamily: policy.DNS.LookupFamily,
- RespectDNSTTL: policy.DNS.RespectDNSTTL,
- DNSRefreshRate: policy.DNS.DNSRefreshRate,
+ irDNS := &ir.DNS{
+ LookupFamily: policy.DNS.LookupFamily,
+ RespectDNSTTL: policy.DNS.RespectDNSTTL,
}
+
+ if policy.DNS.DNSRefreshRate != nil {
+ if d, err := time.ParseDuration(string(*policy.DNS.DNSRefreshRate)); err == nil {
+ irDNS.DNSRefreshRate = ir.MetaV1DurationPtr(d)
+ }
+ }
+
+ return irDNS
}
func buildRetry(r *egv1a1.Retry) (*ir.Retry, error) {
@@ -552,7 +604,11 @@ func buildRetry(r *egv1a1.Retry) (*ir.Retry, error) {
bpr := false
if r.PerRetry.Timeout != nil {
- pr.Timeout = r.PerRetry.Timeout
+ d, err := time.ParseDuration(string(*r.PerRetry.Timeout))
+ if err != nil {
+ return nil, err
+ }
+ pr.Timeout = ir.MetaV1DurationPtr(d)
bpr = true
}
@@ -560,18 +616,22 @@ func buildRetry(r *egv1a1.Retry) (*ir.Retry, error) {
if r.PerRetry.BackOff.MaxInterval != nil || r.PerRetry.BackOff.BaseInterval != nil {
bop := &ir.BackOffPolicy{}
if r.PerRetry.BackOff.BaseInterval != nil {
- bop.BaseInterval = r.PerRetry.BackOff.BaseInterval
- if bop.BaseInterval.Duration == 0 {
- return nil, fmt.Errorf("baseInterval cannot be set to 0s")
+ if d, err := time.ParseDuration(string(*r.PerRetry.BackOff.BaseInterval)); err == nil {
+ bop.BaseInterval = ir.MetaV1DurationPtr(d)
+ if bop.BaseInterval.Duration == 0 {
+ return nil, fmt.Errorf("baseInterval cannot be set to 0s")
+ }
}
}
if r.PerRetry.BackOff.MaxInterval != nil {
- bop.MaxInterval = r.PerRetry.BackOff.MaxInterval
- if bop.MaxInterval.Duration == 0 {
- return nil, fmt.Errorf("maxInterval cannot be set to 0s")
- }
- if bop.BaseInterval != nil && bop.BaseInterval.Duration > bop.MaxInterval.Duration {
- return nil, fmt.Errorf("maxInterval cannot be less than baseInterval")
+ if d, err := time.ParseDuration(string(*r.PerRetry.BackOff.MaxInterval)); err == nil {
+ bop.MaxInterval = ir.MetaV1DurationPtr(d)
+ if bop.MaxInterval.Duration == 0 {
+ return nil, fmt.Errorf("maxInterval cannot be set to 0s")
+ }
+ if bop.BaseInterval != nil && bop.BaseInterval.Duration > bop.MaxInterval.Duration {
+ return nil, fmt.Errorf("maxInterval cannot be less than baseInterval")
+ }
}
}
diff --git a/internal/gatewayapi/envoyextensionpolicy.go b/internal/gatewayapi/envoyextensionpolicy.go
index 46894556a1..061898b435 100644
--- a/internal/gatewayapi/envoyextensionpolicy.go
+++ b/internal/gatewayapi/envoyextensionpolicy.go
@@ -42,19 +42,7 @@ func (t *Translator) ProcessEnvoyExtensionPolicies(envoyExtensionPolicies []*egv
xdsIR resource.XdsIRMap,
) []*egv1a1.EnvoyExtensionPolicy {
var res []*egv1a1.EnvoyExtensionPolicy
-
- // Initially, policies sort by creation timestamp
- // or sort alphabetically by “{namespace}/{name}” if multiple gateways share same timestamp.
- sort.Slice(envoyExtensionPolicies, func(i, j int) bool {
- if envoyExtensionPolicies[i].CreationTimestamp.Equal(&(envoyExtensionPolicies[j].CreationTimestamp)) {
- policyKeyI := fmt.Sprintf("%s/%s", envoyExtensionPolicies[i].Namespace, envoyExtensionPolicies[i].Name)
- policyKeyJ := fmt.Sprintf("%s/%s", envoyExtensionPolicies[j].Namespace, envoyExtensionPolicies[j].Name)
- return policyKeyI < policyKeyJ
- }
- // Not identical CreationTimestamps
-
- return envoyExtensionPolicies[i].CreationTimestamp.Before(&(envoyExtensionPolicies[j].CreationTimestamp))
- })
+ // EnvoyExtensionPolicies are already sorted by the provider layer
// First build a map out of the routes and gateways for faster lookup since users might have thousands of routes or more.
routeMap := map[policyTargetRouteKey]*policyRouteTargetContext{}
@@ -85,12 +73,12 @@ func (t *Translator) ProcessEnvoyExtensionPolicies(envoyExtensionPolicies []*egv
// Process the policies targeting xRoutes
for _, currPolicy := range envoyExtensionPolicies {
policyName := utils.NamespacedName(currPolicy)
- targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, routes)
+ targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, routes, currPolicy.Namespace)
for _, currTarget := range targetRefs {
if currTarget.Kind != resource.KindGateway {
policy, found := handledPolicies[policyName]
if !found {
- policy = currPolicy.DeepCopy()
+ policy = currPolicy
res = append(res, policy)
handledPolicies[policyName] = policy
}
@@ -159,12 +147,12 @@ func (t *Translator) ProcessEnvoyExtensionPolicies(envoyExtensionPolicies []*egv
// Process the policies targeting Gateways
for _, currPolicy := range envoyExtensionPolicies {
policyName := utils.NamespacedName(currPolicy)
- targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways)
+ targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways, currPolicy.Namespace)
for _, currTarget := range targetRefs {
if currTarget.Kind == resource.KindGateway {
policy, found := handledPolicies[policyName]
if !found {
- policy = currPolicy.DeepCopy()
+ policy = currPolicy
res = append(res, policy)
handledPolicies[policyName] = policy
}
@@ -478,7 +466,6 @@ func (t *Translator) buildLua(
envoyProxy *egv1a1.EnvoyProxy,
) (*ir.Lua, error) {
var luaCode *string
- var luaValidation egv1a1.LuaValidation
var err error
if lua.Type == egv1a1.LuaValueTypeValueRef {
luaCode, err = getLuaBodyFromLocalObjectReference(lua.ValueRef, resources, policy.Namespace)
@@ -488,12 +475,8 @@ func (t *Translator) buildLua(
if err != nil {
return nil, err
}
- if envoyProxy != nil && envoyProxy.Spec.LuaValidation != nil {
- luaValidation = *envoyProxy.Spec.LuaValidation
- } else {
- luaValidation = egv1a1.LuaValidationStrict
- }
- if err = luavalidator.NewLuaValidator(*luaCode, luaValidation).Validate(); err != nil {
+
+ if err = luavalidator.NewLuaValidator(*luaCode, envoyProxy).Validate(); err != nil {
return nil, fmt.Errorf("validation failed for lua body in policy with name %v: %w", name, err)
}
return &ir.Lua{
@@ -605,7 +588,7 @@ func (t *Translator) buildExtProc(
if err != nil {
return nil, fmt.Errorf("invalid ExtProc MessageTimeout value %v", extProc.MessageTimeout)
}
- extProcIR.MessageTimeout = ptr.To(metav1.Duration{Duration: d})
+ extProcIR.MessageTimeout = ir.MetaV1DurationPtr(d)
}
if extProc.FailOpen != nil {
diff --git a/internal/gatewayapi/envoypatchpolicy.go b/internal/gatewayapi/envoypatchpolicy.go
index 1934168b1e..2b6f0f39c5 100644
--- a/internal/gatewayapi/envoypatchpolicy.go
+++ b/internal/gatewayapi/envoypatchpolicy.go
@@ -7,7 +7,6 @@ package gatewayapi
import (
"fmt"
- "sort"
"k8s.io/apimachinery/pkg/types"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
@@ -20,26 +19,11 @@ import (
)
func (t *Translator) ProcessEnvoyPatchPolicies(envoyPatchPolicies []*egv1a1.EnvoyPatchPolicy, xdsIR resource.XdsIRMap) {
- // Initially, envoyPatchPolicies sort by priority
- // if the priority is equal, they sort based on creation timestamp
- // or sort alphabetically by “{namespace}/{name}” if multiple policies share same timestamp.
- sort.Slice(envoyPatchPolicies, func(i, j int) bool {
- if envoyPatchPolicies[i].Spec.Priority == envoyPatchPolicies[j].Spec.Priority {
- if envoyPatchPolicies[i].CreationTimestamp.Equal(&(envoyPatchPolicies[j].CreationTimestamp)) {
- policyKeyI := fmt.Sprintf("%s/%s", envoyPatchPolicies[i].Namespace, envoyPatchPolicies[i].Name)
- policyKeyJ := fmt.Sprintf("%s/%s", envoyPatchPolicies[j].Namespace, envoyPatchPolicies[j].Name)
- return policyKeyI < policyKeyJ
- }
- // Not identical CreationTimestamps
- return envoyPatchPolicies[i].CreationTimestamp.Before(&(envoyPatchPolicies[j].CreationTimestamp))
- }
- // Not identical Priorities
- return envoyPatchPolicies[i].Spec.Priority < envoyPatchPolicies[j].Spec.Priority
- })
+ // EnvoyPatchPolicies are already sorted by the provider layer (priority, then timestamp, then name)
for _, policy := range envoyPatchPolicies {
var (
- policy = policy.DeepCopy()
+ policy = policy
ancestorRefs []gwapiv1a2.ParentReference
resolveErr *status.PolicyResolveError
targetKind string
diff --git a/internal/gatewayapi/extensionserverpolicy.go b/internal/gatewayapi/extensionserverpolicy.go
index b6e7fbb700..bb65606c06 100644
--- a/internal/gatewayapi/extensionserverpolicy.go
+++ b/internal/gatewayapi/extensionserverpolicy.go
@@ -9,7 +9,6 @@ import (
"encoding/json"
"errors"
"fmt"
- "sort"
"strings"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@@ -28,21 +27,7 @@ func (t *Translator) ProcessExtensionServerPolicies(policies []unstructured.Unst
xdsIR resource.XdsIRMap,
) ([]unstructured.Unstructured, error) {
res := []unstructured.Unstructured{}
-
- // Initially, policies sort by creation timestamp
- // or sort alphabetically by “{namespace}/{name}” if multiple gateways share same timestamp.
- sort.Slice(policies, func(i, j int) bool {
- tsI := policies[i].GetCreationTimestamp()
- tsJ := policies[j].GetCreationTimestamp()
- if tsI.Equal(&tsJ) {
- policyKeyI := fmt.Sprintf("%s/%s", policies[i].GetNamespace(), policies[i].GetName())
- policyKeyJ := fmt.Sprintf("%s/%s", policies[j].GetNamespace(), policies[j].GetName())
- return policyKeyI < policyKeyJ
- }
- // Not identical CreationTimestamps
-
- return tsI.Before(&tsJ)
- })
+ // ExtensionServerPolicies are already sorted by the provider layer
// First build a map out of the gateways for faster lookup
gatewayMap := map[types.NamespacedName]*policyGatewayTargetContext{}
@@ -55,7 +40,7 @@ func (t *Translator) ProcessExtensionServerPolicies(policies []unstructured.Unst
// Process the policies targeting Gateways. Only update the policy status if it was accepted.
// A policy is considered accepted if at least one targetRef contained inside matched a listener.
for policyIndex, policy := range policies {
- policy := policy.DeepCopy()
+ policy := &policy
var policyStatus gwapiv1a2.PolicyStatus
accepted := false
targetRefs, err := extractTargetRefs(policy, gateways)
@@ -118,7 +103,7 @@ func extractTargetRefs(policy *unstructured.Unstructured, gateways []*GatewayCon
if err := json.Unmarshal(specAsJSON, &targetRefs); err != nil {
return nil, fmt.Errorf("no targets found for the policy")
}
- ret := getPolicyTargetRefs(targetRefs, gateways)
+ ret := getPolicyTargetRefs(targetRefs, gateways, policy.GetNamespace())
if len(ret) == 0 {
return nil, fmt.Errorf("no targets found for the policy")
}
diff --git a/internal/gatewayapi/filters.go b/internal/gatewayapi/filters.go
index 631de32472..b4fa79d79f 100644
--- a/internal/gatewayapi/filters.go
+++ b/internal/gatewayapi/filters.go
@@ -136,7 +136,7 @@ func (t *Translator) ProcessGRPCFilters(parentRef *RouteParentContext,
if httpFiltersContext.DirectResponse != nil {
break
}
- if err := ValidateGRPCRouteFilter(&filter); err != nil {
+ if err := ValidateGRPCRouteFilter(&filter, t.ExtensionGroupKinds...); err != nil {
t.processInvalidHTTPFilter(string(filter.Type), httpFiltersContext, err)
break
}
@@ -1032,7 +1032,7 @@ func (t *Translator) processCORSFilter(
AllowMethods: allowMethods,
AllowHeaders: allowHeaders,
ExposeHeaders: exposeHeaders,
- MaxAge: ptr.To(metav1.Duration{Duration: time.Duration(corsFilter.MaxAge) * time.Second}),
+ MaxAge: ir.MetaV1DurationPtr(time.Duration(corsFilter.MaxAge) * time.Second),
AllowCredentials: bool(corsFilter.AllowCredentials),
}
}
diff --git a/internal/gatewayapi/globalresources.go b/internal/gatewayapi/globalresources.go
index 24830e34b4..c0ce06d0f9 100644
--- a/internal/gatewayapi/globalresources.go
+++ b/internal/gatewayapi/globalresources.go
@@ -32,6 +32,11 @@ func (t *Translator) ProcessGlobalResources(resources *resource.Resources, xdsIR
xdsIRs[irKey].GlobalResources = &ir.GlobalResources{}
}
xdsIRs[irKey].GlobalResources.ProxyServiceCluster = rDest
+
+ // For merged gateways we only need to process once
+ if t.MergeGateways {
+ break
+ }
}
// Get the envoy client TLS secret. It is used for envoy to establish a TLS connection with control plane components,
diff --git a/internal/gatewayapi/helpers.go b/internal/gatewayapi/helpers.go
index 2126a93ce8..efa9659df4 100644
--- a/internal/gatewayapi/helpers.go
+++ b/internal/gatewayapi/helpers.go
@@ -556,7 +556,7 @@ func selectorFromTargetSelector(selector egv1a1.TargetSelector) labels.Selector
return l
}
-func getPolicyTargetRefs[T client.Object](policy egv1a1.PolicyTargetReferences, potentialTargets []T) []gwapiv1a2.LocalPolicyTargetReferenceWithSectionName {
+func getPolicyTargetRefs[T client.Object](policy egv1a1.PolicyTargetReferences, potentialTargets []T, policyNamespace string) []gwapiv1a2.LocalPolicyTargetReferenceWithSectionName {
dedup := sets.New[targetRefWithTimestamp]()
for _, currSelector := range policy.TargetSelectors {
labelSelector := selectorFromTargetSelector(currSelector)
@@ -567,6 +567,11 @@ func getPolicyTargetRefs[T client.Object](policy egv1a1.PolicyTargetReferences,
continue
}
+ // Skip objects not in the same namespace as the policy
+ if obj.GetNamespace() != policyNamespace {
+ continue
+ }
+
if labelSelector.Matches(labels.Set(obj.GetLabels())) {
dedup.Insert(targetRefWithTimestamp{
CreationTimestamp: obj.GetCreationTimestamp(),
diff --git a/internal/gatewayapi/helpers_test.go b/internal/gatewayapi/helpers_test.go
index 72df6c66c9..228daed0d5 100644
--- a/internal/gatewayapi/helpers_test.go
+++ b/internal/gatewayapi/helpers_test.go
@@ -581,7 +581,7 @@ func TestGetPolicyTargetRefs(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
- results := getPolicyTargetRefs(tc.policy, tc.targets)
+ results := getPolicyTargetRefs(tc.policy, tc.targets, "default")
require.ElementsMatch(t, results, tc.results)
})
}
diff --git a/internal/gatewayapi/luavalidator/lua_validator.go b/internal/gatewayapi/luavalidator/lua_validator.go
index d3628f51bc..1c103ee175 100644
--- a/internal/gatewayapi/luavalidator/lua_validator.go
+++ b/internal/gatewayapi/luavalidator/lua_validator.go
@@ -30,14 +30,14 @@ var mockData []byte
// Validation strictness is controlled by the validation field
type LuaValidator struct {
code string
- validation egv1a1.LuaValidation
+ envoyProxy *egv1a1.EnvoyProxy
}
// NewLuaValidator returns a LuaValidator for user provided Lua code
-func NewLuaValidator(code string, validation egv1a1.LuaValidation) *LuaValidator {
+func NewLuaValidator(code string, envoyProxy *egv1a1.EnvoyProxy) *LuaValidator {
return &LuaValidator{
code: code,
- validation: validation,
+ envoyProxy: envoyProxy,
}
}
@@ -61,7 +61,7 @@ func (l *LuaValidator) Validate() error {
// validate runs the validation on given code
func (l *LuaValidator) validate(code string) error {
- switch l.validation {
+ switch l.getLuaValidation() {
case egv1a1.LuaValidationSyntax:
return l.loadLua(code)
case egv1a1.LuaValidationDisabled:
@@ -71,10 +71,28 @@ func (l *LuaValidator) validate(code string) error {
}
}
+// getLuaValidation returns the Lua validation level, defaulting to strict if not configured
+func (l *LuaValidator) getLuaValidation() egv1a1.LuaValidation {
+ if l.envoyProxy != nil && l.envoyProxy.Spec.LuaValidation != nil {
+ return *l.envoyProxy.Spec.LuaValidation
+ }
+ return egv1a1.LuaValidationStrict
+}
+
+// newLuaState creates a new Lua state with global settings applied
+func (l *LuaValidator) newLuaState() *lua.LState {
+ L := lua.NewState()
+ // Suppress all print statements
+ L.SetGlobal("print", L.NewFunction(func(L *lua.LState) int {
+ return 0
+ }))
+ return L
+}
+
// runLua interprets and runs the provided Lua code in runtime using gopher-lua
// Refer: https://github.com/yuin/gopher-lua?tab=readme-ov-file#differences-between-lua-and-gopherlua
func (l *LuaValidator) runLua(code string) error {
- L := lua.NewState()
+ L := l.newLuaState()
defer L.Close()
if err := L.DoString(code); err != nil {
return err
@@ -85,7 +103,7 @@ func (l *LuaValidator) runLua(code string) error {
// loadLua loads the Lua code into the Lua state, does not run it
// This is used to check for syntax errors in the Lua code
func (l *LuaValidator) loadLua(code string) error {
- L := lua.NewState()
+ L := l.newLuaState()
defer L.Close()
if _, err := L.LoadString(code); err != nil {
return err
diff --git a/internal/gatewayapi/luavalidator/lua_validator_test.go b/internal/gatewayapi/luavalidator/lua_validator_test.go
index fb5ca5604f..0b57c27420 100644
--- a/internal/gatewayapi/luavalidator/lua_validator_test.go
+++ b/internal/gatewayapi/luavalidator/lua_validator_test.go
@@ -9,6 +9,8 @@ import (
"strings"
"testing"
+ "k8s.io/utils/ptr"
+
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
)
@@ -16,7 +18,7 @@ func Test_Validate(t *testing.T) {
type args struct {
name string
code string
- validation egv1a1.LuaValidation
+ proxy *egv1a1.EnvoyProxy
expectedErrSubstring string
}
tests := []args{
@@ -28,7 +30,7 @@ func Test_Validate(t *testing.T) {
{
name: "logInfo: envoy_on_response",
code: `function envoy_on_response(response_handle)
- response_handle:logInfo("Goodbye.")
+ response_handle:logInfo("This log should not be printed.")
end`,
expectedErrSubstring: "",
},
@@ -156,7 +158,11 @@ func Test_Validate(t *testing.T) {
code: `function envoy_on_request(request_handle)
request_handle:unknownApi()
end`,
- validation: egv1a1.LuaValidationSyntax,
+ proxy: &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ LuaValidation: ptr.To(egv1a1.LuaValidationSyntax),
+ },
+ },
expectedErrSubstring: "",
},
{
@@ -173,7 +179,11 @@ func Test_Validate(t *testing.T) {
last:setBytes("Not Found")
end`,
- validation: egv1a1.LuaValidationSyntax,
+ proxy: &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ LuaValidation: ptr.To(egv1a1.LuaValidationSyntax),
+ },
+ },
expectedErrSubstring: " at EOF: syntax error",
},
{
@@ -190,13 +200,17 @@ func Test_Validate(t *testing.T) {
last:setBytes("Not Found")
end`,
- validation: egv1a1.LuaValidationDisabled,
+ proxy: &egv1a1.EnvoyProxy{
+ Spec: egv1a1.EnvoyProxySpec{
+ LuaValidation: ptr.To(egv1a1.LuaValidationDisabled),
+ },
+ },
expectedErrSubstring: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- l := NewLuaValidator(tt.code, tt.validation)
+ l := NewLuaValidator(tt.code, tt.proxy)
if err := l.Validate(); err != nil && tt.expectedErrSubstring == "" {
t.Errorf("Unexpected error: %v", err)
} else if err != nil && !strings.Contains(err.Error(), tt.expectedErrSubstring) {
diff --git a/internal/gatewayapi/resource/load.go b/internal/gatewayapi/resource/load.go
index 5f14f45d5e..6c327f16ef 100644
--- a/internal/gatewayapi/resource/load.go
+++ b/internal/gatewayapi/resource/load.go
@@ -42,6 +42,13 @@ func LoadResourcesFromYAMLBytes(yamlBytes []byte, addMissingResources bool) (*Re
return nil, err
}
+ // Sort to:
+ // 1. ensure identical resources are not retranslated
+ // and updates are avoided by the watchable layer
+ // 2. ensure gateway-api layer receives resources in order
+ // which impacts translation output
+ r.Sort()
+
return r, nil
}
diff --git a/internal/gatewayapi/resource/load_test.go b/internal/gatewayapi/resource/load_test.go
index 3fe0083661..05d6133edd 100644
--- a/internal/gatewayapi/resource/load_test.go
+++ b/internal/gatewayapi/resource/load_test.go
@@ -62,7 +62,6 @@ func TestLoadAllSupportedResourcesFromYAMLBytes(t *testing.T) {
mustUnmarshal(t, outFile, want)
opts := []cmp.Option{
- cmpopts.IgnoreFields(Resources{}, "serviceMap"),
cmpopts.EquateEmpty(),
}
require.Empty(t, cmp.Diff(want, got, opts...))
diff --git a/internal/gatewayapi/resource/resource.go b/internal/gatewayapi/resource/resource.go
index 6304c8385f..7e08e648ba 100644
--- a/internal/gatewayapi/resource/resource.go
+++ b/internal/gatewayapi/resource/resource.go
@@ -6,15 +6,13 @@
package resource
import (
- "cmp"
- "reflect"
+ "fmt"
+ "sort"
- "golang.org/x/exp/slices"
certificatesv1b1 "k8s.io/api/certificates/v1beta1"
corev1 "k8s.io/api/core/v1"
discoveryv1 "k8s.io/api/discovery/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
- "k8s.io/apimachinery/pkg/types"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
@@ -68,8 +66,6 @@ type Resources struct {
HTTPRouteFilters []*egv1a1.HTTPRouteFilter `json:"httpFilters,omitempty" yaml:"httpFilters,omitempty"`
ClusterTrustBundles []*certificatesv1b1.ClusterTrustBundle `json:"clusterTrustBundles,omitempty" yaml:"clusterTrustBundles,omitempty"`
-
- serviceMap map[types.NamespacedName]*corev1.Service
}
func NewResources() *Resources {
@@ -118,19 +114,13 @@ func (r *Resources) GetEnvoyProxy(namespace, name string) *egv1a1.EnvoyProxy {
}
// GetService returns the Service with the given namespace and name.
-// This function creates a HashMap of Services for faster lookup when it's called for the first time.
-// Subsequent calls will use the HashMap for lookup.
-// Note:
-// - This function is not thread-safe.
-// - This function should be called after all the Services are added to the Resources.
func (r *Resources) GetService(namespace, name string) *corev1.Service {
- if r.serviceMap == nil {
- r.serviceMap = make(map[types.NamespacedName]*corev1.Service)
- for _, svc := range r.Services {
- r.serviceMap[types.NamespacedName{Namespace: svc.Namespace, Name: svc.Name}] = svc
+ for _, svc := range r.Services {
+ if svc.Namespace == namespace && svc.Name == name {
+ return svc
}
}
- return r.serviceMap[types.NamespacedName{Namespace: namespace, Name: name}]
+ return nil
}
// GetServiceByLabels returns the Service matching the given labels and namespace target.
@@ -231,22 +221,278 @@ func (c *ControllerResources) DeepCopy() *ControllerResources {
return nil
}
out := make(ControllerResources, len(*c))
- copy(out, *c)
+ for i, res := range *c {
+ if res != nil {
+ out[i] = res.DeepCopy()
+ }
+ }
return &out
}
-// Equal implements the Comparable interface used by watchable.DeepEqual to skip unnecessary updates.
-func (c *ControllerResources) Equal(y *ControllerResources) bool {
- // Deep copy to avoid modifying the original ordering.
- c = c.DeepCopy()
- c.sort()
- y = y.DeepCopy()
- y.sort()
- return reflect.DeepEqual(c, y)
+func (c ControllerResources) Sort() {
+ // Top level sort based on gatewayClass contents
+ // Sort gatewayClass based on timestamp.
+ // Initially, sort by creation timestamp
+ // or sort alphabetically by “{namespace}/{name}” if multiple gatewayclasses share same timestamp.
+ sort.Slice(c, func(i, j int) bool {
+ if c[i].GatewayClass.CreationTimestamp.Equal(&(c[j].GatewayClass.CreationTimestamp)) {
+ return c[i].GatewayClass.Name < c[j].GatewayClass.Name
+ }
+ // Not identical CreationTimestamps
+ return c[i].GatewayClass.CreationTimestamp.Before(&(c[j].GatewayClass.CreationTimestamp))
+ })
+
+ // Then, run Sort for each item
+ for idx := range c {
+ c[idx].Sort()
+ }
}
-func (c *ControllerResources) sort() {
- slices.SortFunc(*c, func(c1, c2 *Resources) int {
- return cmp.Compare(c1.GatewayClass.Name, c2.GatewayClass.Name)
+func (r *Resources) Sort() {
+ // Sort gateways based on timestamp.
+ // Initially, gateways sort by creation timestamp
+ // or sort alphabetically by “{namespace}/{name}” if multiple gateways share same timestamp.
+ sort.Slice(r.Gateways, func(i, j int) bool {
+ if r.Gateways[i].CreationTimestamp.Equal(&(r.Gateways[j].CreationTimestamp)) {
+ gatewayKeyI := fmt.Sprintf("%s/%s", r.Gateways[i].Namespace, r.Gateways[i].Name)
+ gatewayKeyJ := fmt.Sprintf("%s/%s", r.Gateways[j].Namespace, r.Gateways[j].Name)
+ return gatewayKeyI < gatewayKeyJ
+ }
+ // Not identical CreationTimestamps
+
+ return r.Gateways[i].CreationTimestamp.Before(&(r.Gateways[j].CreationTimestamp))
+ })
+
+ // Sort HTTPRoutes by creation timestamp, then namespace/name
+ sort.Slice(r.HTTPRoutes, func(i, j int) bool {
+ if r.HTTPRoutes[i].CreationTimestamp.Equal(&(r.HTTPRoutes[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.HTTPRoutes[i].Namespace, r.HTTPRoutes[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.HTTPRoutes[j].Namespace, r.HTTPRoutes[j].Name)
+ return keyI < keyJ
+ }
+ return r.HTTPRoutes[i].CreationTimestamp.Before(&(r.HTTPRoutes[j].CreationTimestamp))
+ })
+
+ // Sort GRPCRoutes by creation timestamp, then namespace/name
+ sort.Slice(r.GRPCRoutes, func(i, j int) bool {
+ if r.GRPCRoutes[i].CreationTimestamp.Equal(&(r.GRPCRoutes[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.GRPCRoutes[i].Namespace, r.GRPCRoutes[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.GRPCRoutes[j].Namespace, r.GRPCRoutes[j].Name)
+ return keyI < keyJ
+ }
+ return r.GRPCRoutes[i].CreationTimestamp.Before(&(r.GRPCRoutes[j].CreationTimestamp))
+ })
+
+ // Sort TLSRoutes by creation timestamp, then namespace/name
+ sort.Slice(r.TLSRoutes, func(i, j int) bool {
+ if r.TLSRoutes[i].CreationTimestamp.Equal(&(r.TLSRoutes[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.TLSRoutes[i].Namespace, r.TLSRoutes[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.TLSRoutes[j].Namespace, r.TLSRoutes[j].Name)
+ return keyI < keyJ
+ }
+ return r.TLSRoutes[i].CreationTimestamp.Before(&(r.TLSRoutes[j].CreationTimestamp))
+ })
+
+ // Sort TCPRoutes by creation timestamp, then namespace/name
+ sort.Slice(r.TCPRoutes, func(i, j int) bool {
+ if r.TCPRoutes[i].CreationTimestamp.Equal(&(r.TCPRoutes[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.TCPRoutes[i].Namespace, r.TCPRoutes[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.TCPRoutes[j].Namespace, r.TCPRoutes[j].Name)
+ return keyI < keyJ
+ }
+ return r.TCPRoutes[i].CreationTimestamp.Before(&(r.TCPRoutes[j].CreationTimestamp))
+ })
+
+ // Sort UDPRoutes by creation timestamp, then namespace/name
+ sort.Slice(r.UDPRoutes, func(i, j int) bool {
+ if r.UDPRoutes[i].CreationTimestamp.Equal(&(r.UDPRoutes[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.UDPRoutes[i].Namespace, r.UDPRoutes[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.UDPRoutes[j].Namespace, r.UDPRoutes[j].Name)
+ return keyI < keyJ
+ }
+ return r.UDPRoutes[i].CreationTimestamp.Before(&(r.UDPRoutes[j].CreationTimestamp))
+ })
+
+ // Sort ReferenceGrants by creation timestamp, then namespace/name
+ sort.Slice(r.ReferenceGrants, func(i, j int) bool {
+ if r.ReferenceGrants[i].CreationTimestamp.Equal(&(r.ReferenceGrants[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.ReferenceGrants[i].Namespace, r.ReferenceGrants[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.ReferenceGrants[j].Namespace, r.ReferenceGrants[j].Name)
+ return keyI < keyJ
+ }
+ return r.ReferenceGrants[i].CreationTimestamp.Before(&(r.ReferenceGrants[j].CreationTimestamp))
+ })
+
+ // Sort Namespaces by creation timestamp, then name
+ sort.Slice(r.Namespaces, func(i, j int) bool {
+ if r.Namespaces[i].CreationTimestamp.Equal(&(r.Namespaces[j].CreationTimestamp)) {
+ return r.Namespaces[i].Name < r.Namespaces[j].Name
+ }
+ return r.Namespaces[i].CreationTimestamp.Before(&(r.Namespaces[j].CreationTimestamp))
+ })
+
+ // Sort Services by creation timestamp, then namespace/name
+ sort.Slice(r.Services, func(i, j int) bool {
+ if r.Services[i].CreationTimestamp.Equal(&(r.Services[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.Services[i].Namespace, r.Services[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.Services[j].Namespace, r.Services[j].Name)
+ return keyI < keyJ
+ }
+ return r.Services[i].CreationTimestamp.Before(&(r.Services[j].CreationTimestamp))
+ })
+
+ // Sort ServiceImports by creation timestamp, then namespace/name
+ sort.Slice(r.ServiceImports, func(i, j int) bool {
+ if r.ServiceImports[i].CreationTimestamp.Equal(&(r.ServiceImports[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.ServiceImports[i].Namespace, r.ServiceImports[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.ServiceImports[j].Namespace, r.ServiceImports[j].Name)
+ return keyI < keyJ
+ }
+ return r.ServiceImports[i].CreationTimestamp.Before(&(r.ServiceImports[j].CreationTimestamp))
+ })
+
+ // Sort EndpointSlices by creation timestamp, then namespace/name
+ sort.Slice(r.EndpointSlices, func(i, j int) bool {
+ if r.EndpointSlices[i].CreationTimestamp.Equal(&(r.EndpointSlices[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.EndpointSlices[i].Namespace, r.EndpointSlices[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.EndpointSlices[j].Namespace, r.EndpointSlices[j].Name)
+ return keyI < keyJ
+ }
+ return r.EndpointSlices[i].CreationTimestamp.Before(&(r.EndpointSlices[j].CreationTimestamp))
+ })
+
+ // Sort Secrets by creation timestamp, then namespace/name
+ sort.Slice(r.Secrets, func(i, j int) bool {
+ if r.Secrets[i].CreationTimestamp.Equal(&(r.Secrets[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.Secrets[i].Namespace, r.Secrets[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.Secrets[j].Namespace, r.Secrets[j].Name)
+ return keyI < keyJ
+ }
+ return r.Secrets[i].CreationTimestamp.Before(&(r.Secrets[j].CreationTimestamp))
+ })
+
+ // Sort ConfigMaps by creation timestamp, then namespace/name
+ sort.Slice(r.ConfigMaps, func(i, j int) bool {
+ if r.ConfigMaps[i].CreationTimestamp.Equal(&(r.ConfigMaps[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.ConfigMaps[i].Namespace, r.ConfigMaps[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.ConfigMaps[j].Namespace, r.ConfigMaps[j].Name)
+ return keyI < keyJ
+ }
+ return r.ConfigMaps[i].CreationTimestamp.Before(&(r.ConfigMaps[j].CreationTimestamp))
+ })
+
+ // Sort EnvoyPatchPolicies by priority first, then creation timestamp, then namespace/name
+ sort.Slice(r.EnvoyPatchPolicies, func(i, j int) bool {
+ if r.EnvoyPatchPolicies[i].Spec.Priority == r.EnvoyPatchPolicies[j].Spec.Priority {
+ if r.EnvoyPatchPolicies[i].CreationTimestamp.Equal(&(r.EnvoyPatchPolicies[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.EnvoyPatchPolicies[i].Namespace, r.EnvoyPatchPolicies[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.EnvoyPatchPolicies[j].Namespace, r.EnvoyPatchPolicies[j].Name)
+ return keyI < keyJ
+ }
+ return r.EnvoyPatchPolicies[i].CreationTimestamp.Before(&(r.EnvoyPatchPolicies[j].CreationTimestamp))
+ }
+ return r.EnvoyPatchPolicies[i].Spec.Priority < r.EnvoyPatchPolicies[j].Spec.Priority
+ })
+
+ // Sort ClientTrafficPolicies by creation timestamp, then namespace/name
+ sort.Slice(r.ClientTrafficPolicies, func(i, j int) bool {
+ if r.ClientTrafficPolicies[i].CreationTimestamp.Equal(&(r.ClientTrafficPolicies[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.ClientTrafficPolicies[i].Namespace, r.ClientTrafficPolicies[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.ClientTrafficPolicies[j].Namespace, r.ClientTrafficPolicies[j].Name)
+ return keyI < keyJ
+ }
+ return r.ClientTrafficPolicies[i].CreationTimestamp.Before(&(r.ClientTrafficPolicies[j].CreationTimestamp))
+ })
+
+ // Sort BackendTrafficPolicies by creation timestamp, then namespace/name
+ sort.Slice(r.BackendTrafficPolicies, func(i, j int) bool {
+ if r.BackendTrafficPolicies[i].CreationTimestamp.Equal(&(r.BackendTrafficPolicies[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.BackendTrafficPolicies[i].Namespace, r.BackendTrafficPolicies[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.BackendTrafficPolicies[j].Namespace, r.BackendTrafficPolicies[j].Name)
+ return keyI < keyJ
+ }
+ return r.BackendTrafficPolicies[i].CreationTimestamp.Before(&(r.BackendTrafficPolicies[j].CreationTimestamp))
+ })
+
+ // Sort SecurityPolicies by creation timestamp, then namespace/name
+ sort.Slice(r.SecurityPolicies, func(i, j int) bool {
+ if r.SecurityPolicies[i].CreationTimestamp.Equal(&(r.SecurityPolicies[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.SecurityPolicies[i].Namespace, r.SecurityPolicies[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.SecurityPolicies[j].Namespace, r.SecurityPolicies[j].Name)
+ return keyI < keyJ
+ }
+ return r.SecurityPolicies[i].CreationTimestamp.Before(&(r.SecurityPolicies[j].CreationTimestamp))
+ })
+
+ // Sort BackendTLSPolicies by creation timestamp, then namespace/name
+ sort.Slice(r.BackendTLSPolicies, func(i, j int) bool {
+ if r.BackendTLSPolicies[i].CreationTimestamp.Equal(&(r.BackendTLSPolicies[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.BackendTLSPolicies[i].Namespace, r.BackendTLSPolicies[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.BackendTLSPolicies[j].Namespace, r.BackendTLSPolicies[j].Name)
+ return keyI < keyJ
+ }
+ return r.BackendTLSPolicies[i].CreationTimestamp.Before(&(r.BackendTLSPolicies[j].CreationTimestamp))
+ })
+
+ // Sort EnvoyExtensionPolicies by creation timestamp, then namespace/name
+ sort.Slice(r.EnvoyExtensionPolicies, func(i, j int) bool {
+ if r.EnvoyExtensionPolicies[i].CreationTimestamp.Equal(&(r.EnvoyExtensionPolicies[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.EnvoyExtensionPolicies[i].Namespace, r.EnvoyExtensionPolicies[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.EnvoyExtensionPolicies[j].Namespace, r.EnvoyExtensionPolicies[j].Name)
+ return keyI < keyJ
+ }
+ return r.EnvoyExtensionPolicies[i].CreationTimestamp.Before(&(r.EnvoyExtensionPolicies[j].CreationTimestamp))
+ })
+
+ // Sort Backends by creation timestamp, then namespace/name
+ sort.Slice(r.Backends, func(i, j int) bool {
+ if r.Backends[i].CreationTimestamp.Equal(&(r.Backends[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.Backends[i].Namespace, r.Backends[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.Backends[j].Namespace, r.Backends[j].Name)
+ return keyI < keyJ
+ }
+ return r.Backends[i].CreationTimestamp.Before(&(r.Backends[j].CreationTimestamp))
+ })
+
+ // Sort HTTPRouteFilters by creation timestamp, then namespace/name
+ sort.Slice(r.HTTPRouteFilters, func(i, j int) bool {
+ if r.HTTPRouteFilters[i].CreationTimestamp.Equal(&(r.HTTPRouteFilters[j].CreationTimestamp)) {
+ keyI := fmt.Sprintf("%s/%s", r.HTTPRouteFilters[i].Namespace, r.HTTPRouteFilters[i].Name)
+ keyJ := fmt.Sprintf("%s/%s", r.HTTPRouteFilters[j].Namespace, r.HTTPRouteFilters[j].Name)
+ return keyI < keyJ
+ }
+ return r.HTTPRouteFilters[i].CreationTimestamp.Before(&(r.HTTPRouteFilters[j].CreationTimestamp))
+ })
+
+ // Sort ClusterTrustBundles by creation timestamp, then name (cluster-scoped)
+ sort.Slice(r.ClusterTrustBundles, func(i, j int) bool {
+ if r.ClusterTrustBundles[i].CreationTimestamp.Equal(&(r.ClusterTrustBundles[j].CreationTimestamp)) {
+ return r.ClusterTrustBundles[i].Name < r.ClusterTrustBundles[j].Name
+ }
+ return r.ClusterTrustBundles[i].CreationTimestamp.Before(&(r.ClusterTrustBundles[j].CreationTimestamp))
+ })
+
+ // Sort ExtensionRefFilters by creation timestamp, then namespace/name (unstructured resources)
+ sort.Slice(r.ExtensionRefFilters, func(i, j int) bool {
+ tsI := r.ExtensionRefFilters[i].GetCreationTimestamp()
+ tsJ := r.ExtensionRefFilters[j].GetCreationTimestamp()
+ if tsI.Equal(&tsJ) {
+ keyI := fmt.Sprintf("%s/%s", r.ExtensionRefFilters[i].GetNamespace(), r.ExtensionRefFilters[i].GetName())
+ keyJ := fmt.Sprintf("%s/%s", r.ExtensionRefFilters[j].GetNamespace(), r.ExtensionRefFilters[j].GetName())
+ return keyI < keyJ
+ }
+ return tsI.Before(&tsJ)
+ })
+
+ // Sort ExtensionServerPolicies by creation timestamp, then namespace/name (unstructured resources)
+ sort.Slice(r.ExtensionServerPolicies, func(i, j int) bool {
+ tsI := r.ExtensionServerPolicies[i].GetCreationTimestamp()
+ tsJ := r.ExtensionServerPolicies[j].GetCreationTimestamp()
+ if tsI.Equal(&tsJ) {
+ keyI := fmt.Sprintf("%s/%s", r.ExtensionServerPolicies[i].GetNamespace(), r.ExtensionServerPolicies[i].GetName())
+ keyJ := fmt.Sprintf("%s/%s", r.ExtensionServerPolicies[j].GetNamespace(), r.ExtensionServerPolicies[j].GetName())
+ return keyI < keyJ
+ }
+ return tsI.Before(&tsJ)
})
}
diff --git a/internal/gatewayapi/resource/resource_test.go b/internal/gatewayapi/resource/resource_test.go
index f5758b4319..1db2e0f607 100644
--- a/internal/gatewayapi/resource/resource_test.go
+++ b/internal/gatewayapi/resource/resource_test.go
@@ -121,7 +121,11 @@ func TestEqualXds(t *testing.T) {
for _, tc := range tests {
t.Run(tc.desc, func(t *testing.T) {
- require.Equal(t, tc.equal, cmp.Equal(tc.a, tc.b))
+ tc.a.Sort()
+ tc.b.Sort()
+ diff := cmp.Diff(tc.a, tc.b)
+ got := diff == ""
+ require.Equal(t, tc.equal, got)
})
}
}
diff --git a/internal/gatewayapi/resource/testdata/all-resources.out.yaml b/internal/gatewayapi/resource/testdata/all-resources.out.yaml
index f6acba05db..b629510405 100644
--- a/internal/gatewayapi/resource/testdata/all-resources.out.yaml
+++ b/internal/gatewayapi/resource/testdata/all-resources.out.yaml
@@ -45,7 +45,7 @@ backendTrafficPolicies:
attributes:
SameSite: Strict
name: Lb-Test-Cookie
- ttl: 1m0s
+ ttl: 60s
tableSize: 65537
type: Cookie
type: ConsistentHash
@@ -286,14 +286,14 @@ namespaces:
kind: Namespace
metadata:
creationTimestamp: null
- name: envoy-gateway-system
+ name: default
spec: {}
status: {}
- apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: null
- name: default
+ name: envoy-gateway-system
spec: {}
status: {}
- apiVersion: v1
@@ -334,18 +334,18 @@ secrets:
kind: Secret
metadata:
creationTimestamp: null
- name: secret-with-data-and-string-data
+ name: secret-with-data
namespace: default
- stringData:
- secret: literal value
- apiVersion: v1
data:
.secret-file: dmFsdWUtMg0KDQo=
kind: Secret
metadata:
creationTimestamp: null
- name: secret-with-data
+ name: secret-with-data-and-string-data
namespace: default
+ stringData:
+ secret: literal value
- apiVersion: v1
kind: Secret
metadata:
diff --git a/internal/gatewayapi/resource/zz_generated.deepcopy.go b/internal/gatewayapi/resource/zz_generated.deepcopy.go
index 7bc2f9f960..23d6033ca8 100644
--- a/internal/gatewayapi/resource/zz_generated.deepcopy.go
+++ b/internal/gatewayapi/resource/zz_generated.deepcopy.go
@@ -15,7 +15,6 @@ import (
corev1 "k8s.io/api/core/v1"
discoveryv1 "k8s.io/api/discovery/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
- "k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/gateway-api/apis/v1"
"sigs.k8s.io/gateway-api/apis/v1alpha2"
"sigs.k8s.io/gateway-api/apis/v1alpha3"
@@ -303,22 +302,6 @@ func (in *Resources) DeepCopyInto(out *Resources) {
}
}
}
- if in.serviceMap != nil {
- in, out := &in.serviceMap, &out.serviceMap
- *out = make(map[types.NamespacedName]*corev1.Service, len(*in))
- for key, val := range *in {
- var outVal *corev1.Service
- if val == nil {
- (*out)[key] = nil
- } else {
- inVal := (*in)[key]
- in, out := &inVal, &outVal
- *out = new(corev1.Service)
- (*in).DeepCopyInto(*out)
- }
- (*out)[key] = outVal
- }
- }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Resources.
diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go
index a60564028e..7a1acc8703 100644
--- a/internal/gatewayapi/route.go
+++ b/internal/gatewayapi/route.go
@@ -8,7 +8,6 @@ package gatewayapi
import (
"fmt"
"net"
- "sort"
"strconv"
"strings"
"time"
@@ -55,28 +54,13 @@ type RoutesTranslator interface {
func (t *Translator) ProcessHTTPRoutes(httpRoutes []*gwapiv1.HTTPRoute, gateways []*GatewayContext, resources *resource.Resources, xdsIR resource.XdsIRMap) []*HTTPRouteContext {
var relevantHTTPRoutes []*HTTPRouteContext
- // Initially, httpRoutes sort by creation timestamp
- // or sort alphabetically by “{namespace}/{name}” if multiple routes share same timestamp.
- // Later on, additional sorting based on matcher type and match length may occur.
- sort.Slice(httpRoutes, func(i, j int) bool {
- if httpRoutes[i].CreationTimestamp.Equal(&(httpRoutes[j].CreationTimestamp)) {
- routeKeyI := fmt.Sprintf("%s/%s", httpRoutes[i].Namespace, httpRoutes[i].Name)
- routeKeyJ := fmt.Sprintf("%s/%s", httpRoutes[j].Namespace, httpRoutes[j].Name)
- return routeKeyI < routeKeyJ
- }
- // Not identical CreationTimestamps
-
- return httpRoutes[i].CreationTimestamp.Before(&(httpRoutes[j].CreationTimestamp))
- })
+ // HTTPRoutes are already sorted by the provider layer
for _, h := range httpRoutes {
if h == nil {
panic("received nil httproute")
}
- httpRoute := &HTTPRouteContext{
- GatewayControllerName: t.GatewayControllerName,
- HTTPRoute: h.DeepCopy(),
- }
+ httpRoute := &HTTPRouteContext{HTTPRoute: h}
// Find out if this route attaches to one of our Gateway's listeners,
// and if so, get the list of listeners that allow it to attach for each
@@ -97,28 +81,13 @@ func (t *Translator) ProcessHTTPRoutes(httpRoutes []*gwapiv1.HTTPRoute, gateways
func (t *Translator) ProcessGRPCRoutes(grpcRoutes []*gwapiv1.GRPCRoute, gateways []*GatewayContext, resources *resource.Resources, xdsIR resource.XdsIRMap) []*GRPCRouteContext {
var relevantGRPCRoutes []*GRPCRouteContext
- // Initially, grpcRoutes sort by creation timestamp
- // or sort alphabetically by “{namespace}/{name}” if multiple routes share same timestamp.
- // Later on, additional sorting based on matcher type and match length may occur.
- sort.Slice(grpcRoutes, func(i, j int) bool {
- if grpcRoutes[i].CreationTimestamp.Equal(&(grpcRoutes[j].CreationTimestamp)) {
- routeKeyI := fmt.Sprintf("%s/%s", grpcRoutes[i].Namespace, grpcRoutes[i].Name)
- routeKeyJ := fmt.Sprintf("%s/%s", grpcRoutes[j].Namespace, grpcRoutes[j].Name)
- return routeKeyI < routeKeyJ
- }
- // Not identical CreationTimestamps
-
- return grpcRoutes[i].CreationTimestamp.Before(&(grpcRoutes[j].CreationTimestamp))
- })
+ // GRPCRoutes are already sorted by the provider layer
for _, g := range grpcRoutes {
if g == nil {
panic("received nil grpcroute")
}
- grpcRoute := &GRPCRouteContext{
- GatewayControllerName: t.GatewayControllerName,
- GRPCRoute: g.DeepCopy(),
- }
+ grpcRoute := &GRPCRouteContext{GRPCRoute: g}
// Find out if this route attaches to one of our Gateway's listeners,
// and if so, get the list of listeners that allow it to attach for each
@@ -350,7 +319,7 @@ func processRouteTimeout(irRoute *ir.HTTPRoute, rule gwapiv1.HTTPRouteRule) {
if err != nil {
d, _ = time.ParseDuration(HTTPRequestTimeout)
}
- irRoute.Timeout = ptr.To(metav1.Duration{Duration: d})
+ irRoute.Timeout = ir.MetaV1DurationPtr(d)
}
// Only set the IR Route Timeout to the backend request timeout
@@ -361,7 +330,7 @@ func processRouteTimeout(irRoute *ir.HTTPRoute, rule gwapiv1.HTTPRouteRule) {
if err != nil {
d, _ = time.ParseDuration(HTTPRequestTimeout)
}
- irRoute.Timeout = ptr.To(metav1.Duration{Duration: d})
+ irRoute.Timeout = ir.MetaV1DurationPtr(d)
}
}
}
@@ -381,14 +350,14 @@ func processRouteRetry(irRoute *ir.HTTPRoute, rule gwapiv1.HTTPRouteRule) {
if err == nil {
res.PerRetry = &ir.PerRetryPolicy{
BackOff: &ir.BackOffPolicy{
- BaseInterval: ptr.To(metav1.Duration{Duration: backoff}),
+ BaseInterval: ir.MetaV1DurationPtr(backoff),
},
}
// xref: https://gateway-api.sigs.k8s.io/geps/gep-1742/#timeout-values
if rule.Timeouts != nil && rule.Timeouts.BackendRequest != nil {
backendRequestTimeout, err := time.ParseDuration(string(*rule.Timeouts.BackendRequest))
if err == nil {
- res.PerRetry.Timeout = &metav1.Duration{Duration: backendRequestTimeout}
+ res.PerRetry.Timeout = ir.MetaV1DurationPtr(backendRequestTimeout)
}
}
}
@@ -460,7 +429,7 @@ func (t *Translator) processHTTPRouteRule(
if err != nil {
return nil, status.NewRouteStatusError(err, gwapiv1.RouteReasonUnsupportedValue)
}
- sessionPersistence.Cookie.TTL = &metav1.Duration{Duration: ttl}
+ sessionPersistence.Cookie.TTL = ir.MetaV1DurationPtr(ttl)
}
case *rule.SessionPersistence.Type == gwapiv1.HeaderBasedSessionPersistence:
sessionPersistence = &ir.SessionPersistence{
@@ -941,28 +910,13 @@ func filterEGPrefix(in map[string]string) map[string]string {
func (t *Translator) ProcessTLSRoutes(tlsRoutes []*gwapiv1a2.TLSRoute, gateways []*GatewayContext, resources *resource.Resources, xdsIR resource.XdsIRMap) []*TLSRouteContext {
var relevantTLSRoutes []*TLSRouteContext
-
- // Initially, tlsRoutes sort by creation timestamp
- // or sort alphabetically by “{namespace}/{name}” if multiple routes share same timestamp.
- sort.Slice(tlsRoutes, func(i, j int) bool {
- if tlsRoutes[i].CreationTimestamp.Equal(&(tlsRoutes[j].CreationTimestamp)) {
- routeKeyI := fmt.Sprintf("%s/%s", tlsRoutes[i].Namespace, tlsRoutes[i].Name)
- routeKeyJ := fmt.Sprintf("%s/%s", tlsRoutes[j].Namespace, tlsRoutes[j].Name)
- return routeKeyI < routeKeyJ
- }
- // Not identical CreationTimestamps
-
- return tlsRoutes[i].CreationTimestamp.Before(&(tlsRoutes[j].CreationTimestamp))
- })
+ // TLSRoutes are already sorted by the provider layer
for _, tls := range tlsRoutes {
if tls == nil {
panic("received nil tlsroute")
}
- tlsRoute := &TLSRouteContext{
- GatewayControllerName: t.GatewayControllerName,
- TLSRoute: tls.DeepCopy(),
- }
+ tlsRoute := &TLSRouteContext{TLSRoute: tls}
// Find out if this route attaches to one of our Gateway's listeners,
// and if so, get the list of listeners that allow it to attach for each
@@ -1100,28 +1054,13 @@ func (t *Translator) ProcessUDPRoutes(udpRoutes []*gwapiv1a2.UDPRoute, gateways
xdsIR resource.XdsIRMap,
) []*UDPRouteContext {
var relevantUDPRoutes []*UDPRouteContext
-
- // Initially, udpRoutes sort by creation timestamp
- // or sort alphabetically by “{namespace}/{name}” if multiple routes share same timestamp.
- sort.Slice(udpRoutes, func(i, j int) bool {
- if udpRoutes[i].CreationTimestamp.Equal(&(udpRoutes[j].CreationTimestamp)) {
- routeKeyI := fmt.Sprintf("%s/%s", udpRoutes[i].Namespace, udpRoutes[i].Name)
- routeKeyJ := fmt.Sprintf("%s/%s", udpRoutes[j].Namespace, udpRoutes[j].Name)
- return routeKeyI < routeKeyJ
- }
- // Not identical CreationTimestamps
-
- return udpRoutes[i].CreationTimestamp.Before(&(udpRoutes[j].CreationTimestamp))
- })
+ // UDPRoutes are already sorted by the provider layer
for _, u := range udpRoutes {
if u == nil {
panic("received nil udproute")
}
- udpRoute := &UDPRouteContext{
- GatewayControllerName: t.GatewayControllerName,
- UDPRoute: u.DeepCopy(),
- }
+ udpRoute := &UDPRouteContext{UDPRoute: u}
// Find out if this route attaches to one of our Gateway's listeners,
// and if so, get the list of listeners that allow it to attach for each
@@ -1263,28 +1202,13 @@ func (t *Translator) ProcessTCPRoutes(tcpRoutes []*gwapiv1a2.TCPRoute, gateways
xdsIR resource.XdsIRMap,
) []*TCPRouteContext {
var relevantTCPRoutes []*TCPRouteContext
-
- // Initially, tcpRoutes sort by creation timestamp
- // or sort alphabetically by “{namespace}/{name}” if multiple routes share same timestamp.
- sort.Slice(tcpRoutes, func(i, j int) bool {
- if tcpRoutes[i].CreationTimestamp.Equal(&(tcpRoutes[j].CreationTimestamp)) {
- routeKeyI := fmt.Sprintf("%s/%s", tcpRoutes[i].Namespace, tcpRoutes[i].Name)
- routeKeyJ := fmt.Sprintf("%s/%s", tcpRoutes[j].Namespace, tcpRoutes[j].Name)
- return routeKeyI < routeKeyJ
- }
- // Not identical CreationTimestamps
-
- return tcpRoutes[i].CreationTimestamp.Before(&(tcpRoutes[j].CreationTimestamp))
- })
+ // TCPRoutes are already sorted by the provider layer
for _, tcp := range tcpRoutes {
if tcp == nil {
panic("received nil tcproute")
}
- tcpRoute := &TCPRouteContext{
- GatewayControllerName: t.GatewayControllerName,
- TCPRoute: tcp.DeepCopy(),
- }
+ tcpRoute := &TCPRouteContext{TCPRoute: tcp}
// Find out if this route attaches to one of our Gateway's listeners,
// and if so, get the list of listeners that allow it to attach for each
@@ -1488,6 +1412,18 @@ func (t *Translator) processDestination(name string, backendRefContext BackendRe
if t.isCustomBackendResource(backendRef.Group, KindDerefOr(backendRef.Kind, resource.KindService)) {
// Add the custom backend resource to ExtensionRefFilters so it can be processed by the extension system
unstructuredRef = t.processBackendExtensions(backendRef.BackendObjectReference, backendNamespace, resources)
+
+ // Check if the custom backend resource was found
+ if unstructuredRef == nil {
+ return nil, nil, status.NewRouteStatusError(
+ fmt.Errorf("custom backend %s %s/%s not found",
+ KindDerefOr(backendRef.Kind, resource.KindService),
+ backendNamespace,
+ backendRef.Name),
+ gwapiv1.RouteReasonBackendNotFound,
+ ).WithType(gwapiv1.RouteConditionResolvedRefs)
+ }
+
return &ir.DestinationSetting{
Name: name,
Weight: &weight,
@@ -2132,7 +2068,7 @@ func getStatPattern(routeContext RouteContext, parentRef *RouteParentContext) st
func buildStatName(pattern string, route RouteContext, ruleName *gwapiv1.SectionName, idx int, refs []string) string {
statName := strings.ReplaceAll(pattern, egv1a1.StatFormatterRouteName, route.GetName())
statName = strings.ReplaceAll(statName, egv1a1.StatFormatterRouteNamespace, route.GetNamespace())
- statName = strings.ReplaceAll(statName, egv1a1.StatFormatterRouteKind, route.GetObjectKind().GroupVersionKind().Kind)
+ statName = strings.ReplaceAll(statName, egv1a1.StatFormatterRouteKind, strings.ToLower(route.GetObjectKind().GroupVersionKind().Kind))
if ruleName == nil {
statName = strings.ReplaceAll(statName, egv1a1.StatFormatterRouteRuleName, "-")
} else {
diff --git a/internal/gatewayapi/runner/runner.go b/internal/gatewayapi/runner/runner.go
index 2eccf8832d..37e7519a6a 100644
--- a/internal/gatewayapi/runner/runner.go
+++ b/internal/gatewayapi/runner/runner.go
@@ -194,11 +194,11 @@ func (r *Runner) subscribeAndTranslate(sub <-chan watchable.Snapshot[string, *re
r.Logger.Error(err, "unable to validate infra ir, skipped sending it")
errChan <- err
} else {
- message.HandleStore(message.Metadata{
+ r.InfraIR.Store(key, val)
+ message.PublishMetric(message.Metadata{
Runner: r.Name(),
Message: message.InfraIRMessageName,
- },
- key, val, &r.InfraIR.Map)
+ })
newIRKeys = append(newIRKeys, key)
}
}
@@ -209,67 +209,67 @@ func (r *Runner) subscribeAndTranslate(sub <-chan watchable.Snapshot[string, *re
r.Logger.Error(err, "unable to validate xds ir, skipped sending it")
errChan <- err
} else {
- message.HandleStore(message.Metadata{
+ r.XdsIR.Store(key, val)
+ message.PublishMetric(message.Metadata{
Runner: r.Name(),
Message: message.XDSIRMessageName,
- },
- key, val, &r.XdsIR.Map)
+ })
}
}
// Update Status
for _, gateway := range result.Gateways {
key := utils.NamespacedName(gateway)
- message.HandleStore(message.Metadata{
+ r.ProviderResources.GatewayStatuses.Store(key, &gateway.Status)
+ message.PublishMetric(message.Metadata{
Runner: r.Name(),
Message: message.GatewayStatusMessageName,
- },
- key, &gateway.Status, &r.ProviderResources.GatewayStatuses)
+ })
delete(statusesToDelete.GatewayStatusKeys, key)
}
for _, httpRoute := range result.HTTPRoutes {
key := utils.NamespacedName(httpRoute)
- message.HandleStore(message.Metadata{
+ r.ProviderResources.HTTPRouteStatuses.Store(key, &httpRoute.Status)
+ message.PublishMetric(message.Metadata{
Runner: r.Name(),
Message: message.HTTPRouteStatusMessageName,
- },
- key, &httpRoute.Status, &r.ProviderResources.HTTPRouteStatuses)
+ })
delete(statusesToDelete.HTTPRouteStatusKeys, key)
}
for _, grpcRoute := range result.GRPCRoutes {
key := utils.NamespacedName(grpcRoute)
- message.HandleStore(message.Metadata{
+ r.ProviderResources.GRPCRouteStatuses.Store(key, &grpcRoute.Status)
+ message.PublishMetric(message.Metadata{
Runner: r.Name(),
Message: message.GRPCRouteStatusMessageName,
- },
- key, &grpcRoute.Status, &r.ProviderResources.GRPCRouteStatuses)
+ })
delete(statusesToDelete.GRPCRouteStatusKeys, key)
}
for _, tlsRoute := range result.TLSRoutes {
key := utils.NamespacedName(tlsRoute)
- message.HandleStore(message.Metadata{
+ r.ProviderResources.TLSRouteStatuses.Store(key, &tlsRoute.Status)
+ message.PublishMetric(message.Metadata{
Runner: r.Name(),
Message: message.TLSRouteStatusMessageName,
- },
- key, &tlsRoute.Status, &r.ProviderResources.TLSRouteStatuses)
+ })
delete(statusesToDelete.TLSRouteStatusKeys, key)
}
for _, tcpRoute := range result.TCPRoutes {
key := utils.NamespacedName(tcpRoute)
- message.HandleStore(message.Metadata{
+ r.ProviderResources.TCPRouteStatuses.Store(key, &tcpRoute.Status)
+ message.PublishMetric(message.Metadata{
Runner: r.Name(),
Message: message.TCPRouteStatusMessageName,
- },
- key, &tcpRoute.Status, &r.ProviderResources.TCPRouteStatuses)
+ })
delete(statusesToDelete.TCPRouteStatusKeys, key)
}
for _, udpRoute := range result.UDPRoutes {
key := utils.NamespacedName(udpRoute)
- message.HandleStore(message.Metadata{
+ r.ProviderResources.UDPRouteStatuses.Store(key, &udpRoute.Status)
+ message.PublishMetric(message.Metadata{
Runner: r.Name(),
Message: message.UDPRouteStatusMessageName,
- },
- key, &udpRoute.Status, &r.ProviderResources.UDPRouteStatuses)
+ })
delete(statusesToDelete.UDPRouteStatusKeys, key)
}
@@ -280,11 +280,11 @@ func (r *Runner) subscribeAndTranslate(sub <-chan watchable.Snapshot[string, *re
for _, backendTLSPolicy := range result.BackendTLSPolicies {
key := utils.NamespacedName(backendTLSPolicy)
if !(reflect.ValueOf(backendTLSPolicy.Status).IsZero()) {
- message.HandleStore(message.Metadata{
+ r.ProviderResources.BackendTLSPolicyStatuses.Store(key, &backendTLSPolicy.Status)
+ message.PublishMetric(message.Metadata{
Runner: r.Name(),
Message: message.BackendTLSPolicyStatusMessageName,
- },
- key, &backendTLSPolicy.Status, &r.ProviderResources.BackendTLSPolicyStatuses)
+ })
}
delete(statusesToDelete.BackendTLSPolicyStatusKeys, key)
}
@@ -292,55 +292,55 @@ func (r *Runner) subscribeAndTranslate(sub <-chan watchable.Snapshot[string, *re
for _, clientTrafficPolicy := range result.ClientTrafficPolicies {
key := utils.NamespacedName(clientTrafficPolicy)
if !(reflect.ValueOf(clientTrafficPolicy.Status).IsZero()) {
- message.HandleStore(message.Metadata{
+ r.ProviderResources.ClientTrafficPolicyStatuses.Store(key, &clientTrafficPolicy.Status)
+ message.PublishMetric(message.Metadata{
Runner: r.Name(),
Message: message.ClientTrafficPolicyStatusMessageName,
- },
- key, &clientTrafficPolicy.Status, &r.ProviderResources.ClientTrafficPolicyStatuses)
+ })
}
delete(statusesToDelete.ClientTrafficPolicyStatusKeys, key)
}
for _, backendTrafficPolicy := range result.BackendTrafficPolicies {
key := utils.NamespacedName(backendTrafficPolicy)
if !(reflect.ValueOf(backendTrafficPolicy.Status).IsZero()) {
- message.HandleStore(message.Metadata{
+ r.ProviderResources.BackendTrafficPolicyStatuses.Store(key, &backendTrafficPolicy.Status)
+ message.PublishMetric(message.Metadata{
Runner: r.Name(),
Message: message.BackendTrafficPolicyStatusMessageName,
- },
- key, &backendTrafficPolicy.Status, &r.ProviderResources.BackendTrafficPolicyStatuses)
+ })
}
delete(statusesToDelete.BackendTrafficPolicyStatusKeys, key)
}
for _, securityPolicy := range result.SecurityPolicies {
key := utils.NamespacedName(securityPolicy)
if !(reflect.ValueOf(securityPolicy.Status).IsZero()) {
- message.HandleStore(message.Metadata{
+ r.ProviderResources.SecurityPolicyStatuses.Store(key, &securityPolicy.Status)
+ message.PublishMetric(message.Metadata{
Runner: r.Name(),
Message: message.SecurityPolicyStatusMessageName,
- },
- key, &securityPolicy.Status, &r.ProviderResources.SecurityPolicyStatuses)
+ })
}
delete(statusesToDelete.SecurityPolicyStatusKeys, key)
}
for _, envoyExtensionPolicy := range result.EnvoyExtensionPolicies {
key := utils.NamespacedName(envoyExtensionPolicy)
if !(reflect.ValueOf(envoyExtensionPolicy.Status).IsZero()) {
- message.HandleStore(message.Metadata{
+ r.ProviderResources.EnvoyExtensionPolicyStatuses.Store(key, &envoyExtensionPolicy.Status)
+ message.PublishMetric(message.Metadata{
Runner: r.Name(),
Message: message.EnvoyExtensionPolicyStatusMessageName,
- },
- key, &envoyExtensionPolicy.Status, &r.ProviderResources.EnvoyExtensionPolicyStatuses)
+ })
}
delete(statusesToDelete.EnvoyExtensionPolicyStatusKeys, key)
}
for _, backend := range result.Backends {
key := utils.NamespacedName(backend)
if !(reflect.ValueOf(backend.Status).IsZero()) {
- message.HandleStore(message.Metadata{
+ r.ProviderResources.BackendStatuses.Store(key, &backend.Status)
+ message.PublishMetric(message.Metadata{
Runner: r.Name(),
Message: message.BackendStatusMessageName,
- },
- key, &backend.Status, &r.ProviderResources.BackendStatuses)
+ })
}
delete(statusesToDelete.BackendStatusKeys, key)
}
@@ -351,11 +351,11 @@ func (r *Runner) subscribeAndTranslate(sub <-chan watchable.Snapshot[string, *re
}
if !(reflect.ValueOf(extServerPolicy.Object["status"]).IsZero()) {
policyStatus := unstructuredToPolicyStatus(extServerPolicy.Object["status"].(map[string]any))
- message.HandleStore(message.Metadata{
+ r.ProviderResources.ExtensionPolicyStatuses.Store(key, &policyStatus)
+ message.PublishMetric(message.Metadata{
Runner: r.Name(),
Message: message.ExtensionServerPoliciesStatusMessageName,
- },
- key, &policyStatus, &r.ProviderResources.ExtensionPolicyStatuses)
+ })
}
delete(statusesToDelete.ExtensionServerPolicyStatusKeys, key)
}
diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go
index 6ca6f48132..7fc9a3286b 100644
--- a/internal/gatewayapi/securitypolicy.go
+++ b/internal/gatewayapi/securitypolicy.go
@@ -58,19 +58,7 @@ func (t *Translator) ProcessSecurityPolicies(securityPolicies []*egv1a1.Security
xdsIR resource.XdsIRMap,
) []*egv1a1.SecurityPolicy {
var res []*egv1a1.SecurityPolicy
-
- // Initially, policies sort by creation timestamp
- // or sort alphabetically by “{namespace}/{name}” if multiple policies share same timestamp.
- sort.Slice(securityPolicies, func(i, j int) bool {
- if securityPolicies[i].CreationTimestamp.Equal(&(securityPolicies[j].CreationTimestamp)) {
- policyKeyI := fmt.Sprintf("%s/%s", securityPolicies[i].Namespace, securityPolicies[i].Name)
- policyKeyJ := fmt.Sprintf("%s/%s", securityPolicies[j].Namespace, securityPolicies[j].Name)
- return policyKeyI < policyKeyJ
- }
- // Not identical CreationTimestamps
-
- return securityPolicies[i].CreationTimestamp.Before(&(securityPolicies[j].CreationTimestamp))
- })
+ // SecurityPolicies are already sorted by the provider layer
// First build a map out of the routes and gateways for faster lookup since users might have thousands of routes or more.
// For gateways this probably isn't quite as necessary.
@@ -104,12 +92,12 @@ func (t *Translator) ProcessSecurityPolicies(securityPolicies []*egv1a1.Security
// Process the policies targeting RouteRules
for _, currPolicy := range securityPolicies {
policyName := utils.NamespacedName(currPolicy)
- targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, routes)
+ targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, routes, currPolicy.Namespace)
for _, currTarget := range targetRefs {
if currTarget.Kind != resource.KindGateway && currTarget.SectionName != nil {
policy, found := handledPolicies[policyName]
if !found {
- policy = currPolicy.DeepCopy()
+ policy = currPolicy
handledPolicies[policyName] = policy
res = append(res, policy)
}
@@ -122,12 +110,12 @@ func (t *Translator) ProcessSecurityPolicies(securityPolicies []*egv1a1.Security
// Process the policies targeting xRoutes
for _, currPolicy := range securityPolicies {
policyName := utils.NamespacedName(currPolicy)
- targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, routes)
+ targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, routes, currPolicy.Namespace)
for _, currTarget := range targetRefs {
if currTarget.Kind != resource.KindGateway && currTarget.SectionName == nil {
policy, found := handledPolicies[policyName]
if !found {
- policy = currPolicy.DeepCopy()
+ policy = currPolicy
handledPolicies[policyName] = policy
res = append(res, policy)
}
@@ -140,12 +128,12 @@ func (t *Translator) ProcessSecurityPolicies(securityPolicies []*egv1a1.Security
// Process the policies targeting Listeners
for _, currPolicy := range securityPolicies {
policyName := utils.NamespacedName(currPolicy)
- targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways)
+ targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways, currPolicy.Namespace)
for _, currTarget := range targetRefs {
if currTarget.Kind == resource.KindGateway && currTarget.SectionName != nil {
policy, found := handledPolicies[policyName]
if !found {
- policy = currPolicy.DeepCopy()
+ policy = currPolicy
handledPolicies[policyName] = policy
res = append(res, policy)
}
@@ -158,12 +146,12 @@ func (t *Translator) ProcessSecurityPolicies(securityPolicies []*egv1a1.Security
// Process the policies targeting Gateways
for _, currPolicy := range securityPolicies {
policyName := utils.NamespacedName(currPolicy)
- targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways)
+ targetRefs := getPolicyTargetRefs(currPolicy.Spec.PolicyTargetReferences, gateways, currPolicy.Namespace)
for _, currTarget := range targetRefs {
if currTarget.Kind == resource.KindGateway && currTarget.SectionName == nil {
policy, found := handledPolicies[policyName]
if !found {
- policy = currPolicy.DeepCopy()
+ policy = currPolicy
handledPolicies[policyName] = policy
res = append(res, policy)
}
@@ -895,14 +883,21 @@ func (t *Translator) buildCORS(cors *egv1a1.CORS) *ir.CORS {
}
}
- return &ir.CORS{
+ irCORS := &ir.CORS{
AllowOrigins: allowOrigins,
AllowMethods: cors.AllowMethods,
AllowHeaders: cors.AllowHeaders,
ExposeHeaders: cors.ExposeHeaders,
- MaxAge: cors.MaxAge,
AllowCredentials: cors.AllowCredentials != nil && *cors.AllowCredentials,
}
+
+ if cors.MaxAge != nil {
+ if d, err := time.ParseDuration(string(*cors.MaxAge)); err == nil {
+ irCORS.MaxAge = ir.MetaV1DurationPtr(d)
+ }
+ }
+
+ return irCORS
}
func containsWildcard(s string) bool {
@@ -1223,28 +1218,40 @@ func (t *Translator) buildOIDC(
"HMAC secret not found in secret %s/%s", t.ControllerNamespace, oidcHMACSecretName)
}
- return &ir.OIDC{
- Name: irConfigName(policy),
- Provider: *provider,
- ClientID: clientID,
- ClientSecret: clientSecretBytes,
- Scopes: scopes,
- Resources: oidc.Resources,
- RedirectURL: redirectURL,
- RedirectPath: redirectPath,
- LogoutPath: logoutPath,
- ForwardAccessToken: forwardAccessToken,
- DefaultTokenTTL: oidc.DefaultTokenTTL,
- RefreshToken: refreshToken,
- DefaultRefreshTokenTTL: oidc.DefaultRefreshTokenTTL,
- CookieSuffix: suffix,
- CookieNameOverrides: policy.Spec.OIDC.CookieNames,
- CookieDomain: policy.Spec.OIDC.CookieDomain,
- CookieConfig: policy.Spec.OIDC.CookieConfig,
- HMACSecret: hmacData,
- PassThroughAuthHeader: passThroughAuthHeader,
- DenyRedirect: oidc.DenyRedirect,
- }, nil
+ irOIDC := &ir.OIDC{
+ Name: irConfigName(policy),
+ Provider: *provider,
+ ClientID: clientID,
+ ClientSecret: clientSecretBytes,
+ Scopes: scopes,
+ Resources: oidc.Resources,
+ RedirectURL: redirectURL,
+ RedirectPath: redirectPath,
+ LogoutPath: logoutPath,
+ ForwardAccessToken: forwardAccessToken,
+ RefreshToken: refreshToken,
+ CookieSuffix: suffix,
+ CookieNameOverrides: policy.Spec.OIDC.CookieNames,
+ CookieDomain: policy.Spec.OIDC.CookieDomain,
+ CookieConfig: policy.Spec.OIDC.CookieConfig,
+ HMACSecret: hmacData,
+ PassThroughAuthHeader: passThroughAuthHeader,
+ DenyRedirect: oidc.DenyRedirect,
+ }
+
+ if oidc.DefaultTokenTTL != nil {
+ if d, err := time.ParseDuration(string(*oidc.DefaultTokenTTL)); err == nil {
+ irOIDC.DefaultTokenTTL = ir.MetaV1DurationPtr(d)
+ }
+ }
+
+ if oidc.DefaultRefreshTokenTTL != nil {
+ if d, err := time.ParseDuration(string(*oidc.DefaultRefreshTokenTTL)); err == nil {
+ irOIDC.DefaultRefreshTokenTTL = ir.MetaV1DurationPtr(d)
+ }
+ }
+
+ return irOIDC, nil
}
func (t *Translator) buildOIDCProvider(policy *egv1a1.SecurityPolicy, resources *resource.Resources, envoyProxy *egv1a1.EnvoyProxy) (*ir.OIDCProvider, error) {
diff --git a/internal/gatewayapi/testdata/backend-tls-settings-invalid.in.yaml b/internal/gatewayapi/testdata/backend-tls-settings-invalid.in.yaml
new file mode 100644
index 0000000000..c9fdaa9eca
--- /dev/null
+++ b/internal/gatewayapi/testdata/backend-tls-settings-invalid.in.yaml
@@ -0,0 +1,157 @@
+envoyProxyForGatewayClass:
+ apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyProxy
+ metadata:
+ namespace: envoy-gateway-system
+ name: test
+ spec:
+ backendTLS:
+ clientCertificateRef:
+ group: ""
+ kind: Secret
+ namespace: envoy-gateway-system
+ name: client-auth
+ ciphers:
+ - ECDHE-RSA-AES128-GCM-SHA256
+ - ECDHE-ECDSA-AES256-GCM-SHA384
+ ecdhCurves:
+ - ECDHE-RSA-AES128-GCM-SHA256
+ - ECDHE-ECDSA-AES256-GCM-SHA384
+ maxVersion: tls1.3
+ minVersion: tls1.2
+ SignatureAlgorithms:
+ - RSA-PSS-RSAE-SHA256
+ - ECDSA-SECP256R1-SHA256
+ alpnProtocols:
+ - HTTP/1.1
+ - HTTP/2
+
+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: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-1
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-2
+
+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/v1alpha3
+ kind: BackendTLSPolicy
+ metadata:
+ name: policy-btls-for-backend-1
+ namespace: default
+ spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-1
+ validation:
+ caCertificateRefs:
+ - kind: ConfigMap
+ group: ""
+ name: ca-cmap
+ hostname: example.com
+ subjectAltNames:
+ - type: URI
+ uri: spiffe://cluster.local/ns/istio-demo/sa/echo-v1
+ - type: Hostname
+ hostname: subdomain.secondexample.com
+
+backends:
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-1
+ namespace: default
+ spec:
+ # the BackendTLSPolicy should override the one from Backend
+ # the generated ir tls settings should contain the tls settings from Backend, BackendTLSPolicy and EnvoyProxy
+ tls:
+ caCertificateRefs:
+ - name: ca-cmap
+ group: ""
+ kind: ConfigMap
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ name: backend-2
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 2.2.2.2
+ port: 3001
diff --git a/internal/gatewayapi/testdata/backend-tls-settings-invalid.out.yaml b/internal/gatewayapi/testdata/backend-tls-settings-invalid.out.yaml
new file mode 100644
index 0000000000..7c6f33d270
--- /dev/null
+++ b/internal/gatewayapi/testdata/backend-tls-settings-invalid.out.yaml
@@ -0,0 +1,325 @@
+backendTLSPolicies:
+- apiVersion: gateway.networking.k8s.io/v1alpha3
+ kind: BackendTLSPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-btls-for-backend-1
+ namespace: default
+ spec:
+ targetRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-1
+ validation:
+ caCertificateRefs:
+ - group: ""
+ kind: ConfigMap
+ name: ca-cmap
+ hostname: example.com
+ subjectAltNames:
+ - type: URI
+ uri: spiffe://cluster.local/ns/istio-demo/sa/echo-v1
+ - hostname: subdomain.secondexample.com
+ type: Hostname
+ status:
+ ancestors:
+ - ancestorRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ 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-1
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 1.1.1.1
+ port: 3001
+ tls:
+ caCertificateRefs:
+ - group: ""
+ kind: ConfigMap
+ name: ca-cmap
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: Backend
+ metadata:
+ creationTimestamp: null
+ name: backend-2
+ namespace: default
+ spec:
+ endpoints:
+ - ip:
+ address: 2.2.2.2
+ port: 3001
+ status:
+ conditions:
+ - lastTransitionTime: null
+ message: The Backend was accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+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: 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:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-1
+ matches:
+ - path:
+ value: /
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: 'Failed to process route rule 0 backendRef 0: failed to locate TLS
+ secret for client auth: envoy-gateway-system/client-auth specified in EnvoyProxy
+ envoy-gateway-system/test.'
+ reason: InvalidBackendTLS
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ rules:
+ - backendRefs:
+ - group: gateway.envoyproxy.io
+ kind: Backend
+ name: backend-2
+ matches:
+ - path:
+ value: /
+ 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
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ config:
+ apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyProxy
+ metadata:
+ creationTimestamp: null
+ name: test
+ namespace: envoy-gateway-system
+ spec:
+ backendTLS:
+ alpnProtocols:
+ - HTTP/1.1
+ - HTTP/2
+ ciphers:
+ - ECDHE-RSA-AES128-GCM-SHA256
+ - ECDHE-ECDSA-AES256-GCM-SHA384
+ clientCertificateRef:
+ group: ""
+ kind: Secret
+ name: client-auth
+ namespace: envoy-gateway-system
+ ecdhCurves:
+ - ECDHE-RSA-AES128-GCM-SHA256
+ - ECDHE-ECDSA-AES256-GCM-SHA384
+ maxVersion: tls1.3
+ minVersion: tls1.2
+ signatureAlgorithms:
+ - RSA-PSS-RSAE-SHA256
+ - ECDSA-SECP256R1-SHA256
+ logging: {}
+ 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
+ ownerReference:
+ kind: GatewayClass
+ name: envoy-gateway-class
+ name: envoy-gateway/gateway-1
+ namespace: envoy-gateway-system
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ json:
+ - path: /dev/stdout
+ globalResources:
+ proxyServiceCluster:
+ name: envoy-gateway/gateway-1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.6.5.4
+ port: 8080
+ zone: zone1
+ metadata:
+ name: envoy-envoy-gateway-gateway-1-196ae069
+ namespace: envoy-gateway-system
+ sectionName: "8080"
+ name: envoy-gateway/gateway-1
+ protocol: TCP
+ http:
+ - address: 0.0.0.0
+ externalPort: 80
+ 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
+ routes:
+ - directResponse:
+ statusCode: 500
+ hostname: '*'
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
+ - destination:
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 2.2.2.2
+ port: 3001
+ metadata:
+ kind: Backend
+ name: backend-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/backend/0
+ protocol: HTTP
+ weight: 1
+ hostname: '*'
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
+ readyListener:
+ address: 0.0.0.0
+ ipFamily: IPv4
+ path: /ready
+ port: 19003
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-default-ns-targetrefs.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-default-ns-targetrefs.out.yaml
index 3b9eed9e45..a1e60fc1a5 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-default-ns-targetrefs.out.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-default-ns-targetrefs.out.yaml
@@ -68,7 +68,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-btls
+ name: gateway-btls2
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -77,7 +77,7 @@ gateways:
namespaces:
from: All
name: http
- port: 80
+ port: 81
protocol: HTTP
status:
listeners:
@@ -108,7 +108,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-btls2
+ name: gateway-btls
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -117,7 +117,7 @@ gateways:
namespaces:
from: All
name: http
- port: 81
+ port: 80
protocol: HTTP
status:
listeners:
diff --git a/internal/gatewayapi/testdata/backendtlspolicy-status-conditions-truncated.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-status-conditions-truncated.out.yaml
index 609b9c584e..21c0b7cb87 100644
--- a/internal/gatewayapi/testdata/backendtlspolicy-status-conditions-truncated.out.yaml
+++ b/internal/gatewayapi/testdata/backendtlspolicy-status-conditions-truncated.out.yaml
@@ -416,7 +416,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-10
+ name: gateway-2
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -456,7 +456,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-11
+ name: gateway-3
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -496,7 +496,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-12
+ name: gateway-4
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -536,7 +536,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-13
+ name: gateway-5
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -576,7 +576,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-14
+ name: gateway-6
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -616,7 +616,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-15
+ name: gateway-7
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -656,7 +656,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-16
+ name: gateway-8
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -696,7 +696,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-17
+ name: gateway-9
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -736,7 +736,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-18
+ name: gateway-10
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -776,7 +776,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-2
+ name: gateway-11
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -816,7 +816,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-3
+ name: gateway-12
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -856,7 +856,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-4
+ name: gateway-13
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -896,7 +896,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-5
+ name: gateway-14
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -936,7 +936,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-6
+ name: gateway-15
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -976,7 +976,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-7
+ name: gateway-16
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1016,7 +1016,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-8
+ name: gateway-17
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1056,7 +1056,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-9
+ name: gateway-18
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-compression-json-merge.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-compression-json-merge.in.yaml
new file mode 100644
index 0000000000..2ccb740ee9
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-compression-json-merge.in.yaml
@@ -0,0 +1,63 @@
+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: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - name: service-1
+ port: 8080
+backendTrafficPolicies:
+ # Gateway-level policy
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-compression-policy
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ compression:
+ - type: Gzip
+ # Route-level policy
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: default
+ name: route-compression-policy
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ compression:
+ - type: Brotli
+ mergeType: JSONMerge
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-compression-json-merge.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-compression-json-merge.out.yaml
new file mode 100644
index 0000000000..fb49d6bfb4
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-compression-json-merge.out.yaml
@@ -0,0 +1,249 @@
+backendTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: route-compression-policy
+ namespace: default
+ spec:
+ compression:
+ - type: Brotli
+ mergeType: JSONMerge
+ 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: envoy-gateway
+ conditions:
+ - lastTransitionTime: null
+ message: Merged with policy envoy-gateway/gateway-compression-policy
+ reason: Merged
+ status: "True"
+ type: Merged
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ - 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: gateway-compression-policy
+ namespace: envoy-gateway
+ spec:
+ compression:
+ - type: Gzip
+ 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: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: 'This policy is being merged by other backendTrafficPolicies for
+ these routes: [default/httproute-1]'
+ reason: Merged
+ status: "True"
+ type: Merged
+ 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: All
+ name: http
+ 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: 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:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /
+ 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
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ 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
+ ownerReference:
+ kind: GatewayClass
+ name: envoy-gateway-class
+ name: envoy-gateway/gateway-1
+ namespace: envoy-gateway-system
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ json:
+ - path: /dev/stdout
+ globalResources:
+ proxyServiceCluster:
+ name: envoy-gateway/gateway-1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.6.5.4
+ port: 8080
+ zone: zone1
+ metadata:
+ name: envoy-envoy-gateway-gateway-1-196ae069
+ namespace: envoy-gateway-system
+ sectionName: "8080"
+ name: envoy-gateway/gateway-1
+ protocol: TCP
+ http:
+ - address: 0.0.0.0
+ externalPort: 80
+ 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
+ routes:
+ - destination:
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ metadata:
+ name: service-1
+ namespace: default
+ sectionName: "8080"
+ name: httproute/default/httproute-1/rule/0/backend/0
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
+ traffic:
+ compression:
+ - type: Brotli
+ readyListener:
+ address: 0.0.0.0
+ ipFamily: IPv4
+ path: /ready
+ port: 19003
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-compression-strategic-merge.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-compression-strategic-merge.in.yaml
new file mode 100644
index 0000000000..f09c3a93d3
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-compression-strategic-merge.in.yaml
@@ -0,0 +1,126 @@
+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: All
+httpRoutes:
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - name: service-1
+ port: 8080
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-2
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/api"
+ backendRefs:
+ - name: service-2
+ port: 8080
+ - apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-3
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/admin"
+ backendRefs:
+ - name: service-3
+ port: 8080
+backendTrafficPolicies:
+ # Gateway-level policy
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: gateway-compression-policy
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ compression:
+ - type: Gzip
+ # Route-level policy with StrategicMerge
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: default
+ name: route-compression-policy
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-1
+ compression:
+ - type: Brotli
+ mergeType: StrategicMerge
+ # Route-level policy without mergeType (should not merge with gateway policy)
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: default
+ name: route-compression-policy-no-merge
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-2
+ compression:
+ - type: Brotli
+ # Route-level policy with StrategicMerge but no compression (should inherit from gateway)
+ - apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: default
+ name: route-compression-policy-inherit
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-3
+ mergeType: StrategicMerge
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-compression-strategic-merge.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-compression-strategic-merge.out.yaml
new file mode 100644
index 0000000000..dd68160112
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-compression-strategic-merge.out.yaml
@@ -0,0 +1,463 @@
+backendTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: route-compression-policy
+ namespace: default
+ spec:
+ compression:
+ - type: Brotli
+ mergeType: StrategicMerge
+ 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: envoy-gateway
+ conditions:
+ - lastTransitionTime: null
+ message: Merged with policy envoy-gateway/gateway-compression-policy
+ reason: Merged
+ status: "True"
+ type: Merged
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ - 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: route-compression-policy-no-merge
+ namespace: default
+ spec:
+ compression:
+ - type: Brotli
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-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: route-compression-policy-inherit
+ namespace: default
+ spec:
+ mergeType: StrategicMerge
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: httproute-3
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ conditions:
+ - lastTransitionTime: null
+ message: Merged with policy envoy-gateway/gateway-compression-policy
+ reason: Merged
+ status: "True"
+ type: Merged
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ - 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: gateway-compression-policy
+ namespace: envoy-gateway
+ spec:
+ compression:
+ - type: Gzip
+ 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: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: 'This policy is being merged by other backendTrafficPolicies for
+ these routes: [default/httproute-1 default/httproute-3]'
+ reason: Merged
+ status: "True"
+ type: Merged
+ - lastTransitionTime: null
+ message: 'This policy is being overridden by other backendTrafficPolicies
+ for these routes: [default/httproute-2]'
+ reason: Overridden
+ status: "True"
+ type: Overridden
+ 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: All
+ name: http
+ port: 80
+ protocol: HTTP
+ status:
+ listeners:
+ - attachedRoutes: 3
+ 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:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /
+ 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/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-2
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-2
+ port: 8080
+ matches:
+ - path:
+ value: /api
+ 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/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ name: httproute-3
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-3
+ port: 8080
+ matches:
+ - path:
+ value: /admin
+ 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
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ 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
+ ownerReference:
+ kind: GatewayClass
+ name: envoy-gateway-class
+ name: envoy-gateway/gateway-1
+ namespace: envoy-gateway-system
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ json:
+ - path: /dev/stdout
+ globalResources:
+ proxyServiceCluster:
+ name: envoy-gateway/gateway-1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.6.5.4
+ port: 8080
+ zone: zone1
+ metadata:
+ name: envoy-envoy-gateway-gateway-1-196ae069
+ namespace: envoy-gateway-system
+ sectionName: "8080"
+ name: envoy-gateway/gateway-1
+ protocol: TCP
+ http:
+ - address: 0.0.0.0
+ externalPort: 80
+ 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
+ routes:
+ - destination:
+ metadata:
+ kind: HTTPRoute
+ name: httproute-3
+ namespace: default
+ name: httproute/default/httproute-3/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ metadata:
+ name: service-3
+ namespace: default
+ sectionName: "8080"
+ name: httproute/default/httproute-3/rule/0/backend/0
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-3
+ namespace: default
+ name: httproute/default/httproute-3/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /admin
+ traffic:
+ compression:
+ - type: Gzip
+ - destination:
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ metadata:
+ name: service-2
+ namespace: default
+ sectionName: "8080"
+ name: httproute/default/httproute-2/rule/0/backend/0
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-2
+ namespace: default
+ name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /api
+ traffic:
+ compression:
+ - type: Brotli
+ - destination:
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ metadata:
+ name: service-1
+ namespace: default
+ sectionName: "8080"
+ name: httproute/default/httproute-1/rule/0/backend/0
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
+ traffic:
+ compression:
+ - type: Brotli
+ - type: Gzip
+ readyListener:
+ address: 0.0.0.0
+ ipFamily: IPv4
+ path: /ready
+ port: 19003
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-multiple-targets-targetselector.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-multiple-targets-targetselector.in.yaml
new file mode 100644
index 0000000000..9ce7c95d67
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-multiple-targets-targetselector.in.yaml
@@ -0,0 +1,128 @@
+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: All
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute
+ labels:
+ app: web-service
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - name: service-1
+ port: 8080
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: envoy-gateway
+ name: httproute
+ labels:
+ app: web-service
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/"
+ backendRefs:
+ - name: service-2
+ namespace: envoy-gateway
+ port: 8080
+backendTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: policy-for-route-in-envoy-gateway-ns
+ spec:
+ targetSelectors:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ matchLabels:
+ app: web-service
+ useClientProtocol: true
+services:
+- apiVersion: v1
+ kind: Service
+ metadata:
+ namespace: default
+ name: service-1
+ spec:
+ ports:
+ - port: 8080
+ name: http
+ protocol: TCP
+- apiVersion: v1
+ kind: Service
+ metadata:
+ namespace: envoy-gateway
+ name: service-2
+ spec:
+ ports:
+ - port: 8080
+ name: http
+ protocol: TCP
+endpointSlices:
+- apiVersion: discovery.k8s.io/v1
+ kind: EndpointSlice
+ metadata:
+ name: endpointslice-service-1
+ namespace: default
+ labels:
+ kubernetes.io/service-name: service-1
+ addressType: IPv4
+ ports:
+ - name: http
+ protocol: TCP
+ port: 8080
+ endpoints:
+ - addresses:
+ - 8.8.8.8
+ conditions:
+ ready: true
+- apiVersion: discovery.k8s.io/v1
+ kind: EndpointSlice
+ metadata:
+ name: endpointslice-service-2
+ namespace: envoy-gateway
+ labels:
+ kubernetes.io/service-name: service-2
+ addressType: IPv4
+ ports:
+ - name: http
+ protocol: TCP
+ port: 8080
+ endpoints:
+ - addresses:
+ - 8.8.8.8
+ conditions:
+ ready: true
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-multiple-targets-targetselector.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-multiple-targets-targetselector.out.yaml
new file mode 100644
index 0000000000..8387973181
--- /dev/null
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-multiple-targets-targetselector.out.yaml
@@ -0,0 +1,278 @@
+backendTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: policy-for-route-in-envoy-gateway-ns
+ namespace: envoy-gateway
+ spec:
+ targetSelectors:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ matchLabels:
+ app: web-service
+ useClientProtocol: true
+ 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
+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: 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
+ labels:
+ app: web-service
+ name: httproute
+ namespace: default
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /
+ 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/v1
+ kind: HTTPRoute
+ metadata:
+ creationTimestamp: null
+ labels:
+ app: web-service
+ name: httproute
+ namespace: envoy-gateway
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-2
+ namespace: envoy-gateway
+ port: 8080
+ matches:
+ - path:
+ value: /
+ 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
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ 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
+ ownerReference:
+ kind: GatewayClass
+ name: envoy-gateway-class
+ name: envoy-gateway/gateway-1
+ namespace: envoy-gateway-system
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ json:
+ - path: /dev/stdout
+ globalResources:
+ proxyServiceCluster:
+ name: envoy-gateway/gateway-1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.6.5.4
+ port: 8080
+ zone: zone1
+ metadata:
+ name: envoy-envoy-gateway-gateway-1-196ae069
+ namespace: envoy-gateway-system
+ sectionName: "8080"
+ name: envoy-gateway/gateway-1
+ protocol: TCP
+ http:
+ - address: 0.0.0.0
+ externalPort: 80
+ 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
+ routes:
+ - destination:
+ metadata:
+ kind: HTTPRoute
+ name: httproute
+ namespace: default
+ name: httproute/default/httproute/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 8.8.8.8
+ port: 8080
+ - host: 7.7.7.7
+ port: 8080
+ metadata:
+ kind: Service
+ name: service-1
+ namespace: default
+ sectionName: "8080"
+ name: httproute/default/httproute/rule/0/backend/0
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute
+ namespace: default
+ name: httproute/default/httproute/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
+ - destination:
+ metadata:
+ kind: HTTPRoute
+ name: httproute
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 8.8.8.8
+ port: 8080
+ metadata:
+ kind: Service
+ name: service-2
+ namespace: envoy-gateway
+ sectionName: "8080"
+ name: httproute/envoy-gateway/httproute/rule/0/backend/0
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute
+ namespace: envoy-gateway
+ name: httproute/envoy-gateway/httproute/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
+ traffic: {}
+ useClientProtocol: true
+ readyListener:
+ address: 0.0.0.0
+ ipFamily: IPv4
+ path: /ready
+ port: 19003
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions-truncated.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions-truncated.out.yaml
index 135a8fa715..543a9435eb 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions-truncated.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions-truncated.out.yaml
@@ -223,13 +223,13 @@ backendTrafficPolicies:
kind: BackendTrafficPolicy
metadata:
creationTimestamp: null
- name: target-httproute-with-accepted-truncated-ancestors
+ name: target-httproute-with-attachment-conflict-truncated-ancestors
namespace: envoy-gateway
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
- name: httproute-1
+ name: httproute-2
status:
ancestors:
- ancestorRef:
@@ -239,9 +239,10 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -251,9 +252,10 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -263,9 +265,10 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -275,9 +278,10 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -287,9 +291,10 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -299,9 +304,10 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -311,9 +317,10 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -323,9 +330,10 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -335,9 +343,10 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -347,9 +356,10 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -359,9 +369,10 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -371,9 +382,10 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -383,9 +395,10 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -395,9 +408,10 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -407,9 +421,10 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -419,9 +434,10 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
- lastTransitionTime: null
message: 'Ancestors have been aggregated because the number of policy ancestors
@@ -434,13 +450,13 @@ backendTrafficPolicies:
kind: BackendTrafficPolicy
metadata:
creationTimestamp: null
- name: target-httproute-with-attachment-conflict-truncated-ancestors
+ name: target-httproute-with-accepted-truncated-ancestors
namespace: envoy-gateway
spec:
- targetRefs:
- - group: gateway.networking.k8s.io
+ targetRef:
+ group: gateway.networking.k8s.io
kind: HTTPRoute
- name: httproute-2
+ name: httproute-1
status:
ancestors:
- ancestorRef:
@@ -450,10 +466,9 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -463,10 +478,9 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -476,10 +490,9 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -489,10 +502,9 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -502,10 +514,9 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -515,10 +526,9 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -528,10 +538,9 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -541,10 +550,9 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -554,10 +562,9 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -567,10 +574,9 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -580,10 +586,9 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -593,10 +598,9 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -606,10 +610,9 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -619,10 +622,9 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -632,10 +634,9 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -645,10 +646,9 @@ backendTrafficPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another BackendTrafficPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
- lastTransitionTime: null
message: 'Ancestors have been aggregated because the number of policy ancestors
@@ -702,7 +702,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-10
+ name: gateway-2
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -742,7 +742,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-11
+ name: gateway-3
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -782,7 +782,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-12
+ name: gateway-4
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -822,7 +822,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-13
+ name: gateway-5
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -862,7 +862,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-14
+ name: gateway-6
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -902,7 +902,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-15
+ name: gateway-7
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -942,7 +942,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-16
+ name: gateway-8
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -982,7 +982,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-17
+ name: gateway-9
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1022,7 +1022,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-18
+ name: gateway-10
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1062,7 +1062,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-2
+ name: gateway-11
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1102,7 +1102,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-3
+ name: gateway-12
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1142,7 +1142,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-4
+ name: gateway-13
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1182,7 +1182,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-5
+ name: gateway-14
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1222,7 +1222,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-6
+ name: gateway-15
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1262,7 +1262,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-7
+ name: gateway-16
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1302,7 +1302,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-8
+ name: gateway-17
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1342,7 +1342,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-9
+ name: gateway-18
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml
index 11cc134921..a58cf6c335 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-status-conditions.out.yaml
@@ -3,7 +3,7 @@ backendTrafficPolicies:
kind: BackendTrafficPolicy
metadata:
creationTimestamp: null
- name: also-target-httproute-in-gateway-1
+ name: target-httproute-in-gateway-1
namespace: envoy-gateway
spec:
targetRef:
@@ -28,64 +28,51 @@ backendTrafficPolicies:
kind: BackendTrafficPolicy
metadata:
creationTimestamp: null
- name: not-same-namespace-httproute
+ name: also-target-httproute-in-gateway-1
namespace: envoy-gateway
spec:
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
- name: not-same-namespace-httproute
- status:
- ancestors: null
-- apiVersion: gateway.envoyproxy.io/v1alpha1
- kind: BackendTrafficPolicy
- metadata:
- creationTimestamp: null
- name: target-grpcroute-in-gateway-2
- namespace: envoy-gateway
- spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: GRPCRoute
- name: grpcroute-1
+ name: httproute-1
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-2
+ name: gateway-1
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-1, another BackendTrafficPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
creationTimestamp: null
- name: target-httproute-in-gateway-1
+ name: target-grpcroute-in-gateway-2
namespace: envoy-gateway
spec:
targetRef:
group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: httproute-1
+ kind: GRPCRoute
+ name: grpcroute-1
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-1
+ name: gateway-2
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-1, another BackendTrafficPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- apiVersion: gateway.envoyproxy.io/v1alpha1
@@ -105,13 +92,13 @@ backendTrafficPolicies:
kind: BackendTrafficPolicy
metadata:
creationTimestamp: null
- name: not-same-namespace-gateway
+ name: not-same-namespace-httproute
namespace: envoy-gateway
spec:
targetRef:
group: gateway.networking.k8s.io
- kind: Gateway
- name: not-same-namespace-gateway
+ kind: HTTPRoute
+ name: not-same-namespace-httproute
status:
ancestors: null
- apiVersion: gateway.envoyproxy.io/v1alpha1
@@ -184,47 +171,20 @@ backendTrafficPolicies:
name: unknown-gateway
status:
ancestors: null
-gateways:
-- apiVersion: gateway.networking.k8s.io/v1beta1
- kind: Gateway
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: BackendTrafficPolicy
metadata:
creationTimestamp: null
name: not-same-namespace-gateway
- namespace: another-namespace
+ namespace: envoy-gateway
spec:
- gatewayClassName: envoy-gateway-class
- listeners:
- - allowedRoutes:
- namespaces:
- from: Same
- name: http
- port: 80
- protocol: HTTP
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: not-same-namespace-gateway
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
+ ancestors: null
+gateways:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
@@ -356,6 +316,46 @@ gateways:
supportedKinds:
- group: gateway.networking.k8s.io
kind: TCPRoute
+- apiVersion: gateway.networking.k8s.io/v1beta1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: not-same-namespace-gateway
+ namespace: another-namespace
+ 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
grpcRoutes:
- apiVersion: gateway.networking.k8s.io/v1alpha2
kind: GRPCRoute
@@ -398,12 +398,12 @@ httpRoutes:
kind: HTTPRoute
metadata:
creationTimestamp: null
- name: not-same-namespace-httproute
- namespace: another-namespace
+ name: httproute-1
+ namespace: envoy-gateway
spec:
parentRefs:
- - name: not-same-namespace-gateway
- namespace: another-namespace
+ - name: gateway-1
+ namespace: envoy-gateway
rules:
- backendRefs:
- name: service-1
@@ -415,9 +415,9 @@ httpRoutes:
parents:
- conditions:
- lastTransitionTime: null
- message: No listeners included by this parent ref allowed this attachment.
- reason: NotAllowedByListeners
- status: "False"
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
type: Accepted
- lastTransitionTime: null
message: Resolved all the Object references for the Route
@@ -426,18 +426,18 @@ httpRoutes:
type: ResolvedRefs
controllerName: gateway.envoyproxy.io/gatewayclass-controller
parentRef:
- name: not-same-namespace-gateway
- namespace: another-namespace
+ name: gateway-1
+ namespace: envoy-gateway
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
- name: httproute-1
- namespace: envoy-gateway
+ name: not-same-namespace-httproute
+ namespace: another-namespace
spec:
parentRefs:
- - name: gateway-1
- namespace: envoy-gateway
+ - name: not-same-namespace-gateway
+ namespace: another-namespace
rules:
- backendRefs:
- name: service-1
@@ -449,9 +449,9 @@ httpRoutes:
parents:
- conditions:
- lastTransitionTime: null
- message: Route is accepted
- reason: Accepted
- status: "True"
+ message: No listeners included by this parent ref allowed this attachment.
+ reason: NotAllowedByListeners
+ status: "False"
type: Accepted
- lastTransitionTime: null
message: Resolved all the Object references for the Route
@@ -460,8 +460,8 @@ httpRoutes:
type: ResolvedRefs
controllerName: gateway.envoyproxy.io/gatewayclass-controller
parentRef:
- name: gateway-1
- namespace: envoy-gateway
+ name: not-same-namespace-gateway
+ namespace: another-namespace
infraIR:
another-namespace/not-same-namespace-gateway:
proxy:
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml
index 9cd4988698..461042c4c8 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-status-fault-injection.out.yaml
@@ -3,26 +3,26 @@ backendTrafficPolicies:
kind: BackendTrafficPolicy
metadata:
creationTimestamp: null
- name: policy-for-grpcroute
+ name: policy-for-route
namespace: default
spec:
faultInjection:
abort:
- grpcStatus: 14
+ httpStatus: 500
percentage: 100
delay:
fixedDelay: 5.4s
percentage: 80
targetRef:
group: gateway.networking.k8s.io
- kind: GRPCRoute
- name: grpcroute-1
+ kind: HTTPRoute
+ name: httproute-1
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-1
+ name: gateway-2
namespace: envoy-gateway
sectionName: http
conditions:
@@ -36,26 +36,26 @@ backendTrafficPolicies:
kind: BackendTrafficPolicy
metadata:
creationTimestamp: null
- name: policy-for-route
+ name: policy-for-grpcroute
namespace: default
spec:
faultInjection:
abort:
- httpStatus: 500
+ grpcStatus: 14
percentage: 100
delay:
fixedDelay: 5.4s
percentage: 80
targetRef:
group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: httproute-1
+ kind: GRPCRoute
+ name: grpcroute-1
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-2
+ name: gateway-1
namespace: envoy-gateway
sectionName: http
conditions:
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-endpointoverride-loadbalancer-multiple-mixed.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-endpointoverride-loadbalancer-multiple-mixed.out.yaml
index 107b0fbacd..ed2d15b437 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-endpointoverride-loadbalancer-multiple-mixed.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-endpointoverride-loadbalancer-multiple-mixed.out.yaml
@@ -181,6 +181,7 @@ xdsIR:
- host: 7.7.7.7
port: 8080
metadata:
+ kind: Service
name: service-1
namespace: default
sectionName: "8080"
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-endpointoverride-loadbalancer-single-header.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-endpointoverride-loadbalancer-single-header.out.yaml
index d0e166f7cc..3ea22053f2 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-endpointoverride-loadbalancer-single-header.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-endpointoverride-loadbalancer-single-header.out.yaml
@@ -181,6 +181,7 @@ xdsIR:
- host: 7.7.7.7
port: 8080
metadata:
+ kind: Service
name: service-1
namespace: default
sectionName: "8080"
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-endpointoverride-loadbalancer.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-endpointoverride-loadbalancer.out.yaml
index 9cae1a04ff..8970c4a7bb 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-endpointoverride-loadbalancer.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-endpointoverride-loadbalancer.out.yaml
@@ -219,6 +219,7 @@ xdsIR:
- host: 7.7.7.7
port: 8080
metadata:
+ kind: Service
name: service-2
namespace: default
sectionName: "8080"
@@ -250,6 +251,7 @@ xdsIR:
- host: 7.7.7.7
port: 8080
metadata:
+ kind: Service
name: service-1
namespace: default
sectionName: "8080"
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml
index 20cf9e2af0..9983ff868d 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-healthcheck.out.yaml
@@ -3,61 +3,44 @@ backendTrafficPolicies:
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
+ name: policy-for-route-1
namespace: default
spec:
healthCheck:
active:
- grpc:
- service: foo-service
- healthyThreshold: 1
- interval: 3s
+ healthyThreshold: 3
+ http:
+ expectedResponse:
+ text: pong
+ type: Text
+ expectedStatuses:
+ - 200
+ - 201
+ hostname: foo.bar
+ method: GET
+ path: /healthz
+ interval: 5s
timeout: 1s
- type: GRPC
+ type: HTTP
unhealthyThreshold: 3
+ passive:
+ baseEjectionTime: 150s
+ consecutive5XxErrors: 5
+ consecutiveGatewayErrors: 0
+ consecutiveLocalOriginFailures: 5
+ interval: 1s
+ maxEjectionPercent: 100
+ splitExternalLocalOriginErrors: false
targetRef:
group: gateway.networking.k8s.io
- kind: GRPCRoute
- name: grpcroute-3
+ kind: HTTPRoute
+ name: httproute-1
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-1
+ name: gateway-2
namespace: envoy-gateway
sectionName: http
conditions:
@@ -71,7 +54,7 @@ backendTrafficPolicies:
kind: BackendTrafficPolicy
metadata:
creationTimestamp: null
- name: policy-for-route-1
+ name: policy-for-route-4
namespace: default
spec:
healthCheck:
@@ -81,28 +64,16 @@ backendTrafficPolicies:
expectedResponse:
text: pong
type: Text
- expectedStatuses:
- - 200
- - 201
- hostname: foo.bar
method: GET
path: /healthz
interval: 5s
timeout: 1s
type: HTTP
unhealthyThreshold: 3
- passive:
- baseEjectionTime: 2m30s
- consecutive5XxErrors: 5
- consecutiveGatewayErrors: 0
- consecutiveLocalOriginFailures: 5
- interval: 1s
- maxEjectionPercent: 100
- splitExternalLocalOriginErrors: false
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
- name: httproute-1
+ name: httproute-4
status:
ancestors:
- ancestorRef:
@@ -188,7 +159,7 @@ backendTrafficPolicies:
type: TCP
unhealthyThreshold: 3
passive:
- baseEjectionTime: 2m40s
+ baseEjectionTime: 160s
consecutive5XxErrors: 5
consecutiveGatewayErrors: 0
consecutiveLocalOriginFailures: 5
@@ -218,26 +189,22 @@ backendTrafficPolicies:
kind: BackendTrafficPolicy
metadata:
creationTimestamp: null
- name: policy-for-route-4
+ name: policy-for-route-5
namespace: default
spec:
healthCheck:
active:
- healthyThreshold: 3
- http:
- expectedResponse:
- text: pong
- type: Text
- method: GET
- path: /healthz
- interval: 5s
- timeout: 1s
- type: HTTP
- unhealthyThreshold: 3
+ healthyThreshold: 2
+ initialJitter: 15s
+ interval: 30s
+ tcp: {}
+ timeout: 10s
+ type: TCP
+ unhealthyThreshold: 2
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
- name: httproute-4
+ name: httproute-5
status:
ancestors:
- ancestorRef:
@@ -257,28 +224,61 @@ backendTrafficPolicies:
kind: BackendTrafficPolicy
metadata:
creationTimestamp: null
- name: policy-for-route-5
+ name: policy-for-grpc-route
namespace: default
spec:
healthCheck:
active:
- healthyThreshold: 2
- initialJitter: 15s
- interval: 30s
- tcp: {}
- timeout: 10s
- type: TCP
- unhealthyThreshold: 2
+ healthyThreshold: 1
+ interval: 3s
+ timeout: 1s
+ type: GRPC
+ unhealthyThreshold: 3
targetRef:
group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: httproute-5
+ kind: GRPCRoute
+ name: grpcroute-2
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-2
+ 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:
@@ -312,7 +312,7 @@ backendTrafficPolicies:
type: HTTP
unhealthyThreshold: 3
passive:
- baseEjectionTime: 2m40s
+ baseEjectionTime: 160s
consecutive5XxErrors: 5
consecutiveGatewayErrors: 0
consecutiveLocalOriginFailures: 5
@@ -462,7 +462,7 @@ grpcRoutes:
kind: GRPCRoute
metadata:
creationTimestamp: null
- name: grpcroute-2
+ name: grpcroute-3
namespace: default
spec:
parentRefs:
@@ -471,7 +471,7 @@ grpcRoutes:
sectionName: http
rules:
- backendRefs:
- - name: service-2
+ - name: service-3
port: 8080
status:
parents:
@@ -495,7 +495,7 @@ grpcRoutes:
kind: GRPCRoute
metadata:
creationTimestamp: null
- name: grpcroute-3
+ name: grpcroute-2
namespace: default
spec:
parentRefs:
@@ -504,7 +504,7 @@ grpcRoutes:
sectionName: http
rules:
- backendRefs:
- - name: service-3
+ - name: service-2
port: 8080
status:
parents:
@@ -828,32 +828,33 @@ xdsIR:
- destination:
metadata:
kind: GRPCRoute
- name: grpcroute-2
+ name: grpcroute-3
namespace: default
- name: grpcroute/default/grpcroute-2/rule/0
+ name: grpcroute/default/grpcroute-3/rule/0
settings:
- addressType: IP
endpoints:
- host: 7.7.7.7
port: 8080
metadata:
- name: service-2
+ name: service-3
namespace: default
sectionName: "8080"
- name: grpcroute/default/grpcroute-2/rule/0/backend/0
+ name: grpcroute/default/grpcroute-3/rule/0/backend/0
protocol: GRPC
weight: 1
hostname: '*'
isHTTP2: true
metadata:
kind: GRPCRoute
- name: grpcroute-2
+ name: grpcroute-3
namespace: default
- name: grpcroute/default/grpcroute-2/rule/0/match/-1/*
+ name: grpcroute/default/grpcroute-3/rule/0/match/-1/*
traffic:
healthCheck:
active:
- grpc: {}
+ grpc:
+ service: foo-service
healthyThreshold: 1
interval: 3s
timeout: 1s
@@ -861,33 +862,32 @@ xdsIR:
- destination:
metadata:
kind: GRPCRoute
- name: grpcroute-3
+ name: grpcroute-2
namespace: default
- name: grpcroute/default/grpcroute-3/rule/0
+ name: grpcroute/default/grpcroute-2/rule/0
settings:
- addressType: IP
endpoints:
- host: 7.7.7.7
port: 8080
metadata:
- name: service-3
+ name: service-2
namespace: default
sectionName: "8080"
- name: grpcroute/default/grpcroute-3/rule/0/backend/0
+ name: grpcroute/default/grpcroute-2/rule/0/backend/0
protocol: GRPC
weight: 1
hostname: '*'
isHTTP2: true
metadata:
kind: GRPCRoute
- name: grpcroute-3
+ name: grpcroute-2
namespace: default
- name: grpcroute/default/grpcroute-3/rule/0/match/-1/*
+ name: grpcroute/default/grpcroute-2/rule/0/match/-1/*
traffic:
healthCheck:
active:
- grpc:
- service: foo-service
+ grpc: {}
healthyThreshold: 1
interval: 3s
timeout: 1s
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.in.yaml
index 9da4a34e66..6527fe4589 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.in.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.in.yaml
@@ -142,6 +142,11 @@ backendTrafficPolicies:
type: RoundRobin
slowStart:
window: 300s
+ zoneAware:
+ preferLocal:
+ force:
+ minEndpointsInZoneThreshold: 1
+ minEndpointsThreshold: 1
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml
index 787e1b9a97..ae77eb5215 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-loadbalancer.out.yaml
@@ -39,7 +39,7 @@ backendTrafficPolicies:
spec:
loadBalancer:
slowStart:
- window: 5m0s
+ window: 300s
type: LeastRequest
targetRef:
group: gateway.networking.k8s.io
@@ -128,8 +128,13 @@ backendTrafficPolicies:
spec:
loadBalancer:
slowStart:
- window: 5m0s
+ window: 300s
type: RoundRobin
+ zoneAware:
+ preferLocal:
+ force:
+ minEndpointsInZoneThreshold: 1
+ minEndpointsThreshold: 1
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml
index a02130e69a..bb297aa721 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml
@@ -29,7 +29,7 @@ backendTrafficPolicies:
type: HTTP
unhealthyThreshold: 3
passive:
- baseEjectionTime: 2m40s
+ baseEjectionTime: 160s
consecutive5XxErrors: 5
consecutiveGatewayErrors: 0
consecutiveLocalOriginFailures: 5
diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml
index 68bc27202b..0d6f3dda25 100644
--- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml
+++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml
@@ -29,7 +29,7 @@ backendTrafficPolicies:
type: HTTP
unhealthyThreshold: 3
passive:
- baseEjectionTime: 2m40s
+ baseEjectionTime: 160s
consecutive5XxErrors: 5
consecutiveGatewayErrors: 0
consecutiveLocalOriginFailures: 5
@@ -101,7 +101,7 @@ backendTrafficPolicies:
type: HTTP
unhealthyThreshold: 3
passive:
- baseEjectionTime: 2m40s
+ baseEjectionTime: 160s
consecutive5XxErrors: 5
consecutiveGatewayErrors: 0
consecutiveLocalOriginFailures: 5
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-connection-max-accept-per-socket-event.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-connection-max-accept-per-socket-event.in.yaml
new file mode 100644
index 0000000000..e98f57ca58
--- /dev/null
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-connection-max-accept-per-socket-event.in.yaml
@@ -0,0 +1,65 @@
+clientTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: ClientTrafficPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: default-max-accept
+ spec:
+ connection: {}
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: ClientTrafficPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: non-default-max-accept
+ spec:
+ connection:
+ maxAcceptPerSocketEvent: 3
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ sectionName: http-2
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: ClientTrafficPolicy
+ metadata:
+ namespace: envoy-gateway
+ name: disabled-max-accept
+ spec:
+ connection:
+ maxAcceptPerSocketEvent: 0
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ sectionName: http-3
+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: 8081
+ allowedRoutes:
+ namespaces:
+ from: Same
+ - name: http-2
+ protocol: HTTP
+ port: 8082
+ allowedRoutes:
+ namespaces:
+ from: Same
+ - name: http-3
+ protocol: HTTP
+ port: 8083
+ allowedRoutes:
+ namespaces:
+ from: Same
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-connection-max-accept-per-socket-event.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-connection-max-accept-per-socket-event.out.yaml
new file mode 100644
index 0000000000..542c68ee5a
--- /dev/null
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-connection-max-accept-per-socket-event.out.yaml
@@ -0,0 +1,300 @@
+clientTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: ClientTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: non-default-max-accept
+ namespace: envoy-gateway
+ spec:
+ connection:
+ maxAcceptPerSocketEvent: 3
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ sectionName: http-2
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http-2
+ 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: ClientTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: disabled-max-accept
+ namespace: envoy-gateway
+ spec:
+ connection:
+ maxAcceptPerSocketEvent: 0
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ sectionName: http-3
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http-3
+ 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: ClientTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: default-max-accept
+ namespace: envoy-gateway
+ spec:
+ connection: {}
+ 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: There are existing ClientTrafficPolicies that are overriding these
+ sections [http-2 http-3]
+ reason: Overridden
+ status: "True"
+ type: Overridden
+ - 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: envoy-gateway
+ spec:
+ gatewayClassName: envoy-gateway-class
+ listeners:
+ - allowedRoutes:
+ namespaces:
+ from: Same
+ name: http-1
+ port: 8081
+ protocol: HTTP
+ - allowedRoutes:
+ namespaces:
+ from: Same
+ name: http-2
+ port: 8082
+ protocol: HTTP
+ - allowedRoutes:
+ namespaces:
+ from: Same
+ name: http-3
+ port: 8083
+ 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
+ - 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-2
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+ - 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-3
+ 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: 8081
+ name: http-8081
+ protocol: HTTP
+ servicePort: 8081
+ - address: null
+ name: envoy-gateway/gateway-1/http-2
+ ports:
+ - containerPort: 8082
+ name: http-8082
+ protocol: HTTP
+ servicePort: 8082
+ - address: null
+ name: envoy-gateway/gateway-1/http-3
+ ports:
+ - containerPort: 8083
+ name: http-8083
+ protocol: HTTP
+ servicePort: 8083
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ ownerReference:
+ kind: GatewayClass
+ name: envoy-gateway-class
+ name: envoy-gateway/gateway-1
+ namespace: envoy-gateway-system
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ json:
+ - path: /dev/stdout
+ globalResources:
+ proxyServiceCluster:
+ name: envoy-gateway/gateway-1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.6.5.4
+ port: 8080
+ zone: zone1
+ metadata:
+ name: envoy-envoy-gateway-gateway-1-196ae069
+ namespace: envoy-gateway-system
+ sectionName: "8080"
+ name: envoy-gateway/gateway-1
+ protocol: TCP
+ http:
+ - address: 0.0.0.0
+ connection: {}
+ externalPort: 8081
+ 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: 8081
+ - address: 0.0.0.0
+ connection:
+ maxAcceptPerSocketEvent: 3
+ externalPort: 8082
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http-2
+ name: envoy-gateway/gateway-1/http-2
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 8082
+ - address: 0.0.0.0
+ connection:
+ maxAcceptPerSocketEvent: 0
+ externalPort: 8083
+ hostnames:
+ - '*'
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http-3
+ name: envoy-gateway/gateway-1/http-3
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 8083
+ readyListener:
+ address: 0.0.0.0
+ ipFamily: IPv4
+ path: /ready
+ port: 19003
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol-legacy-mixed.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol-legacy-mixed.out.yaml
index 94497b8635..0b641c23b7 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol-legacy-mixed.out.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol-legacy-mixed.out.yaml
@@ -3,20 +3,22 @@ clientTrafficPolicies:
kind: ClientTrafficPolicy
metadata:
creationTimestamp: null
- name: target-gateway-legacy-only
+ name: target-gateway-precedence-test
namespace: envoy-gateway
spec:
- enableProxyProtocol: true
+ enableProxyProtocol: false
+ proxyProtocol:
+ optional: true
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-legacy-only
+ name: gateway-precedence-test
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-legacy-only
+ name: gateway-precedence-test
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
@@ -29,21 +31,20 @@ clientTrafficPolicies:
kind: ClientTrafficPolicy
metadata:
creationTimestamp: null
- name: target-gateway-new-api-only
+ name: target-gateway-legacy-only
namespace: envoy-gateway
spec:
- proxyProtocol:
- optional: false
+ enableProxyProtocol: true
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-new-api-only
+ name: gateway-legacy-only
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-new-api-only
+ name: gateway-legacy-only
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
@@ -56,22 +57,21 @@ clientTrafficPolicies:
kind: ClientTrafficPolicy
metadata:
creationTimestamp: null
- name: target-gateway-precedence-test
+ name: target-gateway-new-api-only
namespace: envoy-gateway
spec:
- enableProxyProtocol: false
proxyProtocol:
- optional: true
+ optional: false
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-precedence-test
+ name: gateway-new-api-only
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-precedence-test
+ name: gateway-new-api-only
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
@@ -85,7 +85,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-legacy-only
+ name: gateway-precedence-test
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -93,12 +93,12 @@ gateways:
- allowedRoutes:
namespaces:
from: Same
- name: tcp-1
- port: 9090
- protocol: TCP
+ name: http-1
+ port: 80
+ protocol: HTTP
status:
listeners:
- - attachedRoutes: 1
+ - attachedRoutes: 0
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
@@ -115,15 +115,17 @@ gateways:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
- name: tcp-1
+ name: http-1
supportedKinds:
- group: gateway.networking.k8s.io
- kind: TCPRoute
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-new-api-only
+ name: gateway-legacy-only
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -131,12 +133,12 @@ gateways:
- allowedRoutes:
namespaces:
from: Same
- name: http-2
- port: 8080
- protocol: HTTP
+ name: tcp-1
+ port: 9090
+ protocol: TCP
status:
listeners:
- - attachedRoutes: 0
+ - attachedRoutes: 1
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
@@ -153,17 +155,15 @@ gateways:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
- name: http-2
+ name: tcp-1
supportedKinds:
- group: gateway.networking.k8s.io
- kind: HTTPRoute
- - group: gateway.networking.k8s.io
- kind: GRPCRoute
+ kind: TCPRoute
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-precedence-test
+ name: gateway-new-api-only
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -171,8 +171,8 @@ gateways:
- allowedRoutes:
namespaces:
from: Same
- name: http-1
- port: 80
+ name: http-2
+ port: 8080
protocol: HTTP
status:
listeners:
@@ -193,7 +193,7 @@ gateways:
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
- name: http-1
+ name: http-2
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions-truncated.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions-truncated.out.yaml
index b1d3f1c11e..b053bf086f 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions-truncated.out.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions-truncated.out.yaml
@@ -584,7 +584,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-10
+ name: gateway-2
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -624,7 +624,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-11
+ name: gateway-3
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -664,7 +664,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-12
+ name: gateway-4
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -704,7 +704,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-13
+ name: gateway-5
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -744,7 +744,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-14
+ name: gateway-6
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -784,7 +784,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-15
+ name: gateway-7
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -824,7 +824,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-16
+ name: gateway-8
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -864,7 +864,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-17
+ name: gateway-9
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -904,7 +904,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-18
+ name: gateway-10
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -944,7 +944,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-2
+ name: gateway-11
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -984,7 +984,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-3
+ name: gateway-12
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1024,7 +1024,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-4
+ name: gateway-13
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1064,7 +1064,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-5
+ name: gateway-14
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1104,7 +1104,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-6
+ name: gateway-15
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1144,7 +1144,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-7
+ name: gateway-16
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1184,7 +1184,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-8
+ name: gateway-17
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1224,7 +1224,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-9
+ name: gateway-18
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml
index c67cacd615..6e77d17577 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-status-conditions.out.yaml
@@ -1,31 +1,4 @@
clientTrafficPolicies:
-- apiVersion: gateway.envoyproxy.io/v1alpha1
- kind: ClientTrafficPolicy
- metadata:
- creationTimestamp: null
- name: not-found-section-name
- namespace: envoy-gateway
- spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: gateway-3
- sectionName: foo-bar
- status:
- ancestors:
- - ancestorRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: gateway-3
- namespace: envoy-gateway
- sectionName: foo-bar
- conditions:
- - lastTransitionTime: null
- message: No section name foo-bar found for Gateway envoy-gateway/gateway-3
- reason: TargetNotFound
- status: "False"
- type: Accepted
- controllerName: gateway.envoyproxy.io/gatewayclass-controller
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
@@ -112,15 +85,29 @@ clientTrafficPolicies:
kind: ClientTrafficPolicy
metadata:
creationTimestamp: null
- name: not-same-namespace-with-gateway
+ name: not-found-section-name
namespace: envoy-gateway
spec:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: not-same-namespace-gateway
+ name: gateway-3
+ sectionName: foo-bar
status:
- ancestors: null
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-3
+ namespace: envoy-gateway
+ sectionName: foo-bar
+ conditions:
+ - lastTransitionTime: null
+ message: No section name foo-bar found for Gateway envoy-gateway/gateway-3
+ reason: TargetNotFound
+ status: "False"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
@@ -216,6 +203,19 @@ clientTrafficPolicies:
name: unknown-gateway
status:
ancestors: null
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: ClientTrafficPolicy
+ metadata:
+ creationTimestamp: null
+ name: not-same-namespace-with-gateway
+ namespace: envoy-gateway
+ spec:
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: not-same-namespace-gateway
+ status:
+ ancestors: null
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
diff --git a/internal/gatewayapi/testdata/conflicting-policies.out.yaml b/internal/gatewayapi/testdata/conflicting-policies.out.yaml
index 0ef3c928db..9db433b2fb 100644
--- a/internal/gatewayapi/testdata/conflicting-policies.out.yaml
+++ b/internal/gatewayapi/testdata/conflicting-policies.out.yaml
@@ -244,7 +244,7 @@ securityPolicies:
- OPTIONS
allowOrigins:
- http://*.foo.com
- maxAge: 10m0s
+ maxAge: 600s
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions-truncated.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions-truncated.out.yaml
index 5332b0453c..ef6f102ee2 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions-truncated.out.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions-truncated.out.yaml
@@ -223,13 +223,13 @@ envoyExtensionPolicies:
kind: EnvoyExtensionPolicy
metadata:
creationTimestamp: null
- name: target-httproute-with-accepted-truncated-ancestors
+ name: target-httproute-with-attachment-conflict-truncated-ancestors
namespace: envoy-gateway
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
- name: httproute-1
+ name: httproute-2
status:
ancestors:
- ancestorRef:
@@ -239,9 +239,10 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -251,9 +252,10 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -263,9 +265,10 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -275,9 +278,10 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -287,9 +291,10 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -299,9 +304,10 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -311,9 +317,10 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -323,9 +330,10 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -335,9 +343,10 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -347,9 +356,10 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -359,9 +369,10 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -371,9 +382,10 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -383,9 +395,10 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -395,9 +408,10 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -407,9 +421,10 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -419,9 +434,10 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
- lastTransitionTime: null
message: 'Ancestors have been aggregated because the number of policy ancestors
@@ -434,13 +450,13 @@ envoyExtensionPolicies:
kind: EnvoyExtensionPolicy
metadata:
creationTimestamp: null
- name: target-httproute-with-attachment-conflict-truncated-ancestors
+ name: target-httproute-with-accepted-truncated-ancestors
namespace: envoy-gateway
spec:
- targetRefs:
- - group: gateway.networking.k8s.io
+ targetRef:
+ group: gateway.networking.k8s.io
kind: HTTPRoute
- name: httproute-2
+ name: httproute-1
status:
ancestors:
- ancestorRef:
@@ -450,10 +466,9 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -463,10 +478,9 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -476,10 +490,9 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -489,10 +502,9 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -502,10 +514,9 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -515,10 +526,9 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -528,10 +538,9 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -541,10 +550,9 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -554,10 +562,9 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -567,10 +574,9 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -580,10 +586,9 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -593,10 +598,9 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -606,10 +610,9 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -619,10 +622,9 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -632,10 +634,9 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -645,10 +646,9 @@ envoyExtensionPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another EnvoyExtensionPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
- lastTransitionTime: null
message: 'Ancestors have been aggregated because the number of policy ancestors
@@ -702,7 +702,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-10
+ name: gateway-2
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -742,7 +742,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-11
+ name: gateway-3
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -782,7 +782,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-12
+ name: gateway-4
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -822,7 +822,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-13
+ name: gateway-5
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -862,7 +862,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-14
+ name: gateway-6
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -902,7 +902,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-15
+ name: gateway-7
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -942,7 +942,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-16
+ name: gateway-8
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -982,7 +982,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-17
+ name: gateway-9
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1022,7 +1022,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-18
+ name: gateway-10
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1062,7 +1062,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-2
+ name: gateway-11
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1102,7 +1102,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-3
+ name: gateway-12
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1142,7 +1142,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-4
+ name: gateway-13
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1182,7 +1182,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-5
+ name: gateway-14
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1222,7 +1222,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-6
+ name: gateway-15
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1262,7 +1262,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-7
+ name: gateway-16
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1302,7 +1302,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-8
+ name: gateway-17
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1342,7 +1342,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-9
+ name: gateway-18
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml
index ef54e8f3eb..d013002c7e 100644
--- a/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml
+++ b/internal/gatewayapi/testdata/envoyextensionpolicy-status-conditions.out.yaml
@@ -3,7 +3,7 @@ envoyExtensionPolicies:
kind: EnvoyExtensionPolicy
metadata:
creationTimestamp: null
- name: also-target-httproute-in-gateway-1
+ name: target-httproute-in-gateway-1
namespace: envoy-gateway
spec:
targetRef:
@@ -28,64 +28,51 @@ envoyExtensionPolicies:
kind: EnvoyExtensionPolicy
metadata:
creationTimestamp: null
- name: not-same-namespace-httproute
+ name: also-target-httproute-in-gateway-1
namespace: envoy-gateway
spec:
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
- name: not-same-namespace-httproute
- status:
- ancestors: null
-- apiVersion: gateway.envoyproxy.io/v1alpha1
- kind: EnvoyExtensionPolicy
- metadata:
- creationTimestamp: null
- name: target-grpcroute-in-gateway-2
- namespace: envoy-gateway
- spec:
- targetRef:
- group: gateway.networking.k8s.io
- kind: GRPCRoute
- name: grpcroute-1
+ name: httproute-1
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-2
+ name: gateway-1
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-1, another EnvoyExtensionPolicy
+ has already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyExtensionPolicy
metadata:
creationTimestamp: null
- name: target-httproute-in-gateway-1
+ name: target-grpcroute-in-gateway-2
namespace: envoy-gateway
spec:
targetRef:
group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: httproute-1
+ kind: GRPCRoute
+ name: grpcroute-1
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-1
+ name: gateway-2
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-1, another EnvoyExtensionPolicy
- has already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- apiVersion: gateway.envoyproxy.io/v1alpha1
@@ -105,13 +92,13 @@ envoyExtensionPolicies:
kind: EnvoyExtensionPolicy
metadata:
creationTimestamp: null
- name: not-same-namespace-gateway
+ name: not-same-namespace-httproute
namespace: envoy-gateway
spec:
targetRef:
group: gateway.networking.k8s.io
- kind: Gateway
- name: not-same-namespace-gateway
+ kind: HTTPRoute
+ name: not-same-namespace-httproute
status:
ancestors: null
- apiVersion: gateway.envoyproxy.io/v1alpha1
@@ -184,47 +171,20 @@ envoyExtensionPolicies:
name: unknown-gateway
status:
ancestors: null
-gateways:
-- apiVersion: gateway.networking.k8s.io/v1beta1
- kind: Gateway
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+ kind: EnvoyExtensionPolicy
metadata:
creationTimestamp: null
name: not-same-namespace-gateway
- namespace: another-namespace
+ namespace: envoy-gateway
spec:
- gatewayClassName: envoy-gateway-class
- listeners:
- - allowedRoutes:
- namespaces:
- from: Same
- name: http
- port: 80
- protocol: HTTP
+ targetRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: not-same-namespace-gateway
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
+ ancestors: null
+gateways:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
@@ -356,6 +316,46 @@ gateways:
supportedKinds:
- group: gateway.networking.k8s.io
kind: TCPRoute
+- apiVersion: gateway.networking.k8s.io/v1beta1
+ kind: Gateway
+ metadata:
+ creationTimestamp: null
+ name: not-same-namespace-gateway
+ namespace: another-namespace
+ 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
grpcRoutes:
- apiVersion: gateway.networking.k8s.io/v1alpha2
kind: GRPCRoute
@@ -398,12 +398,12 @@ httpRoutes:
kind: HTTPRoute
metadata:
creationTimestamp: null
- name: not-same-namespace-httproute
- namespace: another-namespace
+ name: httproute-1
+ namespace: envoy-gateway
spec:
parentRefs:
- - name: not-same-namespace-gateway
- namespace: another-namespace
+ - name: gateway-1
+ namespace: envoy-gateway
rules:
- backendRefs:
- name: service-1
@@ -415,9 +415,9 @@ httpRoutes:
parents:
- conditions:
- lastTransitionTime: null
- message: No listeners included by this parent ref allowed this attachment.
- reason: NotAllowedByListeners
- status: "False"
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
type: Accepted
- lastTransitionTime: null
message: Resolved all the Object references for the Route
@@ -426,18 +426,18 @@ httpRoutes:
type: ResolvedRefs
controllerName: gateway.envoyproxy.io/gatewayclass-controller
parentRef:
- name: not-same-namespace-gateway
- namespace: another-namespace
+ name: gateway-1
+ namespace: envoy-gateway
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
- name: httproute-1
- namespace: envoy-gateway
+ name: not-same-namespace-httproute
+ namespace: another-namespace
spec:
parentRefs:
- - name: gateway-1
- namespace: envoy-gateway
+ - name: not-same-namespace-gateway
+ namespace: another-namespace
rules:
- backendRefs:
- name: service-1
@@ -449,9 +449,9 @@ httpRoutes:
parents:
- conditions:
- lastTransitionTime: null
- message: Route is accepted
- reason: Accepted
- status: "True"
+ message: No listeners included by this parent ref allowed this attachment.
+ reason: NotAllowedByListeners
+ status: "False"
type: Accepted
- lastTransitionTime: null
message: Resolved all the Object references for the Route
@@ -460,8 +460,8 @@ httpRoutes:
type: ResolvedRefs
controllerName: gateway.envoyproxy.io/gatewayclass-controller
parentRef:
- name: gateway-1
- namespace: envoy-gateway
+ name: not-same-namespace-gateway
+ namespace: another-namespace
infraIR:
another-namespace/not-same-namespace-gateway:
proxy:
diff --git a/internal/gatewayapi/testdata/envoypatchpolicy-valid-merge-gateways.out.yaml b/internal/gatewayapi/testdata/envoypatchpolicy-valid-merge-gateways.out.yaml
index cc35cb7f67..6ed5b7c521 100644
--- a/internal/gatewayapi/testdata/envoypatchpolicy-valid-merge-gateways.out.yaml
+++ b/internal/gatewayapi/testdata/envoypatchpolicy-valid-merge-gateways.out.yaml
@@ -79,10 +79,10 @@ xdsIR:
- name: envoy-gateway-gateway-1-http
operation:
op: replace
- path: /ignore_global_conn_limit
- value: "true"
+ path: /per_connection_buffer_limit_bytes
+ value: "1024"
type: type.googleapis.com/envoy.config.listener.v3.Listener
- name: edit-ignore-global-limit
+ name: edit-conn-buffer-bytes
namespace: envoy-gateway
status:
ancestors:
@@ -101,10 +101,10 @@ xdsIR:
- name: envoy-gateway-gateway-1-http
operation:
op: replace
- path: /per_connection_buffer_limit_bytes
- value: "1024"
+ path: /ignore_global_conn_limit
+ value: "true"
type: type.googleapis.com/envoy.config.listener.v3.Listener
- name: edit-conn-buffer-bytes
+ name: edit-ignore-global-limit
namespace: envoy-gateway
status:
ancestors:
diff --git a/internal/gatewayapi/testdata/envoypatchpolicy-valid.out.yaml b/internal/gatewayapi/testdata/envoypatchpolicy-valid.out.yaml
index 59d64e660a..93155c0ccd 100644
--- a/internal/gatewayapi/testdata/envoypatchpolicy-valid.out.yaml
+++ b/internal/gatewayapi/testdata/envoypatchpolicy-valid.out.yaml
@@ -69,10 +69,10 @@ xdsIR:
- name: envoy-gateway-gateway-1-http
operation:
op: replace
- path: /ignore_global_conn_limit
- value: "true"
+ path: /per_connection_buffer_limit_bytes
+ value: "1024"
type: type.googleapis.com/envoy.config.listener.v3.Listener
- name: edit-ignore-global-limit
+ name: edit-conn-buffer-bytes
namespace: envoy-gateway
status:
ancestors:
@@ -93,10 +93,10 @@ xdsIR:
- name: envoy-gateway-gateway-1-http
operation:
op: replace
- path: /per_connection_buffer_limit_bytes
- value: "1024"
+ path: /ignore_global_conn_limit
+ value: "true"
type: type.googleapis.com/envoy.config.listener.v3.Listener
- name: edit-conn-buffer-bytes
+ name: edit-ignore-global-limit
namespace: envoy-gateway
status:
ancestors:
diff --git a/internal/gatewayapi/testdata/envoyproxy-with-statname.out.yaml b/internal/gatewayapi/testdata/envoyproxy-with-statname.out.yaml
index 9c194246aa..59ced8aa6b 100644
--- a/internal/gatewayapi/testdata/envoyproxy-with-statname.out.yaml
+++ b/internal/gatewayapi/testdata/envoyproxy-with-statname.out.yaml
@@ -230,7 +230,7 @@ xdsIR:
name: httproute/default/httproute-1/rule/0/backend/1
protocol: HTTP
weight: 1
- statName: HTTPRoute/default/httproute-1/foo/0/default/service-3|default/service-4
+ statName: httproute/default/httproute-1/foo/0/default/service-3|default/service-4
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
@@ -262,7 +262,7 @@ xdsIR:
name: httproute/default/httproute-1/rule/1/backend/0
protocol: HTTP
weight: 1
- statName: HTTPRoute/default/httproute-1/fallback/1/default/service-1
+ statName: httproute/default/httproute-1/fallback/1/default/service-1
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
@@ -326,7 +326,7 @@ xdsIR:
name: grpcroute/default/grpcroute-1/rule/0/backend/3
protocol: GRPC
weight: 1
- statName: GRPCRoute/default/grpcroute-1/-/0/default/service-1|default/service-2|default/service-3|default/service-4
+ statName: grpcroute/default/grpcroute-1/-/0/default/service-1|default/service-2|default/service-3|default/service-4
hostname: '*'
isHTTP2: true
metadata:
diff --git a/internal/gatewayapi/testdata/extensions/extensionpolicy-tcp-listener.out.yaml b/internal/gatewayapi/testdata/extensions/extensionpolicy-tcp-listener.out.yaml
index 41b161cbc3..9091747abd 100644
--- a/internal/gatewayapi/testdata/extensions/extensionpolicy-tcp-listener.out.yaml
+++ b/internal/gatewayapi/testdata/extensions/extensionpolicy-tcp-listener.out.yaml
@@ -162,6 +162,20 @@ xdsIR:
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: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
- object:
apiVersion: foo.example.io/v1alpha1
kind: Bar
@@ -175,6 +189,21 @@ xdsIR:
kind: Gateway
name: gateway-1
sectionName: tcp1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: tcp1
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
globalResources:
proxyServiceCluster:
name: envoy-gateway/gateway-1
diff --git a/internal/gatewayapi/testdata/extensions/extensionpolicy-udp-listener.out.yaml b/internal/gatewayapi/testdata/extensions/extensionpolicy-udp-listener.out.yaml
index 6282b46226..68600c04d2 100644
--- a/internal/gatewayapi/testdata/extensions/extensionpolicy-udp-listener.out.yaml
+++ b/internal/gatewayapi/testdata/extensions/extensionpolicy-udp-listener.out.yaml
@@ -162,6 +162,20 @@ xdsIR:
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: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
- object:
apiVersion: foo.example.io/v1alpha1
kind: Bar
@@ -175,6 +189,21 @@ xdsIR:
kind: Gateway
name: gateway-1
sectionName: udp1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: udp1
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
globalResources:
proxyServiceCluster:
name: envoy-gateway/gateway-1
diff --git a/internal/gatewayapi/testdata/extensions/extensionpolicy-with-valid-target-array.out.yaml b/internal/gatewayapi/testdata/extensions/extensionpolicy-with-valid-target-array.out.yaml
index 39fb71a8ba..a4806effd3 100644
--- a/internal/gatewayapi/testdata/extensions/extensionpolicy-with-valid-target-array.out.yaml
+++ b/internal/gatewayapi/testdata/extensions/extensionpolicy-with-valid-target-array.out.yaml
@@ -180,6 +180,32 @@ xdsIR:
- group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-2
+ namespace: envoy-gateway
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
http:
- address: 0.0.0.0
extensionRefs:
@@ -263,6 +289,32 @@ xdsIR:
- group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-2
+ namespace: envoy-gateway
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
globalResources:
proxyServiceCluster:
name: envoy-gateway/gateway-2
diff --git a/internal/gatewayapi/testdata/extensions/extensionpolicy-with-valid-target.out.yaml b/internal/gatewayapi/testdata/extensions/extensionpolicy-with-valid-target.out.yaml
index 5df8dc3518..63495e3991 100644
--- a/internal/gatewayapi/testdata/extensions/extensionpolicy-with-valid-target.out.yaml
+++ b/internal/gatewayapi/testdata/extensions/extensionpolicy-with-valid-target.out.yaml
@@ -166,6 +166,20 @@ xdsIR:
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: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
- object:
apiVersion: foo.example.io/v1alpha1
kind: Bar
@@ -179,6 +193,21 @@ xdsIR:
kind: Gateway
name: gateway-1
sectionName: http2
+ status:
+ ancestors:
+ - ancestorRef:
+ group: gateway.networking.k8s.io
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http2
+ conditions:
+ - lastTransitionTime: null
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
globalResources:
proxyServiceCluster:
name: envoy-gateway/gateway-1
diff --git a/internal/gatewayapi/testdata/extensions/grpcroute-with-valid-extension-filter.in.yaml b/internal/gatewayapi/testdata/extensions/grpcroute-with-valid-extension-filter.in.yaml
new file mode 100644
index 0000000000..c44e2ca8d0
--- /dev/null
+++ b/internal/gatewayapi/testdata/extensions/grpcroute-with-valid-extension-filter.in.yaml
@@ -0,0 +1,48 @@
+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: All
+grpcRoutes:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ namespace: default
+ name: grpcroute-1
+ spec:
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - method:
+ service: com.example.Service
+ type: Exact
+ backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - type: ExtensionRef
+ extensionRef:
+ group: foo.example.io
+ kind: Foo
+ name: test
+extensionRefFilters:
+- apiVersion: foo.example.io/v1alpha1
+ kind: Foo
+ metadata:
+ name: test
+ namespace: default
+ spec:
+ data: "stuff"
diff --git a/internal/gatewayapi/testdata/extensions/grpcroute-with-valid-extension-filter.out.yaml b/internal/gatewayapi/testdata/extensions/grpcroute-with-valid-extension-filter.out.yaml
new file mode 100644
index 0000000000..be7d056cd8
--- /dev/null
+++ b/internal/gatewayapi/testdata/extensions/grpcroute-with-valid-extension-filter.out.yaml
@@ -0,0 +1,184 @@
+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: http
+ 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: http
+ supportedKinds:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ - group: gateway.networking.k8s.io
+ kind: GRPCRoute
+grpcRoutes:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+ kind: GRPCRoute
+ metadata:
+ creationTimestamp: null
+ name: grpcroute-1
+ namespace: default
+ spec:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ filters:
+ - extensionRef:
+ group: foo.example.io
+ kind: Foo
+ name: test
+ type: ExtensionRef
+ matches:
+ - method:
+ service: com.example.Service
+ type: Exact
+ 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
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ 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
+ ownerReference:
+ kind: GatewayClass
+ name: envoy-gateway-class
+ name: envoy-gateway/gateway-1
+ namespace: ""
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ json:
+ - path: /dev/stdout
+ globalResources:
+ proxyServiceCluster:
+ name: envoy-gateway/gateway-1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.6.5.4
+ port: 8080
+ zone: zone1
+ metadata:
+ name: envoy-envoy-gateway-gateway-1-196ae069
+ sectionName: "8080"
+ name: envoy-gateway/gateway-1
+ protocol: TCP
+ http:
+ - address: 0.0.0.0
+ externalPort: 80
+ hostnames:
+ - '*'
+ isHTTP2: true
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ name: envoy-gateway/gateway-1/http
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10080
+ routes:
+ - destination:
+ metadata:
+ kind: GRPCRoute
+ name: grpcroute-1
+ namespace: default
+ name: grpcroute/default/grpcroute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ metadata:
+ name: service-1
+ namespace: default
+ sectionName: "8080"
+ name: grpcroute/default/grpcroute-1/rule/0/backend/0
+ protocol: GRPC
+ weight: 1
+ extensionRefs:
+ - object:
+ apiVersion: foo.example.io/v1alpha1
+ kind: Foo
+ metadata:
+ name: test
+ namespace: default
+ spec:
+ data: stuff
+ hostname: '*'
+ isHTTP2: true
+ metadata:
+ kind: GRPCRoute
+ name: grpcroute-1
+ namespace: default
+ name: grpcroute/default/grpcroute-1/rule/0/match/0/*
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /com.example.Service
+ readyListener:
+ address: 0.0.0.0
+ ipFamily: IPv4
+ path: /ready
+ port: 19003
diff --git a/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-invalid-apiversion.out.yaml b/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-invalid-apiversion.out.yaml
index bf91cc836b..1083567720 100644
--- a/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-invalid-apiversion.out.yaml
+++ b/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-invalid-apiversion.out.yaml
@@ -80,9 +80,11 @@ httpRoutes:
status: "True"
type: Accepted
- lastTransitionTime: null
- message: Resolved all the Object references for the Route
- reason: ResolvedRefs
- status: "True"
+ message: |-
+ Failed to process route rule 0 backendRef 0: custom backend S3Backend default/s3-backend not found.
+ Failed to process route rule 1 backendRef 0: custom backend LambdaBackend default/lambda-backend not found.
+ reason: BackendNotFound
+ status: "False"
type: ResolvedRefs
controllerName: gateway.envoyproxy.io/gatewayclass-controller
parentRef:
@@ -145,16 +147,8 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- metadata:
- kind: HTTPRoute
- name: httproute-1
- namespace: default
- name: httproute/default/httproute-1/rule/1
- settings:
- - isCustomBackend: true
- name: httproute/default/httproute-1/rule/1/backend/0
- weight: 1
+ - directResponse:
+ statusCode: 500
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
@@ -166,16 +160,8 @@ xdsIR:
distinct: false
name: ""
prefix: /lambda
- - destination:
- metadata:
- kind: HTTPRoute
- name: httproute-1
- namespace: default
- name: httproute/default/httproute-1/rule/0
- settings:
- - isCustomBackend: true
- name: httproute/default/httproute-1/rule/0/backend/0
- weight: 1
+ - directResponse:
+ statusCode: 500
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
diff --git a/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-mixed-multiple.out.yaml b/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-mixed-multiple.out.yaml
index 0462d3e050..1a96f003f8 100644
--- a/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-mixed-multiple.out.yaml
+++ b/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-mixed-multiple.out.yaml
@@ -169,6 +169,7 @@ xdsIR:
- host: 7.7.7.7
port: 8080
metadata:
+ kind: Service
name: service-1
namespace: default
sectionName: "8080"
@@ -231,6 +232,7 @@ xdsIR:
- host: 7.7.7.7
port: 8080
metadata:
+ kind: Service
name: service-2
namespace: default
sectionName: "8080"
diff --git a/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-mixed.out.yaml b/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-mixed.out.yaml
index 45342445e2..a5b5e3db18 100644
--- a/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-mixed.out.yaml
+++ b/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-mixed.out.yaml
@@ -161,6 +161,7 @@ xdsIR:
- host: 7.7.7.7
port: 8080
metadata:
+ kind: Service
name: service-1
namespace: default
sectionName: "8080"
@@ -207,6 +208,7 @@ xdsIR:
- host: 7.7.7.7
port: 8080
metadata:
+ kind: Service
name: service-2
namespace: default
sectionName: "8080"
diff --git a/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-not-found.in.yaml b/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-not-found.in.yaml
new file mode 100644
index 0000000000..bd1054f0e7
--- /dev/null
+++ b/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-not-found.in.yaml
@@ -0,0 +1,46 @@
+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
+ hostname: "*.envoyproxy.io"
+ allowedRoutes:
+ namespaces:
+ from: All
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+ kind: HTTPRoute
+ metadata:
+ namespace: default
+ name: httproute-1
+ spec:
+ hostnames:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - namespace: envoy-gateway
+ name: gateway-1
+ sectionName: http
+ rules:
+ - matches:
+ - path:
+ value: "/s3"
+ backendRefs:
+ - group: storage.example.io
+ kind: S3Backend
+ name: s3-backend
+ port: 443
+ - matches:
+ - path:
+ value: "/lambda"
+ backendRefs:
+ - group: compute.example.io
+ kind: LambdaBackend
+ name: lambda-backend
+ port: 443
diff --git a/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-not-found.out.yaml b/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-not-found.out.yaml
new file mode 100644
index 0000000000..1083567720
--- /dev/null
+++ b/internal/gatewayapi/testdata/extensions/httproute-with-custom-backend-not-found.out.yaml
@@ -0,0 +1,180 @@
+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
+ hostname: '*.envoyproxy.io'
+ name: http
+ 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: 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:
+ - gateway.envoyproxy.io
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+ rules:
+ - backendRefs:
+ - group: storage.example.io
+ kind: S3Backend
+ name: s3-backend
+ port: 443
+ matches:
+ - path:
+ value: /s3
+ - backendRefs:
+ - group: compute.example.io
+ kind: LambdaBackend
+ name: lambda-backend
+ port: 443
+ matches:
+ - path:
+ value: /lambda
+ status:
+ parents:
+ - conditions:
+ - lastTransitionTime: null
+ message: Route is accepted
+ reason: Accepted
+ status: "True"
+ type: Accepted
+ - lastTransitionTime: null
+ message: |-
+ Failed to process route rule 0 backendRef 0: custom backend S3Backend default/s3-backend not found.
+ Failed to process route rule 1 backendRef 0: custom backend LambdaBackend default/lambda-backend not found.
+ reason: BackendNotFound
+ status: "False"
+ type: ResolvedRefs
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parentRef:
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: http
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ 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
+ ownerReference:
+ kind: GatewayClass
+ name: envoy-gateway-class
+ name: envoy-gateway/gateway-1
+ namespace: ""
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ json:
+ - path: /dev/stdout
+ globalResources:
+ proxyServiceCluster:
+ name: envoy-gateway/gateway-1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.6.5.4
+ port: 8080
+ zone: zone1
+ metadata:
+ name: envoy-envoy-gateway-gateway-1-196ae069
+ sectionName: "8080"
+ name: envoy-gateway/gateway-1
+ protocol: TCP
+ http:
+ - address: 0.0.0.0
+ externalPort: 80
+ hostnames:
+ - '*.envoyproxy.io'
+ 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
+ routes:
+ - directResponse:
+ statusCode: 500
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/1/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /lambda
+ - directResponse:
+ statusCode: 500
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /s3
+ readyListener:
+ address: 0.0.0.0
+ ipFamily: IPv4
+ path: /ready
+ port: 19003
diff --git a/internal/gatewayapi/testdata/gateway-namespace-mode-infra-httproute.out.yaml b/internal/gatewayapi/testdata/gateway-namespace-mode-infra-httproute.out.yaml
index 4507655c60..abeb51acf8 100644
--- a/internal/gatewayapi/testdata/gateway-namespace-mode-infra-httproute.out.yaml
+++ b/internal/gatewayapi/testdata/gateway-namespace-mode-infra-httproute.out.yaml
@@ -317,6 +317,7 @@ xdsIR:
- host: 7.7.7.7
port: 8080
metadata:
+ kind: Service
name: service-1
namespace: default
sectionName: "8080"
@@ -372,6 +373,7 @@ xdsIR:
- host: 7.7.7.7
port: 8080
metadata:
+ kind: Service
name: service-2
namespace: default
sectionName: "8080"
@@ -398,6 +400,16 @@ xdsIR:
accessLog:
json:
- path: /dev/stdout
+ globalResources:
+ proxyServiceCluster:
+ name: test-ns/gateway-3
+ settings:
+ - metadata:
+ name: gateway-3
+ namespace: test-ns
+ sectionName: "8080"
+ name: test-ns/gateway-3
+ protocol: TCP
http:
- address: 0.0.0.0
externalPort: 80
diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-multiple-tls-configuration.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-multiple-tls-configuration.out.yaml
index bbdb1f4df6..d1fde15677 100644
--- a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-multiple-tls-configuration.out.yaml
+++ b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-multiple-tls-configuration.out.yaml
@@ -32,8 +32,7 @@ gateways:
conditions:
- lastTransitionTime: null
message: Secret envoy-gateway/tls-secret-ecdsa-2 public key algorithm must
- be unique, matched certificate FQDN [foo.bar.com] has a conflicting algorithm
- [ECDSA].
+ be unique, certificate domain foo.bar.com has a conflicting algorithm [ECDSA].
reason: InvalidCertificateRef
status: "False"
type: ResolvedRefs
diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-no-valid-certificate-for-fqdn.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-no-valid-certificate-for-fqdn.out.yaml
deleted file mode 100644
index a28e3dc648..0000000000
--- a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-no-valid-certificate-for-fqdn.out.yaml
+++ /dev/null
@@ -1,117 +0,0 @@
-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
- hostname: example.com
- name: tls
- port: 443
- protocol: HTTPS
- tls:
- certificateRefs:
- - group: null
- kind: null
- name: tls-secret-1
- mode: Terminate
- status:
- listeners:
- - attachedRoutes: 1
- conditions:
- - lastTransitionTime: null
- message: Secret envoy-gateway/tls-secret-1 must contain valid tls.crt and
- tls.key, hostname example.com does not match Common Name or DNS Names in
- the certificate tls.crt.
- reason: InvalidCertificateRef
- status: "False"
- type: ResolvedRefs
- - lastTransitionTime: null
- message: Listener is invalid, see other Conditions for details.
- reason: Invalid
- status: "False"
- type: Programmed
- name: tls
- 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:
- parentRefs:
- - name: gateway-1
- namespace: envoy-gateway
- rules:
- - backendRefs:
- - name: service-1
- port: 8080
- matches:
- - path:
- value: /
- status:
- parents:
- - conditions:
- - lastTransitionTime: null
- message: There are no ready listeners for this parent ref
- reason: NoReadyListeners
- status: "False"
- 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
-infraIR:
- envoy-gateway/gateway-1:
- proxy:
- metadata:
- labels:
- gateway.envoyproxy.io/owning-gateway-name: gateway-1
- gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
- ownerReference:
- kind: GatewayClass
- name: envoy-gateway-class
- name: envoy-gateway/gateway-1
- namespace: envoy-gateway-system
-xdsIR:
- envoy-gateway/gateway-1:
- accessLog:
- json:
- - path: /dev/stdout
- globalResources:
- proxyServiceCluster:
- name: envoy-gateway/gateway-1
- settings:
- - addressType: IP
- endpoints:
- - host: 7.6.5.4
- port: 8080
- zone: zone1
- metadata:
- name: envoy-envoy-gateway-gateway-1-196ae069
- namespace: envoy-gateway-system
- sectionName: "8080"
- name: envoy-gateway/gateway-1
- protocol: TCP
- readyListener:
- address: 0.0.0.0
- ipFamily: IPv4
- path: /ready
- port: 19003
diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-no-valid-certificate-for-fqdn.in.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-tls-configuration-sni-san-mismatch-allowed.in.yaml
similarity index 100%
rename from internal/gatewayapi/testdata/gateway-with-listener-with-invalid-tls-configuration-no-valid-certificate-for-fqdn.in.yaml
rename to internal/gatewayapi/testdata/gateway-with-listener-with-tls-configuration-sni-san-mismatch-allowed.in.yaml
diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-tls-configuration-sni-san-mismatch-allowed.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-tls-configuration-sni-san-mismatch-allowed.out.yaml
new file mode 100644
index 0000000000..1ebb9fc1a5
--- /dev/null
+++ b/internal/gatewayapi/testdata/gateway-with-listener-with-tls-configuration-sni-san-mismatch-allowed.out.yaml
@@ -0,0 +1,180 @@
+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
+ hostname: example.com
+ name: tls
+ port: 443
+ protocol: HTTPS
+ tls:
+ certificateRefs:
+ - group: null
+ kind: null
+ name: tls-secret-1
+ mode: Terminate
+ 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: tls
+ 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:
+ parentRefs:
+ - name: gateway-1
+ namespace: envoy-gateway
+ rules:
+ - backendRefs:
+ - name: service-1
+ port: 8080
+ matches:
+ - path:
+ value: /
+ 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
+infraIR:
+ envoy-gateway/gateway-1:
+ proxy:
+ listeners:
+ - address: null
+ name: envoy-gateway/gateway-1/tls
+ ports:
+ - containerPort: 10443
+ name: https-443
+ protocol: HTTPS
+ servicePort: 443
+ metadata:
+ labels:
+ gateway.envoyproxy.io/owning-gateway-name: gateway-1
+ gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+ ownerReference:
+ kind: GatewayClass
+ name: envoy-gateway-class
+ name: envoy-gateway/gateway-1
+ namespace: envoy-gateway-system
+xdsIR:
+ envoy-gateway/gateway-1:
+ accessLog:
+ json:
+ - path: /dev/stdout
+ globalResources:
+ proxyServiceCluster:
+ name: envoy-gateway/gateway-1
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.6.5.4
+ port: 8080
+ zone: zone1
+ metadata:
+ name: envoy-envoy-gateway-gateway-1-196ae069
+ namespace: envoy-gateway-system
+ sectionName: "8080"
+ name: envoy-gateway/gateway-1
+ protocol: TCP
+ http:
+ - address: 0.0.0.0
+ externalPort: 443
+ hostnames:
+ - example.com
+ isHTTP2: false
+ metadata:
+ kind: Gateway
+ name: gateway-1
+ namespace: envoy-gateway
+ sectionName: tls
+ name: envoy-gateway/gateway-1/tls
+ path:
+ escapedSlashesAction: UnescapeAndRedirect
+ mergeSlashes: true
+ port: 10443
+ routes:
+ - destination:
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 7.7.7.7
+ port: 8080
+ metadata:
+ name: service-1
+ namespace: default
+ sectionName: "8080"
+ name: httproute/default/httproute-1/rule/0/backend/0
+ protocol: HTTP
+ weight: 1
+ hostname: example.com
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-1
+ namespace: default
+ name: httproute/default/httproute-1/rule/0/match/0/example_com
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /
+ tls:
+ alpnProtocols: null
+ certificates:
+ - certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrek1ERXdXaGNOTXpRdwpNakkyTURrek1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOVE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
+ name: envoy-gateway/tls-secret-1
+ privateKey: '[redacted]'
+ readyListener:
+ address: 0.0.0.0
+ ipFamily: IPv4
+ path: /ready
+ port: 19003
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-and-core-backendrefs.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-and-core-backendrefs.out.yaml
index cced11f524..2fbcf9e012 100644
--- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-and-core-backendrefs.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-and-core-backendrefs.out.yaml
@@ -98,7 +98,7 @@ httpRoutes:
kind: HTTPRoute
metadata:
creationTimestamp: null
- name: httproute-fqdn
+ name: httproute-static
namespace: default
spec:
parentRefs:
@@ -109,16 +109,16 @@ httpRoutes:
- backendRefs:
- group: gateway.envoyproxy.io
kind: Backend
- name: backend-fqdn
- - name: service-fqdn
+ name: backend-ip
+ - name: service-ip
port: 8080
- group: multicluster.x-k8s.io
kind: ServiceImport
- name: service-import-fqdn
+ name: service-import-ip
port: 8081
matches:
- path:
- value: /2
+ value: /1
status:
parents:
- conditions:
@@ -141,7 +141,7 @@ httpRoutes:
kind: HTTPRoute
metadata:
creationTimestamp: null
- name: httproute-static
+ name: httproute-fqdn
namespace: default
spec:
parentRefs:
@@ -152,16 +152,16 @@ httpRoutes:
- backendRefs:
- group: gateway.envoyproxy.io
kind: Backend
- name: backend-ip
- - name: service-ip
+ name: backend-fqdn
+ - name: service-fqdn
port: 8080
- group: multicluster.x-k8s.io
kind: ServiceImport
- name: service-import-ip
+ name: service-import-fqdn
port: 8081
matches:
- path:
- value: /1
+ value: /2
status:
parents:
- conditions:
@@ -240,109 +240,109 @@ xdsIR:
- destination:
metadata:
kind: HTTPRoute
- name: httproute-fqdn
+ name: httproute-static
namespace: default
- name: httproute/default/httproute-fqdn/rule/0
+ name: httproute/default/httproute-static/rule/0
settings:
- - addressType: FQDN
+ - addressType: IP
endpoints:
- - host: primary.foo.com
- port: 3000
+ - host: 1.1.1.1
+ port: 3001
metadata:
kind: Backend
- name: backend-fqdn
+ name: backend-ip
namespace: default
- name: httproute/default/httproute-fqdn/rule/0/backend/0
+ name: httproute/default/httproute-static/rule/0/backend/0
protocol: HTTP
weight: 1
- - addressType: FQDN
+ - addressType: IP
endpoints:
- - host: bar.foo
+ - host: 4.3.2.1
port: 8080
metadata:
kind: Service
- name: service-fqdn
+ name: service-ip
namespace: default
sectionName: "8080"
- name: httproute/default/httproute-fqdn/rule/0/backend/1
+ name: httproute/default/httproute-static/rule/0/backend/1
protocol: HTTP
weight: 1
- - addressType: FQDN
+ - addressType: IP
endpoints:
- - host: foo.bar
- port: 8080
+ - host: 1.2.3.4
+ port: 8081
metadata:
kind: ServiceImport
- name: service-import-fqdn
+ name: service-import-ip
namespace: default
sectionName: "8081"
- name: httproute/default/httproute-fqdn/rule/0/backend/2
+ name: httproute/default/httproute-static/rule/0/backend/2
protocol: HTTP
weight: 1
hostname: '*'
isHTTP2: false
metadata:
kind: HTTPRoute
- name: httproute-fqdn
+ name: httproute-static
namespace: default
- name: httproute/default/httproute-fqdn/rule/0/match/0/*
+ name: httproute/default/httproute-static/rule/0/match/0/*
pathMatch:
distinct: false
name: ""
- prefix: /2
+ prefix: /1
- destination:
metadata:
kind: HTTPRoute
- name: httproute-static
+ name: httproute-fqdn
namespace: default
- name: httproute/default/httproute-static/rule/0
+ name: httproute/default/httproute-fqdn/rule/0
settings:
- - addressType: IP
+ - addressType: FQDN
endpoints:
- - host: 1.1.1.1
- port: 3001
+ - host: primary.foo.com
+ port: 3000
metadata:
kind: Backend
- name: backend-ip
+ name: backend-fqdn
namespace: default
- name: httproute/default/httproute-static/rule/0/backend/0
+ name: httproute/default/httproute-fqdn/rule/0/backend/0
protocol: HTTP
weight: 1
- - addressType: IP
+ - addressType: FQDN
endpoints:
- - host: 4.3.2.1
+ - host: bar.foo
port: 8080
metadata:
kind: Service
- name: service-ip
+ name: service-fqdn
namespace: default
sectionName: "8080"
- name: httproute/default/httproute-static/rule/0/backend/1
+ name: httproute/default/httproute-fqdn/rule/0/backend/1
protocol: HTTP
weight: 1
- - addressType: IP
+ - addressType: FQDN
endpoints:
- - host: 1.2.3.4
- port: 8081
+ - host: foo.bar
+ port: 8080
metadata:
kind: ServiceImport
- name: service-import-ip
+ name: service-import-fqdn
namespace: default
sectionName: "8081"
- name: httproute/default/httproute-static/rule/0/backend/2
+ name: httproute/default/httproute-fqdn/rule/0/backend/2
protocol: HTTP
weight: 1
hostname: '*'
isHTTP2: false
metadata:
kind: HTTPRoute
- name: httproute-static
+ name: httproute-fqdn
namespace: default
- name: httproute/default/httproute-static/rule/0/match/0/*
+ name: httproute/default/httproute-fqdn/rule/0/match/0/*
pathMatch:
distinct: false
name: ""
- prefix: /1
+ prefix: /2
readyListener:
address: 0.0.0.0
ipFamily: IPv4
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref-mixed-address-type.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref-mixed-address-type.out.yaml
index 66b838b980..6cb8adf67e 100644
--- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref-mixed-address-type.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref-mixed-address-type.out.yaml
@@ -165,7 +165,7 @@ httpRoutes:
kind: HTTPRoute
metadata:
creationTimestamp: null
- name: httproute-2
+ name: httproute-3
namespace: default
spec:
parentRefs:
@@ -176,10 +176,10 @@ httpRoutes:
- backendRefs:
- group: gateway.envoyproxy.io
kind: Backend
- name: backend-mixed-uds-fqdn
+ name: backend-mixed-ip-fqdn
matches:
- path:
- value: /2
+ value: /3
status:
parents:
- conditions:
@@ -203,7 +203,7 @@ httpRoutes:
kind: HTTPRoute
metadata:
creationTimestamp: null
- name: httproute-3
+ name: httproute-2
namespace: default
spec:
parentRefs:
@@ -214,10 +214,10 @@ httpRoutes:
- backendRefs:
- group: gateway.envoyproxy.io
kind: Backend
- name: backend-mixed-ip-fqdn
+ name: backend-mixed-uds-fqdn
matches:
- path:
- value: /3
+ value: /2
status:
parents:
- conditions:
@@ -313,26 +313,26 @@ xdsIR:
isHTTP2: false
metadata:
kind: HTTPRoute
- name: httproute-2
+ name: httproute-3
namespace: default
- name: httproute/default/httproute-2/rule/0/match/0/*
+ name: httproute/default/httproute-3/rule/0/match/0/*
pathMatch:
distinct: false
name: ""
- prefix: /2
+ prefix: /3
- directResponse:
statusCode: 500
hostname: '*'
isHTTP2: false
metadata:
kind: HTTPRoute
- name: httproute-3
+ name: httproute-2
namespace: default
- name: httproute/default/httproute-3/rule/0/match/0/*
+ name: httproute/default/httproute-2/rule/0/match/0/*
pathMatch:
distinct: false
name: ""
- prefix: /3
+ prefix: /2
readyListener:
address: 0.0.0.0
ipFamily: IPv4
diff --git a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref.out.yaml b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref.out.yaml
index 29e6d10d4c..52a7abfc0b 100644
--- a/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-attaching-to-listener-with-backend-backendref.out.yaml
@@ -174,7 +174,7 @@ httpRoutes:
kind: HTTPRoute
metadata:
creationTimestamp: null
- name: httproute-2
+ name: httproute-3
namespace: default
spec:
parentRefs:
@@ -185,10 +185,10 @@ httpRoutes:
- backendRefs:
- group: gateway.envoyproxy.io
kind: Backend
- name: backend-ip
+ name: backend-fqdn
matches:
- path:
- value: /2
+ value: /3
status:
parents:
- conditions:
@@ -211,7 +211,7 @@ httpRoutes:
kind: HTTPRoute
metadata:
creationTimestamp: null
- name: httproute-3
+ name: httproute-2
namespace: default
spec:
parentRefs:
@@ -222,10 +222,10 @@ httpRoutes:
- backendRefs:
- group: gateway.envoyproxy.io
kind: Backend
- name: backend-fqdn
+ name: backend-ip
matches:
- path:
- value: /3
+ value: /2
status:
parents:
- conditions:
@@ -393,61 +393,61 @@ xdsIR:
- destination:
metadata:
kind: HTTPRoute
- name: httproute-2
+ name: httproute-3
namespace: default
- name: httproute/default/httproute-2/rule/0
+ name: httproute/default/httproute-3/rule/0
settings:
- - addressType: IP
+ - addressType: FQDN
endpoints:
- - host: 1.1.1.1
- port: 3001
+ - host: primary.foo.com
+ port: 3000
metadata:
kind: Backend
- name: backend-ip
+ name: backend-fqdn
namespace: default
- name: httproute/default/httproute-2/rule/0/backend/0
+ name: httproute/default/httproute-3/rule/0/backend/0
protocol: HTTP
weight: 1
hostname: '*'
isHTTP2: false
metadata:
kind: HTTPRoute
- name: httproute-2
+ name: httproute-3
namespace: default
- name: httproute/default/httproute-2/rule/0/match/0/*
+ name: httproute/default/httproute-3/rule/0/match/0/*
pathMatch:
distinct: false
name: ""
- prefix: /2
+ prefix: /3
- destination:
metadata:
kind: HTTPRoute
- name: httproute-3
+ name: httproute-2
namespace: default
- name: httproute/default/httproute-3/rule/0
+ name: httproute/default/httproute-2/rule/0
settings:
- - addressType: FQDN
+ - addressType: IP
endpoints:
- - host: primary.foo.com
- port: 3000
+ - host: 1.1.1.1
+ port: 3001
metadata:
kind: Backend
- name: backend-fqdn
+ name: backend-ip
namespace: default
- name: httproute/default/httproute-3/rule/0/backend/0
+ name: httproute/default/httproute-2/rule/0/backend/0
protocol: HTTP
weight: 1
hostname: '*'
isHTTP2: false
metadata:
kind: HTTPRoute
- name: httproute-3
+ name: httproute-2
namespace: default
- name: httproute/default/httproute-3/rule/0/match/0/*
+ name: httproute/default/httproute-2/rule/0/match/0/*
pathMatch:
distinct: false
name: ""
- prefix: /3
+ prefix: /2
- directResponse:
statusCode: 500
hostname: '*'
diff --git a/internal/gatewayapi/testdata/httproute-default-order-by-creation-date-and-route-name.out.yaml b/internal/gatewayapi/testdata/httproute-default-order-by-creation-date-and-route-name.out.yaml
index 9187db9c87..eebadea67a 100644
--- a/internal/gatewayapi/testdata/httproute-default-order-by-creation-date-and-route-name.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-default-order-by-creation-date-and-route-name.out.yaml
@@ -44,8 +44,8 @@ httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
- creationTimestamp: "2025-07-10T20:43:53Z"
- name: httproute-5
+ creationTimestamp: "2025-07-12T20:47:53Z"
+ name: httproute-default
namespace: default
spec:
hostnames:
@@ -61,14 +61,7 @@ httpRoutes:
matches:
- path:
type: PathPrefix
- value: /route5
- - backendRefs:
- - name: service-2
- port: 8080
- matches:
- - path:
- type: PathPrefix
- value: /123
+ value: /
status:
parents:
- conditions:
@@ -91,7 +84,7 @@ httpRoutes:
kind: HTTPRoute
metadata:
creationTimestamp: "2025-07-12T20:47:53Z"
- name: httproute-1
+ name: httproute-3
namespace: default
spec:
hostnames:
@@ -107,21 +100,7 @@ httpRoutes:
matches:
- path:
type: PathPrefix
- value: /route1
- - backendRefs:
- - name: service-2
- port: 8080
- matches:
- - path:
- type: PathPrefix
- value: /foobar
- - backendRefs:
- - name: service-3
- port: 8080
- matches:
- - path:
- type: PathPrefix
- value: /bar
+ value: /route3
status:
parents:
- conditions:
@@ -144,7 +123,7 @@ httpRoutes:
kind: HTTPRoute
metadata:
creationTimestamp: "2025-07-12T20:47:53Z"
- name: httproute-3
+ name: httproute-1
namespace: default
spec:
hostnames:
@@ -160,7 +139,21 @@ httpRoutes:
matches:
- path:
type: PathPrefix
- value: /route3
+ value: /route1
+ - backendRefs:
+ - name: service-2
+ port: 8080
+ matches:
+ - path:
+ type: PathPrefix
+ value: /foobar
+ - backendRefs:
+ - name: service-3
+ port: 8080
+ matches:
+ - path:
+ type: PathPrefix
+ value: /bar
status:
parents:
- conditions:
@@ -182,8 +175,8 @@ httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
- creationTimestamp: "2025-07-12T20:47:53Z"
- name: httproute-default
+ creationTimestamp: "2025-07-10T20:43:53Z"
+ name: httproute-5
namespace: default
spec:
hostnames:
@@ -199,7 +192,14 @@ httpRoutes:
matches:
- path:
type: PathPrefix
- value: /
+ value: /route5
+ - backendRefs:
+ - name: service-2
+ port: 8080
+ matches:
+ - path:
+ type: PathPrefix
+ value: /123
status:
parents:
- conditions:
@@ -370,9 +370,9 @@ xdsIR:
- destination:
metadata:
kind: HTTPRoute
- name: httproute-5
+ name: httproute-3
namespace: default
- name: httproute/default/httproute-5/rule/0
+ name: httproute/default/httproute-3/rule/0
settings:
- addressType: IP
endpoints:
@@ -382,20 +382,20 @@ xdsIR:
name: service-1
namespace: default
sectionName: "8080"
- name: httproute/default/httproute-5/rule/0/backend/0
+ name: httproute/default/httproute-3/rule/0/backend/0
protocol: HTTP
weight: 1
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
kind: HTTPRoute
- name: httproute-5
+ name: httproute-3
namespace: default
- name: httproute/default/httproute-5/rule/0/match/0/gateway_envoyproxy_io
+ name: httproute/default/httproute-3/rule/0/match/0/gateway_envoyproxy_io
pathMatch:
distinct: false
name: ""
- prefix: /route5
+ prefix: /route3
- destination:
metadata:
kind: HTTPRoute
@@ -457,9 +457,9 @@ xdsIR:
- destination:
metadata:
kind: HTTPRoute
- name: httproute-3
+ name: httproute-5
namespace: default
- name: httproute/default/httproute-3/rule/0
+ name: httproute/default/httproute-5/rule/0
settings:
- addressType: IP
endpoints:
@@ -469,20 +469,20 @@ xdsIR:
name: service-1
namespace: default
sectionName: "8080"
- name: httproute/default/httproute-3/rule/0/backend/0
+ name: httproute/default/httproute-5/rule/0/backend/0
protocol: HTTP
weight: 1
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
kind: HTTPRoute
- name: httproute-3
+ name: httproute-5
namespace: default
- name: httproute/default/httproute-3/rule/0/match/0/gateway_envoyproxy_io
+ name: httproute/default/httproute-5/rule/0/match/0/gateway_envoyproxy_io
pathMatch:
distinct: false
name: ""
- prefix: /route3
+ prefix: /route5
- destination:
metadata:
kind: HTTPRoute
@@ -546,61 +546,61 @@ xdsIR:
- destination:
metadata:
kind: HTTPRoute
- name: httproute-5
+ name: httproute-1
namespace: default
- name: httproute/default/httproute-5/rule/1
+ name: httproute/default/httproute-1/rule/2
settings:
- addressType: IP
endpoints:
- host: 7.7.7.7
port: 8080
metadata:
- name: service-2
+ name: service-3
namespace: default
sectionName: "8080"
- name: httproute/default/httproute-5/rule/1/backend/0
+ name: httproute/default/httproute-1/rule/2/backend/0
protocol: HTTP
weight: 1
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
kind: HTTPRoute
- name: httproute-5
+ name: httproute-1
namespace: default
- name: httproute/default/httproute-5/rule/1/match/0/gateway_envoyproxy_io
+ name: httproute/default/httproute-1/rule/2/match/0/gateway_envoyproxy_io
pathMatch:
distinct: false
name: ""
- prefix: /123
+ prefix: /bar
- destination:
metadata:
kind: HTTPRoute
- name: httproute-1
+ name: httproute-5
namespace: default
- name: httproute/default/httproute-1/rule/2
+ name: httproute/default/httproute-5/rule/1
settings:
- addressType: IP
endpoints:
- host: 7.7.7.7
port: 8080
metadata:
- name: service-3
+ name: service-2
namespace: default
sectionName: "8080"
- name: httproute/default/httproute-1/rule/2/backend/0
+ name: httproute/default/httproute-5/rule/1/backend/0
protocol: HTTP
weight: 1
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
kind: HTTPRoute
- name: httproute-1
+ name: httproute-5
namespace: default
- name: httproute/default/httproute-1/rule/2/match/0/gateway_envoyproxy_io
+ name: httproute/default/httproute-5/rule/1/match/0/gateway_envoyproxy_io
pathMatch:
distinct: false
name: ""
- prefix: /bar
+ prefix: /123
- destination:
metadata:
kind: HTTPRoute
diff --git a/internal/gatewayapi/testdata/httproute-order-by-creation-date.out.yaml b/internal/gatewayapi/testdata/httproute-order-by-creation-date.out.yaml
index 9d8b357c28..e56365b365 100644
--- a/internal/gatewayapi/testdata/httproute-order-by-creation-date.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-order-by-creation-date.out.yaml
@@ -44,9 +44,9 @@ httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
- creationTimestamp: "2025-04-04T20:47:53Z"
- name: httproute-4
- namespace: test-ns2
+ creationTimestamp: "2025-07-01T20:47:53Z"
+ name: httproute-3
+ namespace: default
spec:
hostnames:
- gateway.envoyproxy.io
@@ -56,12 +56,12 @@ httpRoutes:
sectionName: http
rules:
- backendRefs:
- - name: test-service
+ - name: service-1
port: 8080
matches:
- path:
type: PathPrefix
- value: /route4
+ value: /route3
status:
parents:
- conditions:
@@ -83,8 +83,8 @@ httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
- creationTimestamp: "2025-07-01T20:47:53Z"
- name: httproute-3
+ creationTimestamp: "2025-07-02T10:47:53Z"
+ name: httproute-1
namespace: default
spec:
hostnames:
@@ -100,7 +100,14 @@ httpRoutes:
matches:
- path:
type: PathPrefix
- value: /route3
+ value: /route1
+ - backendRefs:
+ - name: service-2
+ port: 8080
+ matches:
+ - path:
+ type: PathPrefix
+ value: /foobar
status:
parents:
- conditions:
@@ -122,9 +129,9 @@ httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
- creationTimestamp: "2025-07-02T10:47:53Z"
- name: httproute-1
- namespace: default
+ creationTimestamp: "2025-07-03T20:47:53Z"
+ name: httproute-2
+ namespace: test-ns
spec:
hostnames:
- gateway.envoyproxy.io
@@ -134,19 +141,12 @@ httpRoutes:
sectionName: http
rules:
- backendRefs:
- - name: service-1
- port: 8080
- matches:
- - path:
- type: PathPrefix
- value: /route1
- - backendRefs:
- - name: service-2
+ - name: test-service
port: 8080
matches:
- path:
type: PathPrefix
- value: /foobar
+ value: /route2
status:
parents:
- conditions:
@@ -168,9 +168,9 @@ httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
- creationTimestamp: "2025-07-03T20:47:53Z"
- name: httproute-2
- namespace: test-ns
+ creationTimestamp: "2025-04-04T20:47:53Z"
+ name: httproute-4
+ namespace: test-ns2
spec:
hostnames:
- gateway.envoyproxy.io
@@ -185,7 +185,7 @@ httpRoutes:
matches:
- path:
type: PathPrefix
- value: /route2
+ value: /route4
status:
parents:
- conditions:
@@ -261,36 +261,6 @@ xdsIR:
mergeSlashes: true
port: 10080
routes:
- - destination:
- metadata:
- kind: HTTPRoute
- name: httproute-4
- namespace: test-ns2
- name: httproute/test-ns2/httproute-4/rule/0
- settings:
- - addressType: IP
- endpoints:
- - host: 8.8.8.8
- port: 8080
- metadata:
- kind: Service
- name: test-service
- namespace: test-ns2
- sectionName: "8080"
- name: httproute/test-ns2/httproute-4/rule/0/backend/0
- protocol: HTTP
- weight: 1
- hostname: gateway.envoyproxy.io
- isHTTP2: false
- metadata:
- kind: HTTPRoute
- name: httproute-4
- namespace: test-ns2
- name: httproute/test-ns2/httproute-4/rule/0/match/0/gateway_envoyproxy_io
- pathMatch:
- distinct: false
- name: ""
- prefix: /route4
- destination:
metadata:
kind: HTTPRoute
@@ -408,6 +378,36 @@ xdsIR:
distinct: false
name: ""
prefix: /route2
+ - destination:
+ metadata:
+ kind: HTTPRoute
+ name: httproute-4
+ namespace: test-ns2
+ name: httproute/test-ns2/httproute-4/rule/0
+ settings:
+ - addressType: IP
+ endpoints:
+ - host: 8.8.8.8
+ port: 8080
+ metadata:
+ kind: Service
+ name: test-service
+ namespace: test-ns2
+ sectionName: "8080"
+ name: httproute/test-ns2/httproute-4/rule/0/backend/0
+ protocol: HTTP
+ weight: 1
+ hostname: gateway.envoyproxy.io
+ isHTTP2: false
+ metadata:
+ kind: HTTPRoute
+ name: httproute-4
+ namespace: test-ns2
+ name: httproute/test-ns2/httproute-4/rule/0/match/0/gateway_envoyproxy_io
+ pathMatch:
+ distinct: false
+ name: ""
+ prefix: /route4
readyListener:
address: 0.0.0.0
ipFamily: IPv4
diff --git a/internal/gatewayapi/testdata/httproute-with-direct-response.out.yaml b/internal/gatewayapi/testdata/httproute-with-direct-response.out.yaml
index c9e04c9364..cb5ce12761 100644
--- a/internal/gatewayapi/testdata/httproute-with-direct-response.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-direct-response.out.yaml
@@ -95,7 +95,7 @@ httpRoutes:
kind: HTTPRoute
metadata:
creationTimestamp: null
- name: direct-response-too-long
+ name: direct-response-with-value-not-found
namespace: default
spec:
parentRefs:
@@ -107,25 +107,24 @@ httpRoutes:
- extensionRef:
group: gateway.envoyproxy.io
kind: HTTPRouteFilter
- name: direct-response-too-long
+ name: direct-response-value-ref-not-found
type: ExtensionRef
matches:
- path:
type: PathPrefix
- value: /too-long
+ value: /value-ref-not-found
status:
parents:
- conditions:
- lastTransitionTime: null
- message: 'Invalid filter HTTPRouteFilter: response.body size 4097 greater
- than the max size 4096'
+ message: 'Unable to translate HTTPRouteFilter: default/direct-response-value-ref-not-found'
reason: UnsupportedValue
status: "False"
type: Accepted
- lastTransitionTime: null
- message: Resolved all the Object references for the Route
- reason: ResolvedRefs
- status: "True"
+ message: 'Unable to translate HTTPRouteFilter: default/direct-response-value-ref-not-found'
+ reason: BackendNotFound
+ status: "False"
type: ResolvedRefs
controllerName: gateway.envoyproxy.io/gatewayclass-controller
parentRef:
@@ -136,7 +135,7 @@ httpRoutes:
kind: HTTPRoute
metadata:
creationTimestamp: null
- name: direct-response-with-value-not-found
+ name: direct-response-too-long
namespace: default
spec:
parentRefs:
@@ -148,24 +147,25 @@ httpRoutes:
- extensionRef:
group: gateway.envoyproxy.io
kind: HTTPRouteFilter
- name: direct-response-value-ref-not-found
+ name: direct-response-too-long
type: ExtensionRef
matches:
- path:
type: PathPrefix
- value: /value-ref-not-found
+ value: /too-long
status:
parents:
- conditions:
- lastTransitionTime: null
- message: 'Unable to translate HTTPRouteFilter: default/direct-response-value-ref-not-found'
+ message: 'Invalid filter HTTPRouteFilter: response.body size 4097 greater
+ than the max size 4096'
reason: UnsupportedValue
status: "False"
type: Accepted
- lastTransitionTime: null
- message: 'Unable to translate HTTPRouteFilter: default/direct-response-value-ref-not-found'
- reason: BackendNotFound
- status: "False"
+ message: Resolved all the Object references for the Route
+ reason: ResolvedRefs
+ status: "True"
type: ResolvedRefs
controllerName: gateway.envoyproxy.io/gatewayclass-controller
parentRef:
diff --git a/internal/gatewayapi/testdata/httproute-with-multi-gateways-with-same-name.out.yaml b/internal/gatewayapi/testdata/httproute-with-multi-gateways-with-same-name.out.yaml
index e6a97841e4..c82e841f5d 100644
--- a/internal/gatewayapi/testdata/httproute-with-multi-gateways-with-same-name.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-multi-gateways-with-same-name.out.yaml
@@ -4,7 +4,7 @@ gateways:
metadata:
creationTimestamp: null
name: gateway-1
- namespace: default
+ namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
listeners:
@@ -16,7 +16,7 @@ gateways:
protocol: HTTP
status:
listeners:
- - attachedRoutes: 1
+ - attachedRoutes: 0
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
@@ -44,7 +44,7 @@ gateways:
metadata:
creationTimestamp: null
name: gateway-1
- namespace: envoy-gateway
+ namespace: default
spec:
gatewayClassName: envoy-gateway-class
listeners:
@@ -56,7 +56,7 @@ gateways:
protocol: HTTP
status:
listeners:
- - attachedRoutes: 0
+ - attachedRoutes: 1
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
diff --git a/internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter-invalid.out.yaml b/internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter-invalid.out.yaml
index daf5461c08..965549a901 100644
--- a/internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter-invalid.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-urlrewrite-hostname-filter-invalid.out.yaml
@@ -45,7 +45,7 @@ httpRoutes:
kind: HTTPRoute
metadata:
creationTimestamp: null
- name: httproute-header-and-backend-host-rewrites
+ name: httproute-invalid-header
namespace: default
spec:
hostnames:
@@ -62,21 +62,16 @@ httpRoutes:
- extensionRef:
group: gateway.envoyproxy.io
kind: HTTPRouteFilter
- name: valid-header
- type: ExtensionRef
- - extensionRef:
- group: gateway.envoyproxy.io
- kind: HTTPRouteFilter
- name: valid-header
+ name: invalid-header
type: ExtensionRef
matches:
- path:
- value: /header-and-backend
+ value: /invalid-header
status:
parents:
- conditions:
- lastTransitionTime: null
- message: Cannot configure multiple urlRewrite filters for a single HTTPRouteRule
+ message: Header must be set when rewrite path type is "Header"
reason: UnsupportedValue
status: "False"
type: Accepted
@@ -94,7 +89,7 @@ httpRoutes:
kind: HTTPRoute
metadata:
creationTimestamp: null
- name: httproute-invalid-header
+ name: httproute-multiple-host-rewrites-1
namespace: default
spec:
hostnames:
@@ -111,16 +106,19 @@ httpRoutes:
- extensionRef:
group: gateway.envoyproxy.io
kind: HTTPRouteFilter
- name: invalid-header
+ name: valid-header
type: ExtensionRef
+ - type: URLRewrite
+ urlRewrite:
+ hostname: rewrite.com
matches:
- path:
- value: /invalid-header
+ value: /ext-first
status:
parents:
- conditions:
- lastTransitionTime: null
- message: Header must be set when rewrite path type is "Header"
+ message: Cannot configure multiple urlRewrite filters for a single HTTPRouteRule
reason: UnsupportedValue
status: "False"
type: Accepted
@@ -138,7 +136,7 @@ httpRoutes:
kind: HTTPRoute
metadata:
creationTimestamp: null
- name: httproute-multiple-header-host-rewrites
+ name: httproute-multiple-path-rewrites-2
namespace: default
spec:
hostnames:
@@ -152,19 +150,17 @@ httpRoutes:
- name: service-1
port: 8080
filters:
+ - type: URLRewrite
+ urlRewrite:
+ hostname: rewrite.com
- extensionRef:
group: gateway.envoyproxy.io
kind: HTTPRouteFilter
name: valid-header
type: ExtensionRef
- - extensionRef:
- group: gateway.envoyproxy.io
- kind: HTTPRouteFilter
- name: valid-header-2
- type: ExtensionRef
matches:
- path:
- value: /two-headers
+ value: /inline-first
status:
parents:
- conditions:
@@ -204,16 +200,16 @@ httpRoutes:
- extensionRef:
group: gateway.envoyproxy.io
kind: HTTPRouteFilter
- name: valid-backend
+ name: valid-header
type: ExtensionRef
- extensionRef:
group: gateway.envoyproxy.io
kind: HTTPRouteFilter
- name: valid-backend-2
+ name: valid-header-2
type: ExtensionRef
matches:
- path:
- value: /two-backends
+ value: /two-headers
status:
parents:
- conditions:
@@ -236,7 +232,7 @@ httpRoutes:
kind: HTTPRoute
metadata:
creationTimestamp: null
- name: httproute-multiple-host-rewrites-1
+ name: httproute-multiple-header-host-rewrites
namespace: default
spec:
hostnames:
@@ -253,14 +249,16 @@ httpRoutes:
- extensionRef:
group: gateway.envoyproxy.io
kind: HTTPRouteFilter
- name: valid-header
+ name: valid-backend
+ type: ExtensionRef
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-backend-2
type: ExtensionRef
- - type: URLRewrite
- urlRewrite:
- hostname: rewrite.com
matches:
- path:
- value: /ext-first
+ value: /two-backends
status:
parents:
- conditions:
@@ -283,7 +281,7 @@ httpRoutes:
kind: HTTPRoute
metadata:
creationTimestamp: null
- name: httproute-multiple-path-rewrites-2
+ name: httproute-header-and-backend-host-rewrites
namespace: default
spec:
hostnames:
@@ -297,9 +295,11 @@ httpRoutes:
- name: service-1
port: 8080
filters:
- - type: URLRewrite
- urlRewrite:
- hostname: rewrite.com
+ - extensionRef:
+ group: gateway.envoyproxy.io
+ kind: HTTPRouteFilter
+ name: valid-header
+ type: ExtensionRef
- extensionRef:
group: gateway.envoyproxy.io
kind: HTTPRouteFilter
@@ -307,7 +307,7 @@ httpRoutes:
type: ExtensionRef
matches:
- path:
- value: /inline-first
+ value: /header-and-backend
status:
parents:
- conditions:
diff --git a/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml b/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml
index 572fb5b701..202571c4c7 100644
--- a/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml
+++ b/internal/gatewayapi/testdata/merge-with-isolated-policies-2.out.yaml
@@ -441,7 +441,7 @@ securityPolicies:
exposeHeaders:
- x-header-7
- x-header-8
- maxAge: 33m20s
+ maxAge: 2000s
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
@@ -480,7 +480,7 @@ securityPolicies:
exposeHeaders:
- x-header-7
- x-header-8
- maxAge: 33m20s
+ maxAge: 2000s
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
diff --git a/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml b/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml
index 6625c69cd2..442b0e5ad1 100644
--- a/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml
+++ b/internal/gatewayapi/testdata/merge-with-isolated-policies.out.yaml
@@ -272,7 +272,7 @@ securityPolicies:
exposeHeaders:
- x-header-7
- x-header-8
- maxAge: 33m20s
+ maxAge: 2000s
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
diff --git a/internal/gatewayapi/testdata/securitypolicy-invalid-cross-ns-ref.out.yaml b/internal/gatewayapi/testdata/securitypolicy-invalid-cross-ns-ref.out.yaml
index e07797a05a..3e0841057b 100644
--- a/internal/gatewayapi/testdata/securitypolicy-invalid-cross-ns-ref.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-invalid-cross-ns-ref.out.yaml
@@ -81,7 +81,7 @@ securityPolicies:
exposeHeaders:
- x-header-3
- x-header-4
- maxAge: 16m40s
+ maxAge: 1000s
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
diff --git a/internal/gatewayapi/testdata/securitypolicy-override-replace.out.yaml b/internal/gatewayapi/testdata/securitypolicy-override-replace.out.yaml
index a8d6184b01..d857ab1953 100644
--- a/internal/gatewayapi/testdata/securitypolicy-override-replace.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-override-replace.out.yaml
@@ -375,7 +375,7 @@ securityPolicies:
exposeHeaders:
- x-header-7
- x-header-8
- maxAge: 33m20s
+ maxAge: 2000s
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
@@ -405,7 +405,7 @@ securityPolicies:
cors:
allowOrigins:
- http://*.example.com
- maxAge: 16m40s
+ maxAge: 1000s
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
@@ -516,7 +516,7 @@ securityPolicies:
exposeHeaders:
- x-header-3
- x-header-4
- maxAge: 16m40s
+ maxAge: 1000s
jwt:
providers:
- audiences:
diff --git a/internal/gatewayapi/testdata/securitypolicy-status-conditions-truncated.out.yaml b/internal/gatewayapi/testdata/securitypolicy-status-conditions-truncated.out.yaml
index 944b880545..fe6b02f656 100644
--- a/internal/gatewayapi/testdata/securitypolicy-status-conditions-truncated.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-status-conditions-truncated.out.yaml
@@ -43,7 +43,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-10
+ name: gateway-2
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -83,7 +83,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-11
+ name: gateway-3
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -123,7 +123,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-12
+ name: gateway-4
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -163,7 +163,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-13
+ name: gateway-5
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -203,7 +203,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-14
+ name: gateway-6
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -243,7 +243,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-15
+ name: gateway-7
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -283,7 +283,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-16
+ name: gateway-8
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -323,7 +323,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-17
+ name: gateway-9
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -363,7 +363,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-18
+ name: gateway-10
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -403,7 +403,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-2
+ name: gateway-11
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -443,7 +443,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-3
+ name: gateway-12
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -483,7 +483,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-4
+ name: gateway-13
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -523,7 +523,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-5
+ name: gateway-14
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -563,7 +563,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-6
+ name: gateway-15
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -603,7 +603,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-7
+ name: gateway-16
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -643,7 +643,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-8
+ name: gateway-17
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -683,7 +683,7 @@ gateways:
kind: Gateway
metadata:
creationTimestamp: null
- name: gateway-9
+ name: gateway-18
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
@@ -1970,13 +1970,13 @@ securityPolicies:
kind: SecurityPolicy
metadata:
creationTimestamp: null
- name: target-httproute-with-accepted-truncated-ancestors
+ name: target-httproute-with-attachment-conflict-truncated-ancestors
namespace: envoy-gateway
spec:
- targetRef:
- group: gateway.networking.k8s.io
+ targetRefs:
+ - group: gateway.networking.k8s.io
kind: HTTPRoute
- name: httproute-1
+ name: httproute-2
status:
ancestors:
- ancestorRef:
@@ -1986,9 +1986,10 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
+ already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -1998,9 +1999,10 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
+ already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2010,9 +2012,10 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
+ already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2022,9 +2025,10 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
+ already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2034,9 +2038,10 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
+ already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2046,9 +2051,10 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
+ already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2058,9 +2064,10 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
+ already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2070,9 +2077,10 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
+ already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2082,9 +2090,10 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
+ already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2094,9 +2103,10 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
+ already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2106,9 +2116,10 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
+ already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2118,9 +2129,10 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
+ already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2130,9 +2142,10 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
+ already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2142,9 +2155,10 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
+ already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2154,9 +2168,10 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
+ already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2166,9 +2181,10 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
+ already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
- lastTransitionTime: null
message: 'Ancestors have been aggregated because the number of policy ancestors
@@ -2181,13 +2197,13 @@ securityPolicies:
kind: SecurityPolicy
metadata:
creationTimestamp: null
- name: target-httproute-with-attachment-conflict-truncated-ancestors
+ name: target-httproute-with-accepted-truncated-ancestors
namespace: envoy-gateway
spec:
- targetRefs:
- - group: gateway.networking.k8s.io
+ targetRef:
+ group: gateway.networking.k8s.io
kind: HTTPRoute
- name: httproute-2
+ name: httproute-1
status:
ancestors:
- ancestorRef:
@@ -2197,10 +2213,9 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
- already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2210,10 +2225,9 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
- already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2223,10 +2237,9 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
- already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2236,10 +2249,9 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
- already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2249,10 +2261,9 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
- already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2262,10 +2273,9 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
- already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2275,10 +2285,9 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
- already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2288,10 +2297,9 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
- already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2301,10 +2309,9 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
- already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2314,10 +2321,9 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
- already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2327,10 +2333,9 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
- already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2340,10 +2345,9 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
- already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2353,10 +2357,9 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
- already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2366,10 +2369,9 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
- already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2379,10 +2381,9 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
- already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- ancestorRef:
@@ -2392,10 +2393,9 @@ securityPolicies:
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-2, another SecurityPolicy has
- already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
- lastTransitionTime: null
message: 'Ancestors have been aggregated because the number of policy ancestors
diff --git a/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml b/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml
index 3f11863d24..d4e2a2af4a 100644
--- a/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-status-conditions.out.yaml
@@ -255,9 +255,13 @@ securityPolicies:
kind: SecurityPolicy
metadata:
creationTimestamp: null
- name: also-target-httproute-in-gateway-1
+ name: target-httproute-in-gateway-1
namespace: envoy-gateway
spec:
+ cors:
+ allowOrigins:
+ - http://*.example.com
+ maxAge: 1000s
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
@@ -280,59 +284,55 @@ securityPolicies:
kind: SecurityPolicy
metadata:
creationTimestamp: null
- name: target-grpcroute-in-gateway-2
+ name: also-target-httproute-in-gateway-1
namespace: envoy-gateway
spec:
- cors:
- allowOrigins:
- - http://*.example.com
- maxAge: 16m40s
targetRef:
group: gateway.networking.k8s.io
- kind: GRPCRoute
- name: grpcroute-1
+ kind: HTTPRoute
+ name: httproute-1
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-2
+ name: gateway-1
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: Unable to target HTTPRoute httproute-1, another SecurityPolicy has
+ already attached to it
+ reason: Conflicted
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
creationTimestamp: null
- name: target-httproute-in-gateway-1
+ name: target-grpcroute-in-gateway-2
namespace: envoy-gateway
spec:
cors:
allowOrigins:
- http://*.example.com
- maxAge: 16m40s
+ maxAge: 1000s
targetRef:
group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: httproute-1
+ kind: GRPCRoute
+ name: grpcroute-1
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-1
+ name: gateway-2
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
- message: Unable to target HTTPRoute httproute-1, another SecurityPolicy has
- already attached to it
- reason: Conflicted
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- apiVersion: gateway.envoyproxy.io/v1alpha1
@@ -453,7 +453,13 @@ xdsIR:
distinct: false
name: ""
prefix: /
- security: {}
+ security:
+ cors:
+ allowOrigins:
+ - distinct: false
+ name: ""
+ safeRegex: http://.*\.example\.com
+ maxAge: 16m40s
readyListener:
address: 0.0.0.0
ipFamily: IPv4
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-cors-targetrefs.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-cors-targetrefs.out.yaml
index 4c53e97e35..d78d560705 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-cors-targetrefs.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-cors-targetrefs.out.yaml
@@ -313,7 +313,7 @@ securityPolicies:
exposeHeaders:
- x-header-3
- x-header-4
- maxAge: 16m40s
+ maxAge: 1000s
targetRefs:
- group: gateway.networking.k8s.io
kind: Gateway
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-cors.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-cors.out.yaml
index 12847b3c3c..c5d5cd3c31 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-cors.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-cors.out.yaml
@@ -309,7 +309,7 @@ securityPolicies:
exposeHeaders:
- x-header-7
- x-header-8
- maxAge: 33m20s
+ maxAge: 2000s
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
@@ -348,7 +348,7 @@ securityPolicies:
exposeHeaders:
- x-header-7
- x-header-8
- maxAge: 33m20s
+ maxAge: 2000s
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
@@ -389,7 +389,7 @@ securityPolicies:
exposeHeaders:
- x-header-3
- x-header-4
- maxAge: 16m40s
+ maxAge: 1000s
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-jwt-local-jwks.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-jwt-local-jwks.out.yaml
index 4ea604b714..254581dace 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-jwt-local-jwks.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-jwt-local-jwks.out.yaml
@@ -296,7 +296,7 @@ securityPolicies:
kind: SecurityPolicy
metadata:
creationTimestamp: null
- name: securitypolicy-with-jwt-local-jwks-valueref-missing-configmap
+ name: securitypolicy-with-jwt-local-jwks-valueref-missing-key
namespace: default
spec:
jwt:
@@ -307,12 +307,12 @@ securityPolicies:
valueRef:
group: ""
kind: ConfigMap
- name: example3-jwks
+ name: example2-jwks
name: example2
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
- name: httproute-4
+ name: httproute-3
status:
ancestors:
- ancestorRef:
@@ -323,16 +323,16 @@ securityPolicies:
sectionName: http
conditions:
- lastTransitionTime: null
- message: 'JWT: local JWKS ConfigMap default/example3-jwks not found.'
- reason: Invalid
- status: "False"
+ message: Policy has been accepted.
+ reason: Accepted
+ status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
creationTimestamp: null
- name: securitypolicy-with-jwt-local-jwks-valueref-missing-key
+ name: securitypolicy-with-jwt-local-jwks-valueref-missing-configmap
namespace: default
spec:
jwt:
@@ -343,12 +343,12 @@ securityPolicies:
valueRef:
group: ""
kind: ConfigMap
- name: example2-jwks
+ name: example3-jwks
name: example2
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
- name: httproute-3
+ name: httproute-4
status:
ancestors:
- ancestorRef:
@@ -359,9 +359,9 @@ securityPolicies:
sectionName: http
conditions:
- lastTransitionTime: null
- message: Policy has been accepted.
- reason: Accepted
- status: "True"
+ message: 'JWT: local JWKS ConfigMap default/example3-jwks not found.'
+ reason: Invalid
+ status: "False"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
xdsIR:
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc-backendcluster.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc-backendcluster.out.yaml
index 60064b6edb..7fb6248bda 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-oidc-backendcluster.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc-backendcluster.out.yaml
@@ -164,8 +164,8 @@ securityPolicies:
group: null
kind: null
name: client1-secret
- defaultRefreshTokenTTL: 24h0m0s
- defaultTokenTTL: 30m0s
+ defaultRefreshTokenTTL: 24h
+ defaultTokenTTL: 30m
forwardAccessToken: true
logoutPath: /bar/logout
provider:
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc-backendrefs.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc-backendrefs.out.yaml
index 7b875d44f8..883cf1da6c 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-oidc-backendrefs.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc-backendrefs.out.yaml
@@ -150,8 +150,8 @@ securityPolicies:
group: null
kind: null
name: client1-secret
- defaultRefreshTokenTTL: 24h0m0s
- defaultTokenTTL: 30m0s
+ defaultRefreshTokenTTL: 24h
+ defaultTokenTTL: 30m
forwardAccessToken: true
logoutPath: /bar/logout
provider:
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc-invalid-secretref.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc-invalid-secretref.out.yaml
index 7f0d4acc75..49e5b480de 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-oidc-invalid-secretref.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc-invalid-secretref.out.yaml
@@ -182,16 +182,16 @@ securityPolicies:
kind: SecurityPolicy
metadata:
creationTimestamp: null
- name: policy-no-client-secret-key
+ name: policy-non-exist-secretRef
namespace: default
+ uid: b8284d0f-de82-4c65-b204-96a0d3f258a1
spec:
oidc:
clientID: client1.apps.googleusercontent.com
clientSecret:
group: null
kind: null
- name: client3-secret
- namespace: default
+ name: client1-secret
provider:
authorizationEndpoint: https://accounts.google.com/o/oauth2/v2/auth
issuer: https://accounts.google.com
@@ -199,17 +199,17 @@ securityPolicies:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-3
+ name: gateway-1
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-3
+ name: gateway-1
namespace: default
conditions:
- lastTransitionTime: null
- message: 'OIDC: client secret not found in secret default/client3-secret.'
+ message: 'OIDC: secret default/client1-secret does not exist.'
reason: Invalid
status: "False"
type: Accepted
@@ -255,16 +255,16 @@ securityPolicies:
kind: SecurityPolicy
metadata:
creationTimestamp: null
- name: policy-non-exist-secretRef
+ name: policy-no-client-secret-key
namespace: default
- uid: b8284d0f-de82-4c65-b204-96a0d3f258a1
spec:
oidc:
clientID: client1.apps.googleusercontent.com
clientSecret:
group: null
kind: null
- name: client1-secret
+ name: client3-secret
+ namespace: default
provider:
authorizationEndpoint: https://accounts.google.com/o/oauth2/v2/auth
issuer: https://accounts.google.com
@@ -272,17 +272,17 @@ securityPolicies:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-1
+ name: gateway-3
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
- name: gateway-1
+ name: gateway-3
namespace: default
conditions:
- lastTransitionTime: null
- message: 'OIDC: secret default/client1-secret does not exist.'
+ message: 'OIDC: client secret not found in secret default/client3-secret.'
reason: Invalid
status: "False"
type: Accepted
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc-serviceimport.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc-serviceimport.out.yaml
index d1ff5a259a..6b7d8f33cf 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-oidc-serviceimport.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc-serviceimport.out.yaml
@@ -146,8 +146,8 @@ securityPolicies:
group: null
kind: null
name: client1-secret
- defaultRefreshTokenTTL: 24h0m0s
- defaultTokenTTL: 30m0s
+ defaultRefreshTokenTTL: 24h
+ defaultTokenTTL: 30m
forwardAccessToken: true
logoutPath: /bar/logout
provider:
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml
index 9f3d3627a9..1c603f2981 100644
--- a/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml
+++ b/internal/gatewayapi/testdata/securitypolicy-with-oidc.out.yaml
@@ -155,8 +155,8 @@ securityPolicies:
kind: null
name: client2-secret
cookieDomain: example.com
- defaultRefreshTokenTTL: 48h0m0s
- defaultTokenTTL: 1h0m0s
+ defaultRefreshTokenTTL: 48h
+ defaultTokenTTL: 1h
forwardAccessToken: true
logoutPath: /foo/logout
provider:
@@ -204,8 +204,8 @@ securityPolicies:
group: null
kind: null
name: client1-secret
- defaultRefreshTokenTTL: 24h0m0s
- defaultTokenTTL: 30m0s
+ defaultRefreshTokenTTL: 24h
+ defaultTokenTTL: 30m
forwardAccessToken: true
logoutPath: /bar/logout
provider:
diff --git a/internal/gatewayapi/tls.go b/internal/gatewayapi/tls.go
index 74857b15ae..9d7d864fce 100644
--- a/internal/gatewayapi/tls.go
+++ b/internal/gatewayapi/tls.go
@@ -12,17 +12,16 @@ import (
"time"
corev1 "k8s.io/api/core/v1"
- gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
)
// validateTLSSecretData ensures the cert and key provided in a secret
// is not malformed and can be properly parsed
-func validateTLSSecretsData(secrets []*corev1.Secret, host *gwapiv1.Hostname) ([]*x509.Certificate, error) {
+func validateTLSSecretsData(secrets []*corev1.Secret) ([]*x509.Certificate, error) {
var publicKeyAlgorithm string
var certs []*x509.Certificate
var parseErr error
- pkaSecretSet := make(map[string][]string)
+ pkaSecretSet := make(map[string]string)
for _, secret := range secrets {
certData := secret.Data[corev1.TLSCertKey]
@@ -48,18 +47,29 @@ func validateTLSSecretsData(secrets []*corev1.Secret, host *gwapiv1.Hostname) ([
return nil, fmt.Errorf("%s/%s must contain valid %s and %s, unable to decode pem data in %s", secret.Namespace, secret.Name, corev1.TLSCertKey, corev1.TLSPrivateKeyKey, corev1.TLSPrivateKeyKey)
}
- matchedFQDN, err := verifyHostname(cert, host)
- if err != nil {
- return nil, fmt.Errorf("%s/%s must contain valid %s and %s, hostname %s does not match Common Name or DNS Names in the certificate %s", secret.Namespace, secret.Name, corev1.TLSCertKey, corev1.TLSPrivateKeyKey, string(*host), corev1.TLSCertKey)
+ // SNI and SAN/Cert Domain mismatch is allowed
+ // Consider converting this into a warning once
+ // https://github.com/envoyproxy/gateway/issues/6717 is in
+
+ // Extract certificate domains (SANs or CN) for uniqueness checking
+ var certDomains []string
+ if len(cert.DNSNames) > 0 {
+ certDomains = cert.DNSNames
+ } else if cert.Subject.CommonName != "" {
+ certDomains = []string{cert.Subject.CommonName}
}
- pkaSecretKey := fmt.Sprintf("%s/%s", publicKeyAlgorithm, matchedFQDN)
- // Check whether the public key algorithm and matched certificate FQDN in the referenced secrets are unique.
- if matchedFQDN, ok := pkaSecretSet[pkaSecretKey]; ok {
- return nil, fmt.Errorf("%s/%s public key algorithm must be unique, matched certificate FQDN %s has a conflicting algorithm [%s]",
- secret.Namespace, secret.Name, matchedFQDN, publicKeyAlgorithm)
+ // Check uniqueness for each domain in the certificate with this algorithm
+ for _, domain := range certDomains {
+ pkaSecretKey := fmt.Sprintf("%s/%s", publicKeyAlgorithm, domain)
+
+ // Check whether the public key algorithm and certificate domain are unique
+ if _, ok := pkaSecretSet[pkaSecretKey]; ok {
+ return nil, fmt.Errorf("%s/%s public key algorithm must be unique, certificate domain %s has a conflicting algorithm [%s]",
+ secret.Namespace, secret.Name, domain, publicKeyAlgorithm)
+ }
+ pkaSecretSet[pkaSecretKey] = domain
}
- pkaSecretSet[pkaSecretKey] = matchedFQDN
switch keyBlock.Type {
case "PRIVATE KEY":
@@ -86,26 +96,6 @@ func validateTLSSecretsData(secrets []*corev1.Secret, host *gwapiv1.Hostname) ([
return certs, parseErr
}
-// verifyHostname checks if the listener Hostname matches any domain in the certificate, returns a list of matched hosts.
-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, &listenerContext)
- } else {
- matchedHosts = computeHosts([]string{cert.Subject.CommonName}, &listenerContext)
- }
-
- if len(matchedHosts) > 0 {
- return matchedHosts, nil
- }
-
- return nil, x509.HostnameError{Certificate: cert, Host: string(*host)}
-}
-
func validateCertificate(data []byte) error {
block, _ := pem.Decode(data)
if block == nil {
diff --git a/internal/gatewayapi/tls_test.go b/internal/gatewayapi/tls_test.go
index 07e68e5f5a..901bbe2685 100644
--- a/internal/gatewayapi/tls_test.go
+++ b/internal/gatewayapi/tls_test.go
@@ -149,20 +149,13 @@ func TestValidateTLSSecretsData(t *testing.T) {
Domain: "*",
ExpectedErr: errors.New("test/secret must contain valid tls.crt and tls.key, FOO key format found in tls.key, supported formats are PKCS1, PKCS8 or EC"),
},
- {
- Name: "invalid-domain-cert",
- CertFile: "rsa-cert-san.pem",
- KeyFile: "rsa-pkcs8-san.key",
- Domain: "*.example.com",
- ExpectedErr: errors.New("test/secret must contain valid tls.crt and tls.key, hostname *.example.com does not match Common Name or DNS Names in the certificate tls.crt"),
- },
}
for _, tc := range testCases {
t.Run(tc.Name, func(t *testing.T) {
secrets := createTestSecrets(t, tc.CertFile, tc.KeyFile)
require.NotNil(t, secrets)
- _, err := validateTLSSecretsData(secrets, &tc.Domain)
+ _, err := validateTLSSecretsData(secrets)
if tc.ExpectedErr == nil {
require.NoError(t, err)
} else {
diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go
index c17c84460b..f80fdc8c57 100644
--- a/internal/gatewayapi/translator.go
+++ b/internal/gatewayapi/translator.go
@@ -7,8 +7,6 @@ package gatewayapi
import (
"errors"
- "fmt"
- "sort"
"golang.org/x/exp/maps"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@@ -169,19 +167,7 @@ func (t *Translator) Translate(resources *resource.Resources) (*TranslateResult,
// Get Gateways belonging to our GatewayClass.
acceptedGateways, failedGateways := t.GetRelevantGateways(resources)
- // Sort gateways based on timestamp.
- // Initially, acceptedGateways sort by creation timestamp
- // or sort alphabetically by “{namespace}/{name}” if multiple gateways share same timestamp.
- sort.Slice(acceptedGateways, func(i, j int) bool {
- if acceptedGateways[i].CreationTimestamp.Equal(&(acceptedGateways[j].CreationTimestamp)) {
- gatewayKeyI := fmt.Sprintf("%s/%s", acceptedGateways[i].Namespace, acceptedGateways[i].Name)
- gatewayKeyJ := fmt.Sprintf("%s/%s", acceptedGateways[j].Namespace, acceptedGateways[j].Name)
- return gatewayKeyI < gatewayKeyJ
- }
- // Not identical CreationTimestamps
-
- return acceptedGateways[i].CreationTimestamp.Before(&(acceptedGateways[j].CreationTimestamp))
- })
+ // Gateways are already sorted by the provider layer
// Build IR maps.
xdsIR, infraIR := t.InitIRs(acceptedGateways)
@@ -294,7 +280,7 @@ func (t *Translator) GetRelevantGateways(resources *resource.Resources) (
if gateway.Spec.GatewayClassName == t.GatewayClassName {
gc := &GatewayContext{
- Gateway: gateway.DeepCopy(),
+ Gateway: gateway,
}
// Gateways that are not accepted by the controller because they reference an invalid EnvoyProxy.
diff --git a/internal/gatewayapi/translator_test.go b/internal/gatewayapi/translator_test.go
index 11b2a73312..40293977c8 100644
--- a/internal/gatewayapi/translator_test.go
+++ b/internal/gatewayapi/translator_test.go
@@ -373,8 +373,15 @@ func TestTranslate(t *testing.T) {
} else {
for _, g := range resources.Gateways {
gSvc := svc
- // Matches proxy.ExpectedResourceHashedName()
- gSvc.Name = fmt.Sprintf("%s-%s", config.EnvoyPrefix, utils.GetHashedName(fmt.Sprintf("%s/%s", g.Namespace, g.Name), 48))
+ if gatewayNamespaceMode {
+ // In gateway namespace mode, the service name is the same as the gateway name
+ // and the namespace is the gateway namespace.
+ gSvc.Name = g.Name
+ gSvc.Namespace = g.Namespace
+ } else {
+ gSvc.Name = fmt.Sprintf("%s-%s", config.EnvoyPrefix, utils.GetHashedName(fmt.Sprintf("%s/%s", g.Namespace, g.Name), 48))
+ }
+
gSvc.Labels[OwningGatewayNameLabel] = g.Name
gSvc.Labels[OwningGatewayNamespaceLabel] = g.Namespace
gEndPtSlice := endPtSlice
@@ -416,7 +423,6 @@ func TestTranslate(t *testing.T) {
opts := []cmp.Option{
cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime"),
- cmpopts.IgnoreFields(resource.Resources{}, "serviceMap"),
cmp.Transformer("ClearXdsEqual", xdsWithoutEqual),
cmpopts.IgnoreTypes(ir.PrivateBytes{}),
cmpopts.EquateEmpty(),
@@ -695,7 +701,6 @@ func TestTranslateWithExtensionKinds(t *testing.T) {
opts := []cmp.Option{
cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime"),
- cmpopts.IgnoreFields(resource.Resources{}, "serviceMap"),
}
require.Empty(t, cmp.Diff(want, got, opts...))
})
diff --git a/internal/gatewayapi/validate.go b/internal/gatewayapi/validate.go
index c0f324dc9f..76f30f76a0 100644
--- a/internal/gatewayapi/validate.go
+++ b/internal/gatewayapi/validate.go
@@ -460,7 +460,7 @@ func (t *Translator) validateTerminateModeAndGetTLSSecrets(listener *ListenerCon
secrets = append(secrets, secret)
}
- certs, err := validateTLSSecretsData(secrets, listener.Hostname)
+ certs, err := validateTLSSecretsData(secrets)
if err != nil {
status.SetGatewayListenerStatusCondition(listener.gateway.Gateway,
listener.listenerStatusIdx,
diff --git a/internal/infrastructure/common/proxy_args.go b/internal/infrastructure/common/proxy_args.go
index 4d6a67892d..5d2fa5f22d 100644
--- a/internal/infrastructure/common/proxy_args.go
+++ b/internal/infrastructure/common/proxy_args.go
@@ -7,6 +7,7 @@ package common
import (
"fmt"
+ "time"
"k8s.io/utils/ptr"
@@ -84,7 +85,11 @@ func BuildProxyArgs(
// Default drain timeout.
drainTimeout := 60.0
if shutdownConfig != nil && shutdownConfig.DrainTimeout != nil {
- drainTimeout = shutdownConfig.DrainTimeout.Seconds()
+ d, err := time.ParseDuration(string(*shutdownConfig.DrainTimeout))
+ if err != nil {
+ return nil, err
+ }
+ drainTimeout = d.Seconds()
}
args = append(args, fmt.Sprintf("--drain-time-s %.0f", drainTimeout))
diff --git a/internal/infrastructure/host/proxy_infra.go b/internal/infrastructure/host/proxy_infra.go
index 229fdcd1c3..690ffc1736 100644
--- a/internal/infrastructure/host/proxy_infra.go
+++ b/internal/infrastructure/host/proxy_infra.go
@@ -73,7 +73,9 @@ func (i *Infra) CreateOrUpdateProxyInfra(ctx context.Context, infra *ir.Infra) e
AdminServerPort: ptr.To(int32(0)),
StatsServerPort: ptr.To(int32(0)),
}
-
+ if i.EnvoyGateway != nil {
+ bootstrapConfigOptions.TopologyInjectorDisabled = i.EnvoyGateway.TopologyInjectorDisabled()
+ }
args, err := common.BuildProxyArgs(proxyInfra, proxyConfig.Spec.Shutdown, bootstrapConfigOptions, proxyName, false)
if err != nil {
return err
diff --git a/internal/infrastructure/kubernetes/proxy/resource.go b/internal/infrastructure/kubernetes/proxy/resource.go
index a332387742..285b5bb5d1 100644
--- a/internal/infrastructure/kubernetes/proxy/resource.go
+++ b/internal/infrastructure/kubernetes/proxy/resource.go
@@ -8,6 +8,7 @@ package proxy
import (
"fmt"
"path/filepath"
+ "time"
"github.com/containers/image/v5/docker/reference"
corev1 "k8s.io/api/core/v1"
@@ -76,6 +77,7 @@ func enablePrometheus(infra *ir.ProxyInfra) bool {
func expectedProxyContainers(infra *ir.ProxyInfra,
containerSpec *egv1a1.KubernetesContainerSpec,
shutdownConfig *egv1a1.ShutdownConfig, shutdownManager *egv1a1.ShutdownManager,
+ topologyInjectorDisabled bool,
controllerNamespace, dnsDomain string, gatewayNamespaceMode bool,
) ([]corev1.Container, error) {
ports := make([]corev1.ContainerPort, 0, 2)
@@ -100,6 +102,7 @@ func expectedProxyContainers(infra *ir.ProxyInfra,
}
maxHeapSizeBytes := calculateMaxHeapSizeBytes(containerSpec.Resources)
+
// Get the default Bootstrap
bootstrapConfigOptions := &bootstrap.RenderBootstrapConfigOptions{
ProxyMetrics: proxyMetrics,
@@ -107,8 +110,9 @@ func expectedProxyContainers(infra *ir.ProxyInfra,
Certificate: filepath.Join("/sds", common.SdsCertFilename),
TrustedCA: filepath.Join("/sds", common.SdsCAFilename),
},
- MaxHeapSizeBytes: maxHeapSizeBytes,
- XdsServerHost: ptr.To(fmt.Sprintf("%s.%s.svc.%s.", config.EnvoyGatewayServiceName, controllerNamespace, dnsDomain)),
+ MaxHeapSizeBytes: maxHeapSizeBytes,
+ XdsServerHost: ptr.To(fmt.Sprintf("%s.%s.svc.%s.", config.EnvoyGatewayServiceName, controllerNamespace, dnsDomain)),
+ TopologyInjectorDisabled: topologyInjectorDisabled,
}
args, err := common.BuildProxyArgs(infra, shutdownConfig, bootstrapConfigOptions, fmt.Sprintf("$(%s)", envoyPodEnvVar), gatewayNamespaceMode)
@@ -257,7 +261,11 @@ func expectedShutdownManagerImage(shutdownManager *egv1a1.ShutdownManager) strin
func expectedShutdownManagerArgs(cfg *egv1a1.ShutdownConfig) []string {
args := []string{"envoy", "shutdown-manager"}
if cfg != nil && cfg.DrainTimeout != nil {
- args = append(args, fmt.Sprintf("--ready-timeout=%.0fs", cfg.DrainTimeout.Seconds()+10))
+ d, err := time.ParseDuration(string(*cfg.DrainTimeout))
+ if err != nil {
+ return nil
+ }
+ args = append(args, fmt.Sprintf("--ready-timeout=%.0fs", d.Seconds()+10))
}
return args
}
@@ -270,11 +278,19 @@ func expectedShutdownPreStopCommand(cfg *egv1a1.ShutdownConfig) []string {
}
if cfg.DrainTimeout != nil {
- command = append(command, fmt.Sprintf("--drain-timeout=%.0fs", cfg.DrainTimeout.Seconds()))
+ d, err := time.ParseDuration(string(*cfg.DrainTimeout))
+ if err != nil {
+ return nil
+ }
+ command = append(command, fmt.Sprintf("--drain-timeout=%.0fs", d.Seconds()))
}
if cfg.MinDrainDuration != nil {
- command = append(command, fmt.Sprintf("--min-drain-duration=%.0fs", cfg.MinDrainDuration.Seconds()))
+ d, err := time.ParseDuration(string(*cfg.MinDrainDuration))
+ if err != nil {
+ return nil
+ }
+ command = append(command, fmt.Sprintf("--min-drain-duration=%.0fs", d.Seconds()))
}
return command
diff --git a/internal/infrastructure/kubernetes/proxy/resource_provider.go b/internal/infrastructure/kubernetes/proxy/resource_provider.go
index 61adadaff5..e4fada02a7 100644
--- a/internal/infrastructure/kubernetes/proxy/resource_provider.go
+++ b/internal/infrastructure/kubernetes/proxy/resource_provider.go
@@ -9,6 +9,7 @@ import (
"context"
"fmt"
"strconv"
+ "time"
"golang.org/x/exp/maps"
appsv1 "k8s.io/api/apps/v1"
@@ -61,6 +62,8 @@ type ResourceRender struct {
ShutdownManager *egv1a1.ShutdownManager
+ TopologyInjectorDisabled bool
+
GatewayNamespaceMode bool
// ownerReferenceUID store the uid of its owner reference. Key is the kind of owner resource.
@@ -85,13 +88,14 @@ func NewResourceRender(ctx context.Context, kubeInfra KubernetesInfraProvider, i
}
return &ResourceRender{
- envoyNamespace: kubeInfra.GetResourceNamespace(infra),
- controllerNamespace: kubeInfra.GetControllerNamespace(),
- DNSDomain: kubeInfra.GetDNSDomain(),
- infra: infra.GetProxyInfra(),
- ShutdownManager: kubeInfra.GetEnvoyGateway().GetEnvoyGatewayProvider().GetEnvoyGatewayKubeProvider().ShutdownManager,
- GatewayNamespaceMode: kubeInfra.GetEnvoyGateway().GatewayNamespaceMode(),
- ownerReferenceUID: ownerReference,
+ envoyNamespace: kubeInfra.GetResourceNamespace(infra),
+ controllerNamespace: kubeInfra.GetControllerNamespace(),
+ DNSDomain: kubeInfra.GetDNSDomain(),
+ infra: infra.GetProxyInfra(),
+ ShutdownManager: kubeInfra.GetEnvoyGateway().GetEnvoyGatewayProvider().GetEnvoyGatewayKubeProvider().ShutdownManager,
+ TopologyInjectorDisabled: kubeInfra.GetEnvoyGateway().TopologyInjectorDisabled(),
+ GatewayNamespaceMode: kubeInfra.GetEnvoyGateway().GatewayNamespaceMode(),
+ ownerReferenceUID: ownerReference,
}, nil
}
@@ -365,7 +369,7 @@ func (r *ResourceRender) Deployment() (*appsv1.Deployment, error) {
}
// Get expected bootstrap configurations rendered ProxyContainers
- containers, err := expectedProxyContainers(r.infra, deploymentConfig.Container, proxyConfig.Spec.Shutdown, r.ShutdownManager, r.ControllerNamespace(), r.DNSDomain, r.GatewayNamespaceMode)
+ containers, err := expectedProxyContainers(r.infra, deploymentConfig.Container, proxyConfig.Spec.Shutdown, r.ShutdownManager, r.TopologyInjectorDisabled, r.ControllerNamespace(), r.DNSDomain, r.GatewayNamespaceMode)
if err != nil {
return nil, err
}
@@ -455,7 +459,7 @@ func (r *ResourceRender) DaemonSet() (*appsv1.DaemonSet, error) {
}
// Get expected bootstrap configurations rendered ProxyContainers
- containers, err := expectedProxyContainers(r.infra, daemonSetConfig.Container, proxyConfig.Spec.Shutdown, r.ShutdownManager, r.ControllerNamespace(), r.DNSDomain, r.GatewayNamespaceMode)
+ containers, err := expectedProxyContainers(r.infra, daemonSetConfig.Container, proxyConfig.Spec.Shutdown, r.ShutdownManager, r.TopologyInjectorDisabled, r.ControllerNamespace(), r.DNSDomain, r.GatewayNamespaceMode)
if err != nil {
return nil, err
}
@@ -631,7 +635,11 @@ func (r *ResourceRender) HorizontalPodAutoscaler() (*autoscalingv2.HorizontalPod
func expectedTerminationGracePeriodSeconds(cfg *egv1a1.ShutdownConfig) *int64 {
s := 360 // default
if cfg != nil && cfg.DrainTimeout != nil {
- s = int(cfg.DrainTimeout.Seconds() + 300) // 5 minutes longer than drain timeout
+ d, err := time.ParseDuration(string(*cfg.DrainTimeout))
+ if err != nil {
+ return nil
+ }
+ s = int(d.Seconds() + 300) // 5 minutes longer than drain timeout
}
return ptr.To(int64(s))
}
diff --git a/internal/infrastructure/kubernetes/proxy/resource_provider_test.go b/internal/infrastructure/kubernetes/proxy/resource_provider_test.go
index def8a1893c..8e78d1a603 100644
--- a/internal/infrastructure/kubernetes/proxy/resource_provider_test.go
+++ b/internal/infrastructure/kubernetes/proxy/resource_provider_test.go
@@ -11,7 +11,6 @@ import (
"os"
"sort"
"testing"
- "time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -25,6 +24,7 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/utils/ptr"
+ gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
"sigs.k8s.io/yaml"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
@@ -293,12 +293,8 @@ func TestDeployment(t *testing.T) {
},
},
shutdown: &egv1a1.ShutdownConfig{
- DrainTimeout: &metav1.Duration{
- Duration: 30 * time.Second,
- },
- MinDrainDuration: &metav1.Duration{
- Duration: 15 * time.Second,
- },
+ DrainTimeout: ptr.To(gwapiv1.Duration("30s")),
+ MinDrainDuration: ptr.To(gwapiv1.Duration("15s")),
},
shutdownManager: &egv1a1.ShutdownManager{
Image: ptr.To("privaterepo/envoyproxy/gateway-dev:v1.2.3"),
@@ -865,12 +861,8 @@ func TestDaemonSet(t *testing.T) {
},
},
shutdown: &egv1a1.ShutdownConfig{
- DrainTimeout: &metav1.Duration{
- Duration: 30 * time.Second,
- },
- MinDrainDuration: &metav1.Duration{
- Duration: 15 * time.Second,
- },
+ DrainTimeout: ptr.To(gwapiv1.Duration("30s")),
+ MinDrainDuration: ptr.To(gwapiv1.Duration("15s")),
},
},
{
diff --git a/internal/infrastructure/kubernetes/proxy/resource_test.go b/internal/infrastructure/kubernetes/proxy/resource_test.go
index d295944fa6..b41319b845 100644
--- a/internal/infrastructure/kubernetes/proxy/resource_test.go
+++ b/internal/infrastructure/kubernetes/proxy/resource_test.go
@@ -65,7 +65,7 @@ func TestExpectedShutdownManagerSecurityContext(t *testing.T) {
func TestResolveProxyImage(t *testing.T) {
defaultImage := egv1a1.DefaultEnvoyProxyImage
- defaultTag := "distroless-dev"
+ defaultTag := "distroless-v1.35.3"
tests := []struct {
name string
@@ -105,6 +105,13 @@ func TestResolveProxyImage(t *testing.T) {
},
expected: fmt.Sprintf("envoyproxy/envoy:%s", defaultTag),
},
+ {
+ name: "imageRepository with port",
+ container: &egv1a1.KubernetesContainerSpec{
+ ImageRepository: ptr.To("docker.io:443/envoyproxy/envoy"),
+ },
+ expected: fmt.Sprintf("docker.io:443/envoyproxy/envoy:%s", defaultTag),
+ },
}
for _, tc := range tests {
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml
index eb41b2ac52..e8a1b97af0 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml
@@ -66,7 +66,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml
index 9ceff33391..9eb02bdc01 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml
@@ -216,7 +216,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml
index f85db5c4eb..93d0548573 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml
@@ -165,7 +165,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/gateway-namespace-mode.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/gateway-namespace-mode.yaml
index d9346bcd61..071f611023 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/gateway-namespace-mode.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/gateway-namespace-mode.yaml
@@ -232,7 +232,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
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 e28c71c4ca..b31a0d0259 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
@@ -225,7 +225,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-prometheus-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-prometheus-annotations.yaml
index 8f5c5f4327..ec84353271 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-prometheus-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-prometheus-annotations.yaml
@@ -216,7 +216,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml
index 9351f583cc..920a972c03 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml
@@ -216,7 +216,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml
index 1eee8dc87c..c432def036 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml
@@ -216,7 +216,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml
index 666ed147ab..166f6513c0 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml
@@ -221,7 +221,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml
index cee00906f7..9e7a450d2e 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml
@@ -67,7 +67,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
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 6135e25dd5..e9db1a206b 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml
@@ -218,7 +218,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
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 b887d5fb64..d4e5844ed9 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
@@ -216,7 +216,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml
index 14290dbbb4..8c826e941f 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml
@@ -216,7 +216,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
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 de5ca90fb1..9f3c3f1812 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml
@@ -216,7 +216,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
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 7213fe6b39..df8b09354c 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
@@ -216,7 +216,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml
index e22ab6b7b1..ca4f9f9749 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml
@@ -70,7 +70,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml
index e66ddbdb54..a043496eee 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml
@@ -70,7 +70,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom-sa.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom-sa.yaml
index 2f68d8a3d5..f831a6dabf 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom-sa.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom-sa.yaml
@@ -236,7 +236,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml
index 1834f939e3..9064ead61f 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml
@@ -220,7 +220,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml
index e235f3cf47..14e4411b09 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml
@@ -169,7 +169,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml
index 27bfa0b977..6ae5a7c9cf 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml
@@ -221,7 +221,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/gateway-namespace-mode.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/gateway-namespace-mode.yaml
index ac2ca511a5..e12c631b6a 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/gateway-namespace-mode.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/gateway-namespace-mode.yaml
@@ -236,7 +236,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml
index d69c8416b9..e8a33e1284 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml
@@ -221,7 +221,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
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 3c608b33b1..f5607106fb 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
@@ -229,7 +229,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-prometheus-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-prometheus-annotations.yaml
index ad1e5e20e3..f1c2ab39cc 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-prometheus-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-prometheus-annotations.yaml
@@ -222,7 +222,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml
index ed09ddfb5e..e5d4928496 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml
@@ -220,7 +220,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml
index 8460a89583..2550eb3c2a 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml
@@ -220,7 +220,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml
index 40df545f02..bc81390488 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml
@@ -225,7 +225,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml
index 21798b3bb9..188edf8429 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml
@@ -71,7 +71,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
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 feb0438970..0aeeb34db8 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
@@ -220,7 +220,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
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 a65f48a328..3a3fd7b623 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml
@@ -222,7 +222,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
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 f05baa94e9..b62bc9a719 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
@@ -220,7 +220,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml
index 17496a2190..d3d7ddc691 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml
@@ -220,7 +220,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
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 acd2582f0f..435c3ba36e 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml
@@ -220,7 +220,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
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 9e40147e04..7b09eaf492 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
@@ -220,7 +220,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/gateway-namespace-mode/deployment.yaml b/internal/infrastructure/kubernetes/proxy/testdata/gateway-namespace-mode/deployment.yaml
index 5d2fa9b9da..50f765a5c4 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/gateway-namespace-mode/deployment.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/gateway-namespace-mode/deployment.yaml
@@ -236,7 +236,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
@@ -650,7 +650,7 @@ spec:
fieldRef:
apiVersion: v1
fieldPath: metadata.annotations['topology.kubernetes.io/zone']
- image: docker.io/envoyproxy/envoy:distroless-dev
+ image: docker.io/envoyproxy/envoy:distroless-v1.35.3
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml
index 1cc68f00a8..4195412cd0 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml
@@ -86,7 +86,7 @@ spec:
value: :19001
- name: PROMETHEUS_MAPPER_YAML
value: /etc/statsd-exporter/conf.yaml
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml
index 502a0dd3be..ea3ec6397e 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml
@@ -76,7 +76,7 @@ spec:
value: tcp
- name: REDIS_URL
value: redis.redis.svc:6379
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
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 4dd13119b3..ddc1004f1e 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml
@@ -101,7 +101,7 @@ spec:
value: "0.6"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: http://trace-collector.envoy-gateway-system.svc.cluster.local:4317
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml
index 1fa61480b2..ce64570326 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml
@@ -101,7 +101,7 @@ spec:
value: "1.0"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: http://trace-collector.envoy-gateway-system.svc.cluster.local:4318
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-annotations.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-annotations.yaml
index 1d7ac9f095..149a680873 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-annotations.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-annotations.yaml
@@ -88,7 +88,7 @@ spec:
value: :19001
- name: PROMETHEUS_MAPPER_YAML
value: /etc/statsd-exporter/conf.yaml
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-labels.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-labels.yaml
index 135ec2691a..5bad4e555f 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-labels.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/merge-labels.yaml
@@ -88,7 +88,7 @@ spec:
value: :19001
- name: PROMETHEUS_MAPPER_YAML
value: /etc/statsd-exporter/conf.yaml
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment-containers.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment-containers.yaml
index 462437dfca..42131d4071 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment-containers.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment-containers.yaml
@@ -88,7 +88,7 @@ spec:
value: :19001
- name: PROMETHEUS_MAPPER_YAML
value: /etc/statsd-exporter/conf.yaml
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml
index 18ff23d255..7f11e98bab 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml
@@ -86,7 +86,7 @@ spec:
value: :19001
- name: PROMETHEUS_MAPPER_YAML
value: /etc/statsd-exporter/conf.yaml
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
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 9e08bb7adf..ce24035e57 100644
--- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-node-selector.yaml
+++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-node-selector.yaml
@@ -86,7 +86,7 @@ spec:
value: :19001
- name: PROMETHEUS_MAPPER_YAML
value: /etc/statsd-exporter/conf.yaml
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
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 13357946e2..1daa909a0b 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
@@ -86,7 +86,7 @@ spec:
value: :19001
- name: PROMETHEUS_MAPPER_YAML
value: /etc/statsd-exporter/conf.yaml
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
diff --git a/internal/ir/infra.go b/internal/ir/infra.go
index f4c95bd335..ef793f399e 100644
--- a/internal/ir/infra.go
+++ b/internal/ir/infra.go
@@ -6,13 +6,10 @@
package ir
import (
- "cmp"
"encoding/json"
"errors"
"fmt"
- "reflect"
- "golang.org/x/exp/slices"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"sigs.k8s.io/yaml"
@@ -249,20 +246,3 @@ func (p *ProxyInfra) ObjectName() string {
}
return "envoy-" + p.Name
}
-
-// Equal implements the Comparable interface used by watchable.DeepEqual to skip unnecessary updates.
-func (p *ProxyInfra) Equal(y *ProxyInfra) bool {
- // Deep copy to avoid modifying the original ordering.
- p = p.DeepCopy()
- p.sort()
- y = y.DeepCopy()
- y.sort()
- return reflect.DeepEqual(p, y)
-}
-
-// sort ensures the listeners are in a consistent order.
-func (p *ProxyInfra) sort() {
- slices.SortFunc(p.Listeners, func(l1, l2 *ProxyListener) int {
- return cmp.Compare(l1.Name, l2.Name)
- })
-}
diff --git a/internal/ir/infra_test.go b/internal/ir/infra_test.go
index 92781e06c6..ce5fd4d577 100644
--- a/internal/ir/infra_test.go
+++ b/internal/ir/infra_test.go
@@ -8,7 +8,6 @@ package ir
import (
"testing"
- "github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
)
@@ -208,35 +207,3 @@ func TestObjectName(t *testing.T) {
})
}
}
-
-func TestEqualInfra(t *testing.T) {
- tests := []struct {
- desc string
- a *ProxyInfra
- b *ProxyInfra
- equal bool
- }{
- {
- desc: "out of order proxy listeners are equal",
- a: &ProxyInfra{
- Listeners: []*ProxyListener{
- {Name: "listener-1"},
- {Name: "listener-2"},
- },
- },
- b: &ProxyInfra{
- Listeners: []*ProxyListener{
- {Name: "listener-2"},
- {Name: "listener-1"},
- },
- },
- equal: true,
- },
- }
-
- for _, tc := range tests {
- t.Run(tc.desc, func(t *testing.T) {
- require.Equal(t, tc.equal, cmp.Equal(tc.a, tc.b))
- })
- }
-}
diff --git a/internal/ir/xds.go b/internal/ir/xds.go
index 477d8896c4..b7514a535d 100644
--- a/internal/ir/xds.go
+++ b/internal/ir/xds.go
@@ -6,7 +6,6 @@
package ir
import (
- "cmp"
"crypto/tls"
"crypto/x509"
"encoding"
@@ -15,10 +14,8 @@ import (
"fmt"
"net/http"
"net/netip"
- "reflect"
"time"
- "golang.org/x/exp/slices"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -132,6 +129,11 @@ func (p *PrivateBytes) UnmarshalJSON(data []byte) error {
return err
}
+// MetaV1DurationPtr converts a time.Duration to a *metav1.Duration
+func MetaV1DurationPtr(d time.Duration) *metav1.Duration {
+ return &metav1.Duration{Duration: d}
+}
+
// Xds holds the intermediate representation of a Gateway and is
// used by the xDS Translator to convert it into xDS resources.
// +k8s:deepcopy-gen=true
@@ -160,34 +162,6 @@ type Xds struct {
ExtensionServerPolicies []*UnstructuredRef `json:"extensionServerPolicies,omitempty" yaml:"extensionServerPolicies,omitempty"`
}
-// Equal implements the Comparable interface used by watchable.DeepEqual to skip unnecessary updates.
-func (x *Xds) Equal(y *Xds) bool {
- // Deep copy to avoid modifying the original ordering.
- x = x.DeepCopy()
- x.sort()
- y = y.DeepCopy()
- y.sort()
- return reflect.DeepEqual(x, y)
-}
-
-// sort ensures the listeners are in a consistent order.
-func (x *Xds) sort() {
- slices.SortFunc(x.HTTP, func(l1, l2 *HTTPListener) int {
- return cmp.Compare(l1.Name, l2.Name)
- })
- for _, l := range x.HTTP {
- slices.SortFunc(l.Routes, func(r1, r2 *HTTPRoute) int {
- return cmp.Compare(r1.Name, r2.Name)
- })
- }
- slices.SortFunc(x.TCP, func(l1, l2 *TCPListener) int {
- return cmp.Compare(l1.Name, l2.Name)
- })
- slices.SortFunc(x.UDP, func(l1, l2 *UDPListener) int {
- return cmp.Compare(l1.Name, l2.Name)
- })
-}
-
// Validate the fields within the Xds structure.
func (x *Xds) Validate() error {
var errs error
diff --git a/internal/ir/xds_test.go b/internal/ir/xds_test.go
index 6cebc99dc6..073529e33f 100644
--- a/internal/ir/xds_test.go
+++ b/internal/ir/xds_test.go
@@ -11,11 +11,9 @@ import (
"testing"
"time"
- "github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
@@ -756,80 +754,6 @@ func TestValidateTLSListenerConfig(t *testing.T) {
}
}
-func TestEqualXds(t *testing.T) {
- tests := []struct {
- desc string
- a *Xds
- b *Xds
- equal bool
- }{
- {
- desc: "out of order tcp listeners are equal",
- a: &Xds{
- TCP: []*TCPListener{
- {CoreListenerDetails: CoreListenerDetails{Name: "listener-1"}},
- {CoreListenerDetails: CoreListenerDetails{Name: "listener-2"}},
- },
- },
- b: &Xds{
- TCP: []*TCPListener{
- {CoreListenerDetails: CoreListenerDetails{Name: "listener-2"}},
- {CoreListenerDetails: CoreListenerDetails{Name: "listener-1"}},
- },
- },
- equal: true,
- },
- {
- desc: "out of order http routes are equal",
- a: &Xds{
- HTTP: []*HTTPListener{
- {
- CoreListenerDetails: CoreListenerDetails{Name: "listener-1"},
- Routes: []*HTTPRoute{
- {Name: "route-1"},
- {Name: "route-2"},
- },
- },
- },
- },
- b: &Xds{
- HTTP: []*HTTPListener{
- {
- CoreListenerDetails: CoreListenerDetails{Name: "listener-1"},
- Routes: []*HTTPRoute{
- {Name: "route-2"},
- {Name: "route-1"},
- },
- },
- },
- },
- equal: true,
- },
- {
- desc: "out of order udp listeners are equal",
- a: &Xds{
- UDP: []*UDPListener{
- {CoreListenerDetails: CoreListenerDetails{Name: "listener-1"}},
- {CoreListenerDetails: CoreListenerDetails{Name: "listener-2"}},
- },
- },
- b: &Xds{
- UDP: []*UDPListener{
- {CoreListenerDetails: CoreListenerDetails{Name: "listener-2"}},
- {CoreListenerDetails: CoreListenerDetails{Name: "listener-1"}},
- },
- },
- equal: true,
- },
- }
-
- for _, tc := range tests {
- t.Run(tc.desc, func(t *testing.T) {
- require.Equal(t, tc.equal, cmp.Equal(tc.a, tc.b))
- })
- }
-}
-
func TestValidateUDPListener(t *testing.T) {
tests := []struct {
name string
@@ -1533,8 +1457,8 @@ func TestValidateHealthCheck(t *testing.T) {
name: "invalid timeout",
input: HealthCheck{
&ActiveHealthCheck{
- Timeout: &metav1.Duration{Duration: time.Duration(0)},
- Interval: &metav1.Duration{Duration: time.Second},
+ Timeout: MetaV1DurationPtr(time.Duration(0)),
+ Interval: MetaV1DurationPtr(time.Second),
UnhealthyThreshold: ptr.To[uint32](3),
HealthyThreshold: ptr.To[uint32](3),
HTTP: &HTTPHealthChecker{
@@ -1551,8 +1475,8 @@ func TestValidateHealthCheck(t *testing.T) {
name: "invalid panic threshold",
input: HealthCheck{
&ActiveHealthCheck{
- Timeout: &metav1.Duration{Duration: time.Duration(3)},
- Interval: &metav1.Duration{Duration: time.Second},
+ Timeout: MetaV1DurationPtr(time.Duration(3)),
+ Interval: MetaV1DurationPtr(time.Second),
UnhealthyThreshold: ptr.To[uint32](3),
HealthyThreshold: ptr.To[uint32](3),
HTTP: &HTTPHealthChecker{
@@ -1569,8 +1493,8 @@ func TestValidateHealthCheck(t *testing.T) {
name: "invalid interval",
input: HealthCheck{
&ActiveHealthCheck{
- Timeout: &metav1.Duration{Duration: time.Second},
- Interval: &metav1.Duration{Duration: time.Duration(0)},
+ Timeout: MetaV1DurationPtr(time.Second),
+ Interval: MetaV1DurationPtr(time.Duration(0)),
UnhealthyThreshold: ptr.To[uint32](3),
HealthyThreshold: ptr.To[uint32](3),
HTTP: &HTTPHealthChecker{
@@ -1589,8 +1513,8 @@ func TestValidateHealthCheck(t *testing.T) {
name: "invalid initial jitter",
input: HealthCheck{
&ActiveHealthCheck{
- Timeout: &metav1.Duration{Duration: time.Second},
- Interval: &metav1.Duration{Duration: time.Second},
+ Timeout: MetaV1DurationPtr(time.Second),
+ Interval: MetaV1DurationPtr(time.Second),
InitialJitter: ptr.To(gwapiv1.Duration("-1s")),
UnhealthyThreshold: ptr.To[uint32](3),
HealthyThreshold: ptr.To[uint32](3),
@@ -1610,8 +1534,8 @@ func TestValidateHealthCheck(t *testing.T) {
name: "invalid unhealthy threshold",
input: HealthCheck{
&ActiveHealthCheck{
- Timeout: &metav1.Duration{Duration: time.Second},
- Interval: &metav1.Duration{Duration: time.Second},
+ Timeout: MetaV1DurationPtr(time.Second),
+ Interval: MetaV1DurationPtr(time.Second),
UnhealthyThreshold: ptr.To[uint32](0),
HealthyThreshold: ptr.To[uint32](3),
HTTP: &HTTPHealthChecker{
@@ -1630,8 +1554,8 @@ func TestValidateHealthCheck(t *testing.T) {
name: "invalid healthy threshold",
input: HealthCheck{
&ActiveHealthCheck{
- Timeout: &metav1.Duration{Duration: time.Second},
- Interval: &metav1.Duration{Duration: time.Second},
+ Timeout: MetaV1DurationPtr(time.Second),
+ Interval: MetaV1DurationPtr(time.Second),
UnhealthyThreshold: ptr.To[uint32](3),
HealthyThreshold: ptr.To[uint32](0),
HTTP: &HTTPHealthChecker{
@@ -1650,8 +1574,8 @@ func TestValidateHealthCheck(t *testing.T) {
name: "http-health-check: invalid host",
input: HealthCheck{
&ActiveHealthCheck{
- Timeout: &metav1.Duration{Duration: time.Second},
- Interval: &metav1.Duration{Duration: time.Second},
+ Timeout: MetaV1DurationPtr(time.Second),
+ Interval: MetaV1DurationPtr(time.Second),
UnhealthyThreshold: ptr.To[uint32](3),
HealthyThreshold: ptr.To[uint32](3),
HTTP: &HTTPHealthChecker{
@@ -1669,8 +1593,8 @@ func TestValidateHealthCheck(t *testing.T) {
name: "http-health-check: invalid path",
input: HealthCheck{
&ActiveHealthCheck{
- Timeout: &metav1.Duration{Duration: time.Second},
- Interval: &metav1.Duration{Duration: time.Second},
+ Timeout: MetaV1DurationPtr(time.Second),
+ Interval: MetaV1DurationPtr(time.Second),
UnhealthyThreshold: ptr.To[uint32](3),
HealthyThreshold: ptr.To[uint32](3),
HTTP: &HTTPHealthChecker{
@@ -1689,8 +1613,8 @@ func TestValidateHealthCheck(t *testing.T) {
name: "http-health-check: invalid method",
input: HealthCheck{
&ActiveHealthCheck{
- Timeout: &metav1.Duration{Duration: time.Second},
- Interval: &metav1.Duration{Duration: time.Second},
+ Timeout: MetaV1DurationPtr(time.Second),
+ Interval: MetaV1DurationPtr(time.Second),
UnhealthyThreshold: ptr.To(uint32(3)),
HealthyThreshold: ptr.To(uint32(3)),
HTTP: &HTTPHealthChecker{
@@ -1709,8 +1633,8 @@ func TestValidateHealthCheck(t *testing.T) {
name: "http-health-check: invalid expected-statuses",
input: HealthCheck{
&ActiveHealthCheck{
- Timeout: &metav1.Duration{Duration: time.Second},
- Interval: &metav1.Duration{Duration: time.Second},
+ Timeout: MetaV1DurationPtr(time.Second),
+ Interval: MetaV1DurationPtr(time.Second),
UnhealthyThreshold: ptr.To(uint32(3)),
HealthyThreshold: ptr.To(uint32(3)),
HTTP: &HTTPHealthChecker{
@@ -1729,8 +1653,8 @@ func TestValidateHealthCheck(t *testing.T) {
name: "http-health-check: invalid range",
input: HealthCheck{
&ActiveHealthCheck{
- Timeout: &metav1.Duration{Duration: time.Second},
- Interval: &metav1.Duration{Duration: time.Second},
+ Timeout: MetaV1DurationPtr(time.Second),
+ Interval: MetaV1DurationPtr(time.Second),
UnhealthyThreshold: ptr.To(uint32(3)),
HealthyThreshold: ptr.To(uint32(3)),
HTTP: &HTTPHealthChecker{
@@ -1749,8 +1673,8 @@ func TestValidateHealthCheck(t *testing.T) {
name: "http-health-check: invalid expected-responses",
input: HealthCheck{
&ActiveHealthCheck{
- Timeout: &metav1.Duration{Duration: time.Second},
- Interval: &metav1.Duration{Duration: time.Second},
+ Timeout: MetaV1DurationPtr(time.Second),
+ Interval: MetaV1DurationPtr(time.Second),
UnhealthyThreshold: ptr.To(uint32(3)),
HealthyThreshold: ptr.To(uint32(3)),
HTTP: &HTTPHealthChecker{
@@ -1773,8 +1697,8 @@ func TestValidateHealthCheck(t *testing.T) {
name: "tcp-health-check: invalid send payload",
input: HealthCheck{
&ActiveHealthCheck{
- Timeout: &metav1.Duration{Duration: time.Second},
- Interval: &metav1.Duration{Duration: time.Second},
+ Timeout: MetaV1DurationPtr(time.Second),
+ Interval: MetaV1DurationPtr(time.Second),
UnhealthyThreshold: ptr.To(uint32(3)),
HealthyThreshold: ptr.To(uint32(3)),
TCP: &TCPHealthChecker{
@@ -1796,8 +1720,8 @@ func TestValidateHealthCheck(t *testing.T) {
name: "tcp-health-check: invalid receive payload",
input: HealthCheck{
&ActiveHealthCheck{
- Timeout: &metav1.Duration{Duration: time.Second},
- Interval: &metav1.Duration{Duration: time.Second},
+ Timeout: MetaV1DurationPtr(time.Second),
+ Interval: MetaV1DurationPtr(time.Second),
UnhealthyThreshold: ptr.To(uint32(3)),
HealthyThreshold: ptr.To(uint32(3)),
TCP: &TCPHealthChecker{
@@ -1820,8 +1744,8 @@ func TestValidateHealthCheck(t *testing.T) {
input: HealthCheck{
&ActiveHealthCheck{},
&OutlierDetection{
- Interval: &metav1.Duration{Duration: time.Duration(0)},
- BaseEjectionTime: &metav1.Duration{Duration: time.Second},
+ Interval: MetaV1DurationPtr(time.Duration(0)),
+ BaseEjectionTime: MetaV1DurationPtr(time.Second),
},
ptr.To[uint32](10),
},
@@ -1832,8 +1756,8 @@ func TestValidateHealthCheck(t *testing.T) {
input: HealthCheck{
&ActiveHealthCheck{},
&OutlierDetection{
- Interval: &metav1.Duration{Duration: time.Second},
- BaseEjectionTime: &metav1.Duration{Duration: time.Duration(0)},
+ Interval: MetaV1DurationPtr(time.Second),
+ BaseEjectionTime: MetaV1DurationPtr(time.Duration(0)),
},
ptr.To[uint32](10),
},
diff --git a/internal/message/types.go b/internal/message/types.go
index 5ef6acf216..10c5b55726 100644
--- a/internal/message/types.go
+++ b/internal/message/types.go
@@ -15,7 +15,6 @@ import (
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/ir"
- xdstypes "github.com/envoyproxy/gateway/internal/xds/types"
)
// ProviderResources message
@@ -133,16 +132,9 @@ type InfraIR struct {
watchable.Map[string, *ir.Infra]
}
-// Xds message
-type Xds struct {
- watchable.Map[string, *xdstypes.ResourceVersionTable]
-}
-
type MessageName string
const (
- // XDSMessageName is a message containing xds translated from xds-ir
- XDSMessageName MessageName = "xds"
// XDSIRMessageName is a message containing xds-ir translated from provider-resources
XDSIRMessageName MessageName = "xds-ir"
// InfraIRMessageName is a message containing infra-ir translated from provider-resources
diff --git a/internal/message/watchutil.go b/internal/message/watchutil.go
index 32a9f61d3a..645bd7eb0b 100644
--- a/internal/message/watchutil.go
+++ b/internal/message/watchutil.go
@@ -28,6 +28,10 @@ type Metadata struct {
Message MessageName
}
+func PublishMetric(meta Metadata) {
+ watchablePublishTotal.WithSuccess(meta.LabelValues()...).Increment()
+}
+
func (m Metadata) LabelValues() []metrics.LabelValue {
labels := make([]metrics.LabelValue, 0, 2)
if m.Runner != "" {
@@ -100,8 +104,3 @@ func HandleSubscription[K comparable, V any](
}
}
}
-
-func HandleStore[K comparable, V any](meta Metadata, key K, value V, publish *watchable.Map[K, V]) {
- publish.Store(key, value)
- watchablePublishTotal.WithSuccess(meta.LabelValues()...).Increment()
-}
diff --git a/internal/message/watchutil_test.go b/internal/message/watchutil_test.go
index 109c023f43..bc6b10c9c2 100644
--- a/internal/message/watchutil_test.go
+++ b/internal/message/watchutil_test.go
@@ -12,8 +12,10 @@ import (
"github.com/stretchr/testify/assert"
"github.com/telepresenceio/watchable"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
- "github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
"github.com/envoyproxy/gateway/internal/message"
)
@@ -91,75 +93,147 @@ func TestHandleSubscriptionAlreadyInitialized(t *testing.T) {
assert.Equal(t, 1, deleteCalls)
}
-func TestHandleStore(t *testing.T) {
- var m watchable.Map[string, any]
- message.HandleStore(message.Metadata{Runner: "demo", Message: "demo"}, "foo", "bar", &m)
-
- endCtx, end := context.WithCancel(context.Background())
- go func() {
- <-endCtx.Done()
- message.HandleStore(message.Metadata{Runner: "demo", Message: "demo"}, "baz", "qux", &m)
- m.Delete("qux") // no-op
- message.HandleStore(message.Metadata{Runner: "demo", Message: "demo"}, "foo", "bar", &m) // no-op
- m.Delete("baz")
- time.Sleep(100 * time.Millisecond)
- m.Close()
- }()
-
- var storeCalls int
- var deleteCalls int
- message.HandleSubscription[string, any](
- message.Metadata{Runner: "demo", Message: "demo"},
- m.Subscribe(context.Background()),
- func(update message.Update[string, any], errChans chan error) {
- end()
- if update.Delete {
- deleteCalls++
- } else {
- storeCalls++
- }
- },
- )
- assert.Equal(t, 2, storeCalls)
- assert.Equal(t, 1, deleteCalls)
-}
-
-func TestXdsIRUpdates(t *testing.T) {
+func TestControllerResourceUpdate(t *testing.T) {
tests := []struct {
- desc string
- xx []*ir.Xds
- updates int
+ desc string
+ resources []*resource.ControllerResources
+ updates int
}{
{
- desc: "HTTP listener order change skips update",
- xx: []*ir.Xds{
+ desc: "Resource order change skips update",
+ resources: []*resource.ControllerResources{
{
- HTTP: []*ir.HTTPListener{
- {CoreListenerDetails: ir.CoreListenerDetails{Name: "listener-1"}},
- {CoreListenerDetails: ir.CoreListenerDetails{Name: "listener-2"}},
+ {
+ GatewayClass: &gwapiv1.GatewayClass{ObjectMeta: metav1.ObjectMeta{Name: "class-1"}},
+ },
+ {
+ GatewayClass: &gwapiv1.GatewayClass{ObjectMeta: metav1.ObjectMeta{Name: "class-2"}},
},
},
{
- HTTP: []*ir.HTTPListener{
- {CoreListenerDetails: ir.CoreListenerDetails{Name: "listener-2"}},
- {CoreListenerDetails: ir.CoreListenerDetails{Name: "listener-1"}},
+ {
+ GatewayClass: &gwapiv1.GatewayClass{ObjectMeta: metav1.ObjectMeta{Name: "class-2"}},
+ },
+ {
+ GatewayClass: &gwapiv1.GatewayClass{ObjectMeta: metav1.ObjectMeta{Name: "class-1"}},
},
},
},
updates: 1,
},
{
- desc: "Additional HTTP listener triggers update",
- xx: []*ir.Xds{
+ desc: "Additional resource triggers update",
+ resources: []*resource.ControllerResources{
{
- HTTP: []*ir.HTTPListener{
- {CoreListenerDetails: ir.CoreListenerDetails{Name: "listener-1"}},
+ {
+ GatewayClass: &gwapiv1.GatewayClass{ObjectMeta: metav1.ObjectMeta{Name: "class-1"}},
},
},
{
- HTTP: []*ir.HTTPListener{
- {CoreListenerDetails: ir.CoreListenerDetails{Name: "listener-1"}},
- {CoreListenerDetails: ir.CoreListenerDetails{Name: "listener-2"}},
+ {
+ GatewayClass: &gwapiv1.GatewayClass{ObjectMeta: metav1.ObjectMeta{Name: "class-1"}},
+ },
+ {
+ GatewayClass: &gwapiv1.GatewayClass{ObjectMeta: metav1.ObjectMeta{Name: "class-2"}},
+ },
+ },
+ },
+ updates: 2,
+ },
+ {
+ desc: "Multiple Gateways in Resources struct with order change skips update",
+ resources: []*resource.ControllerResources{
+ {
+ {
+ GatewayClass: &gwapiv1.GatewayClass{ObjectMeta: metav1.ObjectMeta{Name: "class-1"}},
+ Gateways: []*gwapiv1.Gateway{
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-1", Namespace: "default"}},
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-2", Namespace: "default"}},
+ },
+ },
+ {
+ GatewayClass: &gwapiv1.GatewayClass{ObjectMeta: metav1.ObjectMeta{Name: "class-2"}},
+ Gateways: []*gwapiv1.Gateway{
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-3", Namespace: "system"}},
+ },
+ },
+ },
+ {
+ {
+ GatewayClass: &gwapiv1.GatewayClass{ObjectMeta: metav1.ObjectMeta{Name: "class-2"}},
+ Gateways: []*gwapiv1.Gateway{
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-3", Namespace: "system"}},
+ },
+ },
+ {
+ GatewayClass: &gwapiv1.GatewayClass{ObjectMeta: metav1.ObjectMeta{Name: "class-1"}},
+ Gateways: []*gwapiv1.Gateway{
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-2", Namespace: "default"}},
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-1", Namespace: "default"}},
+ },
+ },
+ },
+ },
+ updates: 1,
+ },
+ {
+ desc: "Multiple Gateways with Gateway change triggers update",
+ resources: []*resource.ControllerResources{
+ {
+ {
+ GatewayClass: &gwapiv1.GatewayClass{ObjectMeta: metav1.ObjectMeta{Name: "class-1"}},
+ Gateways: []*gwapiv1.Gateway{
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-1", Namespace: "default"}},
+ },
+ },
+ },
+ {
+ {
+ GatewayClass: &gwapiv1.GatewayClass{ObjectMeta: metav1.ObjectMeta{Name: "class-1"}},
+ Gateways: []*gwapiv1.Gateway{
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-1", Namespace: "default"}},
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-2", Namespace: "default"}},
+ },
+ },
+ },
+ },
+ updates: 2,
+ },
+ {
+ desc: "Multiple Resources with varying Gateway counts",
+ resources: []*resource.ControllerResources{
+ {
+ {
+ GatewayClass: &gwapiv1.GatewayClass{ObjectMeta: metav1.ObjectMeta{Name: "class-1"}},
+ Gateways: []*gwapiv1.Gateway{
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-1", Namespace: "default"}},
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-2", Namespace: "default"}},
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-3", Namespace: "test"}},
+ },
+ },
+ {
+ GatewayClass: &gwapiv1.GatewayClass{ObjectMeta: metav1.ObjectMeta{Name: "class-2"}},
+ Gateways: []*gwapiv1.Gateway{
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-4", Namespace: "system"}},
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-5", Namespace: "system"}},
+ },
+ },
+ },
+ {
+ {
+ GatewayClass: &gwapiv1.GatewayClass{ObjectMeta: metav1.ObjectMeta{Name: "class-1"}},
+ Gateways: []*gwapiv1.Gateway{
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-1", Namespace: "default"}},
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-2", Namespace: "default"}},
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-3", Namespace: "test"}},
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-6", Namespace: "test"}},
+ },
+ },
+ {
+ GatewayClass: &gwapiv1.GatewayClass{ObjectMeta: metav1.ObjectMeta{Name: "class-2"}},
+ Gateways: []*gwapiv1.Gateway{
+ {ObjectMeta: metav1.ObjectMeta{Name: "gateway-4", Namespace: "system"}},
+ },
},
},
},
@@ -169,28 +243,29 @@ func TestXdsIRUpdates(t *testing.T) {
for _, tc := range tests {
t.Run(tc.desc, func(t *testing.T) {
ctx := context.Background()
- m := new(message.XdsIR)
+ m := &message.ProviderResources{}
- snapshotC := m.Subscribe(ctx)
+ snapshotC := m.GatewayAPIResources.Subscribe(ctx)
endCtx, end := context.WithCancel(ctx)
- m.Store("start", &ir.Xds{})
+ m.GatewayAPIResources.Store("start", &resource.ControllerResources{})
go func() {
<-endCtx.Done()
- for _, x := range tc.xx {
- m.Store("test", x)
+ for _, r := range tc.resources {
+ r.Sort()
+ m.GatewayAPIResources.Store("test", r)
}
- m.Store("end", &ir.Xds{})
+ m.GatewayAPIResources.Store("end", &resource.ControllerResources{})
}()
updates := 0
- message.HandleSubscription(message.Metadata{Runner: "demo", Message: "demo"}, snapshotC, func(u message.Update[string, *ir.Xds], errChans chan error) {
+ message.HandleSubscription(message.Metadata{Runner: "demo", Message: "demo"}, snapshotC, func(u message.Update[string, *resource.ControllerResources], errChans chan error) {
end()
if u.Key == "test" {
updates += 1
}
if u.Key == "end" {
- m.Close()
+ m.GatewayAPIResources.Close()
}
})
assert.Equal(t, tc.updates, updates)
diff --git a/internal/metrics/register.go b/internal/metrics/register.go
index 51c3f97610..cb1d761bed 100644
--- a/internal/metrics/register.go
+++ b/internal/metrics/register.go
@@ -112,9 +112,8 @@ func (r *Runner) newOptions() (registerOptions, error) {
newOpts.pullOptions.disable = true
} else {
newOpts.pullOptions.disable = false
- restclient.RegisterClientMetricsWithoutRequestTotal(metricsserver.Registry)
- // Workqueue metrics are already registered in controller-runtime. Use another registry.
reg := prometheus.NewRegistry()
+ restclient.RegisterClientMetricsWithoutRequestTotal(reg)
workqueue.RegisterMetrics(reg)
newOpts.pullOptions.registry = metricsserver.Registry
newOpts.pullOptions.gatherer = prometheus.Gatherers{
diff --git a/internal/provider/file/file_test.go b/internal/provider/file/file_test.go
index 89db93f763..1e8ab2ff53 100644
--- a/internal/provider/file/file_test.go
+++ b/internal/provider/file/file_test.go
@@ -84,6 +84,10 @@ func newFileProviderConfig(paths []string) (*config.Server, error) {
},
},
}
+ cfg.EnvoyGateway.ExtensionAPIs = &egv1a1.ExtensionAPISettings{
+ EnableBackend: true,
+ EnableEnvoyPatchPolicy: true,
+ }
return cfg, nil
}
@@ -290,7 +294,6 @@ func mustUnmarshal(t *testing.T, path string, out interface{}) {
func cmpResources(t *testing.T, x, y interface{}) {
opts := []cmp.Option{
- cmpopts.IgnoreFields(resource.Resources{}, "serviceMap"),
cmpopts.IgnoreFields(metav1.ObjectMeta{}, "ResourceVersion"),
cmpopts.EquateEmpty(),
}
diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go
index bf6c1295ae..b1637bd63b 100644
--- a/internal/provider/kubernetes/controller.go
+++ b/internal/provider/kubernetes/controller.go
@@ -218,6 +218,20 @@ func (r *gatewayAPIReconciler) subscribeToResources(ctx context.Context) {
r.subscriptions.extensionPolicyStatuses = r.resources.ExtensionPolicyStatuses.Subscribe(ctx)
}
+func (r *gatewayAPIReconciler) backendAPIDisabled() bool {
+ // we didn't check if the backend CRD exists every time for performance,
+ // please make sure r.backendCRDExists is setting correctly before calling this
+ if !r.backendCRDExists {
+ return true
+ }
+
+ if r.envoyGateway == nil || r.envoyGateway.ExtensionAPIs == nil {
+ return true
+ }
+
+ return !r.envoyGateway.ExtensionAPIs.EnableBackend
+}
+
func byNamespaceSelectorEnabled(eg *egv1a1.EnvoyGateway) bool {
if eg.Provider == nil ||
eg.Provider.Kubernetes == nil ||
@@ -242,7 +256,9 @@ func isTransientError(err error) bool {
kerrors.IsServiceUnavailable(err) ||
kerrors.IsStoreReadError(err) ||
kerrors.IsInternalError(err) ||
- kerrors.IsUnexpectedServerError(err)
+ kerrors.IsUnexpectedServerError(err) ||
+ errors.Is(err, context.Canceled) ||
+ errors.Is(err, context.DeadlineExceeded)
}
// Reconcile handles reconciling all resources in a single call. Any resource event should enqueue the
@@ -300,11 +316,11 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques
false,
string(gwapiv1.GatewayClassReasonInvalidParameters),
msg)
- message.HandleStore(message.Metadata{
+ r.resources.GatewayClassStatuses.Store(utils.NamespacedName(gc), &gc.Status)
+ message.PublishMetric(message.Metadata{
Runner: string(egv1a1.LogComponentProviderRunner),
Message: message.GatewayClassStatusMessageName,
- },
- utils.NamespacedName(gc), &gc.Status, &r.resources.GatewayClassStatuses)
+ })
failToProcessGCParamsRef = true
}
}
@@ -322,11 +338,11 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques
false,
string(gwapiv1.GatewayClassReasonAccepted),
fmt.Sprintf("%s: %v", status.MsgGatewayClassInvalidParams, err))
- message.HandleStore(message.Metadata{
+ r.resources.GatewayClassStatuses.Store(utils.NamespacedName(gc), &gc.Status)
+ message.PublishMetric(message.Metadata{
Runner: string(egv1a1.LogComponentProviderRunner),
Message: message.GatewayClassStatusMessageName,
- },
- utils.NamespacedName(gc), &gc.Status, &r.resources.GatewayClassStatuses)
+ })
failToProcessGCParamsRef = true
}
@@ -508,15 +524,22 @@ func (r *gatewayAPIReconciler) Reconcile(ctx context.Context, _ reconcile.Reques
}
}
+ // Sort before storing to:
+ // 1. ensure identical resources are not retranslated
+ // and updates are avoided by the watchable layer
+ // 2. ensure gateway-api layer receives resources in order
+ // which impacts translation output
+ gwcResources.Sort()
+
// Store the Gateway Resources for the GatewayClass.
// The Store is triggered even when there are no Gateways associated to the
// GatewayClass. This would happen in case the last Gateway is removed and the
// Store will be required to trigger a cleanup of envoy infra resources.
- message.HandleStore(message.Metadata{
+ r.resources.GatewayAPIResources.Store(string(r.classController), &gwcResources)
+ message.PublishMetric(message.Metadata{
Runner: string(egv1a1.LogComponentProviderRunner),
Message: message.ProviderResourcesMessageName,
- },
- string(r.classController), &gwcResources, &r.resources.GatewayAPIResources)
+ })
r.log.Info("reconciled gateways successfully")
return reconcile.Result{}, nil
@@ -626,8 +649,8 @@ func (r *gatewayAPIReconciler) processBackendRefs(ctx context.Context, gwcResour
endpointSliceLabelKey = mcsapiv1a1.LabelServiceName
case egv1a1.KindBackend:
- if !r.backendCRDExists {
- r.log.V(6).Info("skipping Backend processing as Backend CRD is not installed")
+ if r.backendAPIDisabled() {
+ r.log.V(6).Info("skipping Backend processing as Backend API is disabled.")
continue
}
backend := new(egv1a1.Backend)
@@ -1244,7 +1267,7 @@ func (r *gatewayAPIReconciler) processBtpConfigMapRefs(
) error {
for _, policy := range resourceTree.BackendTrafficPolicies {
for _, ro := range policy.Spec.ResponseOverride {
- if ro.Response.Body != nil && ro.Response.Body.ValueRef != nil && string(ro.Response.Body.ValueRef.Kind) == resource.KindConfigMap {
+ if ro.Response != nil && ro.Response.Body != nil && ro.Response.Body.ValueRef != nil && string(ro.Response.Body.ValueRef.Kind) == resource.KindConfigMap {
configMap := new(corev1.ConfigMap)
err := r.client.Get(ctx,
types.NamespacedName{Namespace: policy.Namespace, Name: string(ro.Response.Body.ValueRef.Name)},
@@ -1359,11 +1382,11 @@ func (r *gatewayAPIReconciler) processGateways(ctx context.Context, managedGC *g
mergedGateways := false
if r.mergeGateways.Has(managedGC.Name) {
mergedGateways = true
- r.processServiceCluster(managedGC.Name, resourceMap)
+ // processGatewayClassParamsRef has been called for this gatewayclass, its EnvoyProxy should exist in resourceTree
+ r.processServiceClusterForGatewayClass(resourceTree.EnvoyProxyForGatewayClass, managedGC, resourceMap)
}
for _, gtw := range gatewayList.Items {
- gtw := gtw //nolint:copyloopvar
if r.namespaceLabel != nil {
if ok, err := r.checkObjectNamespaceLabels(>w); err != nil {
// If the error is transient, we return it to allow Reconcile to retry.
@@ -1385,19 +1408,14 @@ func (r *gatewayAPIReconciler) processGateways(ctx context.Context, managedGC *g
if terminatesTLS(&listener) {
for _, certRef := range listener.TLS.CertificateRefs {
if refsSecret(&certRef) {
- if err := r.processSecretRef(
- ctx,
- resourceMap,
- resourceTree,
- resource.KindGateway,
- gtw.Namespace,
- gtw.Name,
+ if err := r.processSecretRef(ctx,
+ resourceMap, resourceTree,
+ resource.KindGateway, gtw.Namespace, gtw.Name,
certRef); err != nil {
if isTransientError(err) {
return err
}
- r.log.Error(err,
- "failed to process TLS SecretRef for gateway",
+ r.log.Error(err, "failed to process TLS SecretRef for gateway",
"gateway", gtw, "secretRef", certRef)
}
}
@@ -1407,10 +1425,6 @@ func (r *gatewayAPIReconciler) processGateways(ctx context.Context, managedGC *g
gtwNamespacedName := utils.NamespacedName(>w).String()
- if !mergedGateways {
- r.processServiceCluster(gtwNamespacedName, resourceMap)
- }
-
// Route Processing
if r.tlsRouteCRDExists {
@@ -1463,6 +1477,20 @@ func (r *gatewayAPIReconciler) processGateways(ctx context.Context, managedGC *g
r.log.Error(err, "failed to process infrastructure.parametersRef for gateway", "namespace", gtw.Namespace, "name", gtw.Name)
}
+ if !mergedGateways {
+ var ep *egv1a1.EnvoyProxy = nil
+ if gtw.Spec.Infrastructure != nil && gtw.Spec.Infrastructure.ParametersRef != nil {
+ // processGatewayParamsRef has been called for this gateway, its EnvoyProxy should exist in resourceTree
+ ep = resourceTree.GetEnvoyProxy(gtw.Namespace, gtw.Spec.Infrastructure.ParametersRef.Name)
+ }
+ // when gateway's EnvoyProxy is nil and gatewayclass 's EnvoyProxy is not nil
+ // the specified proxySvcName should get from gatewayclass's EnvoyProxy
+ if ep == nil && resourceTree.EnvoyProxyForGatewayClass != nil {
+ ep = resourceTree.EnvoyProxyForGatewayClass
+ }
+ r.processServiceClusterForGateway(ep, >w, resourceMap)
+ }
+
if !resourceMap.allAssociatedGateways.Has(gtwNamespacedName) {
resourceMap.allAssociatedGateways.Insert(gtwNamespacedName)
resourceTree.Gateways = append(resourceTree.Gateways, >w)
@@ -1472,11 +1500,55 @@ func (r *gatewayAPIReconciler) processGateways(ctx context.Context, managedGC *g
return nil
}
-func (r *gatewayAPIReconciler) processServiceCluster(resourceName string, resourceMap *resourceMappings) {
- proxySvcName := proxy.ExpectedResourceHashedName(resourceName)
+// Called on a GatewayClass when merged gateways mode is enabled for it.
+func (r *gatewayAPIReconciler) processServiceClusterForGatewayClass(ep *egv1a1.EnvoyProxy, gatewayClass *gwapiv1.GatewayClass, resourceMap *resourceMappings) {
+ // Skip processing if topology injector is disabled
+ if r.envoyGateway != nil && r.envoyGateway.TopologyInjectorDisabled() {
+ return
+ }
+
+ proxySvcName, proxySvcNamespace := proxy.ExpectedResourceHashedName(gatewayClass.Name), r.namespace
+
+ // Check if the service name was specified in EnvoyProxy
+ if ep != nil {
+ provider := ep.GetEnvoyProxyProvider()
+ if provider.Kubernetes != nil && provider.Kubernetes.EnvoyService != nil && provider.Kubernetes.EnvoyService.Name != nil {
+ proxySvcName = *provider.Kubernetes.EnvoyService.Name
+ }
+ }
+
+ resourceMap.allAssociatedBackendRefs.Insert(gwapiv1.BackendObjectReference{
+ Kind: ptr.To(gwapiv1.Kind("Service")),
+ Namespace: gatewayapi.NamespacePtr(proxySvcNamespace),
+ Name: gwapiv1.ObjectName(proxySvcName),
+ })
+}
+
+// Called on a Gateway when merged gateways mode is not enabled for its parent GatewayClass.
+func (r *gatewayAPIReconciler) processServiceClusterForGateway(ep *egv1a1.EnvoyProxy, gateway *gwapiv1.Gateway, resourceMap *resourceMappings) {
+ // Skip processing if topology injector is disabled
+ if r.envoyGateway != nil && r.envoyGateway.TopologyInjectorDisabled() {
+ return
+ }
+
+ proxySvcName, proxySvcNamespace := proxy.ExpectedResourceHashedName(utils.NamespacedName(gateway).String()), r.namespace
+ // Check if gateway namespaced mode is used. If it is, the service's name is the same as
+ // the gateway's and it lives in the gateway's namespace not the controller's.
+ if r.gatewayNamespaceMode {
+ proxySvcName, proxySvcNamespace = gateway.Name, gateway.Namespace
+ }
+
+ // Check if the service name was specified in EnvoyProxy
+ if ep != nil {
+ provider := ep.GetEnvoyProxyProvider()
+ if provider.Kubernetes != nil && provider.Kubernetes.EnvoyService != nil && provider.Kubernetes.EnvoyService.Name != nil {
+ proxySvcName = *provider.Kubernetes.EnvoyService.Name
+ }
+ }
+
resourceMap.allAssociatedBackendRefs.Insert(gwapiv1.BackendObjectReference{
Kind: ptr.To(gwapiv1.Kind("Service")),
- Namespace: gatewayapi.NamespacePtr(r.namespace),
+ Namespace: gatewayapi.NamespacePtr(proxySvcNamespace),
Name: gwapiv1.ObjectName(proxySvcName),
})
}
@@ -1862,10 +1934,16 @@ func (r *gatewayAPIReconciler) watchResources(ctx context.Context, mgr manager.M
return err
}
+ // we didn't check if the backend CRD exists every time for performance,
+ // please make sure r.backendCRDExists is setting correctly before calling this
r.backendCRDExists = r.crdExists(mgr, resource.KindBackend, egv1a1.GroupVersion.String())
- if !r.backendCRDExists {
- r.log.Info("Backend CRD not found, skipping Backend watch")
- } else if r.envoyGateway.ExtensionAPIs != nil && r.envoyGateway.ExtensionAPIs.EnableBackend {
+ if r.backendAPIDisabled() {
+ if !r.backendCRDExists {
+ r.log.Info("Backend CRD not found, skipping Backend watch")
+ } else {
+ r.log.Info("Backend API disabled, skipping Backend watch")
+ }
+ } else {
// Watch Backend CRUDs and process affected *Route objects.
backendPredicates := []predicate.TypedPredicate[*egv1a1.Backend]{
predicate.TypedGenerationChangedPredicate[*egv1a1.Backend]{},
@@ -2291,18 +2369,14 @@ func (r *gatewayAPIReconciler) processGatewayParamsRef(ctx context.Context, gtw
return err
}
+ // Missing secret shouldn't stop the Gateway infrastructure from coming up
if ep.Spec.BackendTLS != nil && ep.Spec.BackendTLS.ClientCertificateRef != nil {
certRef := ep.Spec.BackendTLS.ClientCertificateRef
if refsSecret(certRef) {
- if err := r.processSecretRef(
- ctx,
- resourceMap,
- resourceTree,
- resource.KindGateway,
- gtw.Namespace,
- gtw.Name,
- *certRef); err != nil {
- return fmt.Errorf("failed to process TLS SecretRef for gateway %s/%s: %w", gtw.Namespace, gtw.Name, err)
+ if err := r.processSecretRef(ctx,
+ resourceMap, resourceTree, resource.KindGateway,
+ gtw.Namespace, gtw.Name, *certRef); err != nil {
+ r.log.Error(err, "failed to process ClientCertificateRef for EnvoyProxy", "namespace", gtw.Namespace, "name", gtw.Name)
}
}
}
diff --git a/internal/provider/kubernetes/controller_test.go b/internal/provider/kubernetes/controller_test.go
index 956481c6be..9d5228761a 100644
--- a/internal/provider/kubernetes/controller_test.go
+++ b/internal/provider/kubernetes/controller_test.go
@@ -30,6 +30,7 @@ import (
"github.com/envoyproxy/gateway/internal/envoygateway/config"
"github.com/envoyproxy/gateway/internal/gatewayapi"
"github.com/envoyproxy/gateway/internal/gatewayapi/resource"
+ "github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/proxy"
"github.com/envoyproxy/gateway/internal/logging"
"github.com/envoyproxy/gateway/internal/provider/kubernetes/test"
"github.com/envoyproxy/gateway/internal/utils"
@@ -1247,6 +1248,239 @@ func TestProcessSecurityPolicyObjectRefs(t *testing.T) {
}
}
+func TestProcessServiceClusterForGatewayClass(t *testing.T) {
+ testCases := []struct {
+ name string
+ gatewayClass *gwapiv1.GatewayClass
+ envoyProxy *egv1a1.EnvoyProxy
+ expectedSvcName string
+ }{
+ {
+ name: "when merged gateways and no hardcoded svc name is used",
+ gatewayClass: &gwapiv1.GatewayClass{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "merged-gc",
+ },
+ },
+ envoyProxy: nil,
+ expectedSvcName: proxy.ExpectedResourceHashedName("merged-gc"),
+ },
+ {
+ name: "when merged gateways and a hardcoded svc name is used",
+ gatewayClass: &gwapiv1.GatewayClass{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "merged-gc",
+ },
+ },
+ envoyProxy: &egv1a1.EnvoyProxy{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "merged-gc",
+ },
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyService: &egv1a1.KubernetesServiceSpec{
+ Name: ptr.To("merged-gc-svc"),
+ },
+ },
+ },
+ },
+ },
+ expectedSvcName: "merged-gc-svc",
+ },
+ }
+
+ for i := range testCases {
+ tc := testCases[i]
+ // Run the test cases.
+ t.Run(tc.name, func(t *testing.T) {
+ logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
+ resourceMap := newResourceMapping()
+
+ r := newGatewayAPIReconciler(logger)
+ r.namespace = "envoy-gateway-system"
+
+ r.processServiceClusterForGatewayClass(tc.envoyProxy, tc.gatewayClass, resourceMap)
+
+ require.Contains(t, resourceMap.allAssociatedBackendRefs, gwapiv1.BackendObjectReference{
+ Kind: ptr.To(gwapiv1.Kind("Service")),
+ Namespace: gatewayapi.NamespacePtr(r.namespace),
+ Name: gwapiv1.ObjectName(tc.expectedSvcName),
+ })
+ })
+ }
+}
+
+func TestProcessServiceClusterForGateway(t *testing.T) {
+ testCases := []struct {
+ name string
+ gateway *gwapiv1.Gateway
+ envoyProxy *egv1a1.EnvoyProxy
+ gatewayClassEnvoyProxy *egv1a1.EnvoyProxy
+ gatewayNamespacedMode bool
+ expectedSvcName string
+ expectedSvcNamespace string
+ }{
+ {
+ name: "no gateway namespaced mode with no hardcoded service name",
+ gateway: &gwapiv1.Gateway{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "my-gateway",
+ Namespace: "app-namespace",
+ },
+ },
+ envoyProxy: nil,
+ gatewayNamespacedMode: false,
+ expectedSvcName: "",
+ expectedSvcNamespace: "",
+ },
+ {
+ name: "no gateway namespaced mode with hardcoded service name",
+ gateway: &gwapiv1.Gateway{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "my-gateway",
+ Namespace: "app-namespace",
+ },
+ },
+ envoyProxy: &egv1a1.EnvoyProxy{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "my-gateway",
+ },
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyService: &egv1a1.KubernetesServiceSpec{
+ Name: ptr.To("my-gateway-svc"),
+ },
+ },
+ },
+ },
+ },
+ gatewayNamespacedMode: false,
+ expectedSvcName: "my-gateway-svc",
+ expectedSvcNamespace: "",
+ },
+ {
+ name: "gateway namespaced mode with no hardcoded service name",
+ gateway: &gwapiv1.Gateway{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "my-gateway",
+ Namespace: "app-namespace",
+ },
+ },
+ envoyProxy: nil,
+ gatewayNamespacedMode: true,
+ expectedSvcName: "my-gateway",
+ expectedSvcNamespace: "app-namespace",
+ },
+ {
+ name: "gateway namespaced mode with hardcoded service name",
+ gateway: &gwapiv1.Gateway{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "my-gateway",
+ Namespace: "app-namespace",
+ },
+ },
+ envoyProxy: &egv1a1.EnvoyProxy{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "my-gateway",
+ },
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyService: &egv1a1.KubernetesServiceSpec{
+ Name: ptr.To("my-gateway-svc"),
+ },
+ },
+ },
+ },
+ },
+ gatewayNamespacedMode: true,
+ expectedSvcName: "my-gateway-svc",
+ expectedSvcNamespace: "app-namespace",
+ },
+ {
+ name: "no gateway namespaced mode with no hardcoded service name attached gatewayclass",
+ gateway: &gwapiv1.Gateway{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "my-gateway",
+ Namespace: "app-namespace",
+ },
+ },
+ envoyProxy: nil,
+ gatewayClassEnvoyProxy: &egv1a1.EnvoyProxy{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "my-gateway",
+ },
+ Spec: egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyService: &egv1a1.KubernetesServiceSpec{
+ Name: ptr.To("my-gateway-svc"),
+ },
+ },
+ },
+ },
+ },
+ gatewayNamespacedMode: false,
+ expectedSvcName: "my-gateway-svc",
+ expectedSvcNamespace: "",
+ },
+ }
+
+ for i := range testCases {
+ tc := testCases[i]
+ // Run the test cases.
+ t.Run(tc.name, func(t *testing.T) {
+ logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
+ resourceMap := newResourceMapping()
+
+ r := newGatewayAPIReconciler(logger)
+ r.namespace = "envoy-gateway-system"
+ r.gatewayNamespaceMode = tc.gatewayNamespacedMode
+
+ if tc.expectedSvcNamespace == "" {
+ tc.expectedSvcNamespace = r.namespace
+ }
+
+ if tc.expectedSvcName == "" {
+ tc.expectedSvcName = proxy.ExpectedResourceHashedName(utils.NamespacedName(tc.gateway).String())
+ }
+
+ if tc.envoyProxy == nil && tc.gatewayClassEnvoyProxy != nil {
+ tc.envoyProxy = tc.gatewayClassEnvoyProxy
+ }
+
+ r.processServiceClusterForGateway(tc.envoyProxy, tc.gateway, resourceMap)
+
+ require.Contains(t, resourceMap.allAssociatedBackendRefs, gwapiv1.BackendObjectReference{
+ Kind: ptr.To(gwapiv1.Kind("Service")),
+ Namespace: gatewayapi.NamespacePtr(tc.expectedSvcNamespace),
+ Name: gwapiv1.ObjectName(tc.expectedSvcName),
+ })
+ })
+ }
+}
+
+func newGatewayAPIReconciler(logger logging.Logger) *gatewayAPIReconciler {
+ return &gatewayAPIReconciler{
+ log: logger,
+ classController: "some-gateway-class",
+ backendCRDExists: true,
+ envoyGateway: &egv1a1.EnvoyGateway{
+ EnvoyGatewaySpec: egv1a1.EnvoyGatewaySpec{
+ ExtensionAPIs: &egv1a1.ExtensionAPISettings{
+ EnableBackend: true,
+ },
+ },
+ },
+ }
+}
+
func TestProcessBackendRefs(t *testing.T) {
ns := "default"
ctb := test.GetClusterTrustBundle("fake-ctb")
@@ -1341,12 +1575,7 @@ func TestProcessBackendRefs(t *testing.T) {
objs := []client.Object{tc.backend, ctb, secret, cm}
logger := logging.DefaultLogger(os.Stdout, egv1a1.LogLevelInfo)
- r := &gatewayAPIReconciler{
- log: logger,
- classController: "some-gateway-class",
- backendCRDExists: true,
- }
-
+ r := newGatewayAPIReconciler(logger)
r.client = fakeclient.NewClientBuilder().
WithScheme(envoygateway.GetScheme()).
WithObjects(objs...).
@@ -1407,6 +1636,12 @@ func TestIsTransientError(t *testing.T) {
serviceUnavailableErr := kerrors.NewServiceUnavailable("service unavailable")
badRequestErr := kerrors.NewBadRequest("bad request")
+ // new test errors for context
+ canceledErr := context.Canceled
+ deadlineExceededErr := context.DeadlineExceeded
+ wrappedCanceledErr := fmt.Errorf("wrapped: %w", context.Canceled)
+ wrappedDeadlineExceededErr := fmt.Errorf("wrapped: %w", context.DeadlineExceeded)
+
testCases := []struct {
name string
err error
@@ -1418,6 +1653,10 @@ func TestIsTransientError(t *testing.T) {
{"ServiceUnavailable", serviceUnavailableErr, true},
{"BadRequest", badRequestErr, false},
{"NilError", nil, false},
+ {"ContextCanceled", canceledErr, true},
+ {"ContextDeadlineExceeded", deadlineExceededErr, true},
+ {"WrappedContextCanceled", wrappedCanceledErr, true},
+ {"WrappedContextDeadlineExceeded", wrappedDeadlineExceededErr, true},
}
for _, tc := range testCases {
diff --git a/internal/provider/kubernetes/filters.go b/internal/provider/kubernetes/filters.go
index 64b3b1e242..5e0ea45d9c 100644
--- a/internal/provider/kubernetes/filters.go
+++ b/internal/provider/kubernetes/filters.go
@@ -24,7 +24,7 @@ func (r *gatewayAPIReconciler) getExtensionRefFilters(ctx context.Context) ([]un
uExtResourceList := &unstructured.UnstructuredList{}
uExtResourceList.SetGroupVersionKind(gvk)
if err := r.client.List(ctx, uExtResourceList); err != nil {
- r.log.Info("no associated resources found for %s", gvk.String())
+ r.log.Info("no associated resources found", "GVK", gvk.String())
return nil, fmt.Errorf("failed to list %s: %w", gvk.String(), err)
}
@@ -57,7 +57,7 @@ func (r *gatewayAPIReconciler) getExtensionBackendResources(ctx context.Context)
uExtResourceList := &unstructured.UnstructuredList{}
uExtResourceList.SetGroupVersionKind(gvk)
if err := r.client.List(ctx, uExtResourceList); err != nil {
- r.log.Info("no associated backend resources found for %s", gvk.String())
+ r.log.Info("no associated backend resources found", "GVK", gvk.String())
return nil, fmt.Errorf("failed to list %s: %w", gvk.String(), err)
}
diff --git a/internal/provider/kubernetes/indexers.go b/internal/provider/kubernetes/indexers.go
index 11418f63da..2b9b5efdb3 100644
--- a/internal/provider/kubernetes/indexers.go
+++ b/internal/provider/kubernetes/indexers.go
@@ -837,7 +837,7 @@ func configMapBtpIndexFunc(rawObj client.Object) []string {
var configMapReferences []string
for _, ro := range btp.Spec.ResponseOverride {
- if ro.Response.Body != nil && ro.Response.Body.ValueRef != nil {
+ if ro.Response != nil && ro.Response.Body != nil && ro.Response.Body.ValueRef != nil {
if string(ro.Response.Body.ValueRef.Kind) == resource.KindConfigMap {
configMapReferences = append(configMapReferences,
types.NamespacedName{
diff --git a/internal/provider/kubernetes/kubernetes.go b/internal/provider/kubernetes/kubernetes.go
index b99a486d3f..57084b84a4 100644
--- a/internal/provider/kubernetes/kubernetes.go
+++ b/internal/provider/kubernetes/kubernetes.go
@@ -10,6 +10,8 @@ import (
"fmt"
"time"
+ corev1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/rest"
"k8s.io/klog/v2"
"k8s.io/utils/ptr"
@@ -26,6 +28,7 @@ import (
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/envoygateway"
ec "github.com/envoyproxy/gateway/internal/envoygateway/config"
+ "github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/proxy"
"github.com/envoyproxy/gateway/internal/message"
)
@@ -112,6 +115,16 @@ func New(ctx context.Context, restCfg *rest.Config, svrCfg *ec.Server, resources
mgrOpts.Cache.SyncPeriod = ptr.To(csp)
}
+ // Limit the cache to only Envoy proxy Pods to reduce memory and sync churn.
+ // ProxyTopologyInjector is the only component that interacts with Pods.
+ if mgrOpts.Cache.ByObject == nil {
+ mgrOpts.Cache.ByObject = map[client.Object]cache.ByObject{}
+ }
+
+ mgrOpts.Cache.ByObject[&corev1.Pod{}] = cache.ByObject{
+ Label: labels.SelectorFromSet(proxy.EnvoyAppLabel()),
+ }
+
if svrCfg.EnvoyGateway.NamespaceMode() {
mgrOpts.Cache.DefaultNamespaces = make(map[string]cache.Config)
for _, watchNS := range svrCfg.EnvoyGateway.Provider.Kubernetes.Watch.Namespaces {
@@ -134,9 +147,10 @@ func New(ctx context.Context, restCfg *rest.Config, svrCfg *ec.Server, resources
if svrCfg.EnvoyGateway.Provider.Kubernetes.TopologyInjector == nil || !ptr.Deref(svrCfg.EnvoyGateway.Provider.Kubernetes.TopologyInjector.Disable, false) {
mgr.GetWebhookServer().Register("/inject-pod-topology", &webhook.Admission{
Handler: &ProxyTopologyInjector{
- Client: mgr.GetClient(),
- Logger: svrCfg.Logger.WithName("proxy-topology-injector"),
- Decoder: admission.NewDecoder(mgr.GetScheme()),
+ Client: mgr.GetClient(),
+ APIReader: mgr.GetAPIReader(),
+ Logger: svrCfg.Logger.WithName("proxy-topology-injector"),
+ Decoder: admission.NewDecoder(mgr.GetScheme()),
},
})
}
diff --git a/internal/provider/kubernetes/predicates.go b/internal/provider/kubernetes/predicates.go
index 5e2d22bd52..b4c19b4d6c 100644
--- a/internal/provider/kubernetes/predicates.go
+++ b/internal/provider/kubernetes/predicates.go
@@ -197,7 +197,7 @@ func (r *gatewayAPIReconciler) validateSecretForReconcile(obj client.Object) boo
}
func (r *gatewayAPIReconciler) validateClusterTrustBundleForReconcile(ctb *certificatesv1b1.ClusterTrustBundle) bool {
- if r.backendCRDExists {
+ if !r.backendAPIDisabled() {
if r.isBackendReferencingClusterTrustBundle(ctb) {
return true
}
@@ -614,7 +614,7 @@ func (r *gatewayAPIReconciler) validateEndpointSliceForReconcile(obj client.Obje
}
}
- if r.isProxyServiceCluster(&nsName) {
+ if r.isProxyServiceCluster(ep.GetLabels()) {
return true
}
return false
@@ -940,23 +940,18 @@ func (r *gatewayAPIReconciler) isRouteReferencingHTTPRouteFilter(nsName *types.N
return len(httpRouteList.Items) != 0
}
-func (r *gatewayAPIReconciler) isProxyServiceCluster(nn *types.NamespacedName) bool {
- ctx := context.Background()
- svc := &corev1.Service{}
- if err := r.client.Get(ctx, *nn, svc); err != nil {
- r.log.Error(err, "unable to find associated proxy ServiceCluster")
+// isProxyServiceCluster returns true if the provided labels reference an owning Gateway or GatewayClass
+func (r *gatewayAPIReconciler) isProxyServiceCluster(labels map[string]string) bool {
+ // Skip processing if topology injector is disabled
+ if r.envoyGateway != nil && r.envoyGateway.TopologyInjectorDisabled() {
return false
}
- svcLabels := svc.GetLabels()
-
- // Check if service belongs to a Gateway
- if gtw := r.findOwningGateway(ctx, svcLabels); gtw != nil {
+ if gtw := r.findOwningGateway(context.Background(), labels); gtw != nil {
return true
}
- // Check if service belongs to a GatewayClass
- gcName, ok := svcLabels[gatewayapi.OwningGatewayClassLabel]
+ gcName, ok := labels[gatewayapi.OwningGatewayClassLabel]
if ok && r.mergeGateways.Has(gcName) {
return true
}
diff --git a/internal/provider/kubernetes/predicates_test.go b/internal/provider/kubernetes/predicates_test.go
index 6d1035e518..7478febea0 100644
--- a/internal/provider/kubernetes/predicates_test.go
+++ b/internal/provider/kubernetes/predicates_test.go
@@ -286,6 +286,42 @@ func TestValidateConfigMapForReconcile(t *testing.T) {
}
}
+// TestValidateBackendTrafficPolicyForReconcileWithRedirectResponseOverride tests the validateBackendTrafficPolicyForReconcile
+// predicate function with a redirect response override.
+func TestValidateBackendTrafficPolicyForReconcileWithRedirectResponseOverride(t *testing.T) {
+ btpWithRedirect := &egv1a1.BackendTrafficPolicy{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "response-override",
+ Namespace: "envoy-gateway-system",
+ },
+ Spec: egv1a1.BackendTrafficPolicySpec{
+ ResponseOverride: []*egv1a1.ResponseOverride{
+ {
+ Match: egv1a1.CustomResponseMatch{
+ StatusCodes: []egv1a1.StatusCodeMatch{
+ {
+ Type: &[]egv1a1.StatusCodeValueType{egv1a1.StatusCodeValueTypeRange}[0],
+ Range: &egv1a1.StatusCodeRange{
+ Start: 500,
+ End: 511,
+ },
+ },
+ },
+ },
+ // Using redirect instead of response causes ro.Response to be nil
+ Redirect: &egv1a1.CustomRedirect{
+ Hostname: &[]gwapiv1.PreciseHostname{"custom-errors.example.com"}[0],
+ StatusCode: &[]int{302}[0],
+ Scheme: &[]string{"https"}[0],
+ },
+ },
+ },
+ },
+ }
+ result := configMapBtpIndexFunc(btpWithRedirect)
+ require.Empty(t, result)
+}
+
// TestValidateSecretForReconcile tests the validateSecretForReconcile
// predicate function.
func TestValidateSecretForReconcile(t *testing.T) {
@@ -1559,6 +1595,13 @@ func TestValidateClusterTrustBundleForReconcile(t *testing.T) {
backendCRDExists: true,
bTLSPolicyCRDExists: true,
ctpCRDExists: true,
+ envoyGateway: &egv1a1.EnvoyGateway{
+ EnvoyGatewaySpec: egv1a1.EnvoyGatewaySpec{
+ ExtensionAPIs: &egv1a1.ExtensionAPISettings{
+ EnableBackend: true,
+ },
+ },
+ },
}
for _, tc := range testCases {
diff --git a/internal/provider/kubernetes/status.go b/internal/provider/kubernetes/status.go
index e9abf085a1..29ec951146 100644
--- a/internal/provider/kubernetes/status.go
+++ b/internal/provider/kubernetes/status.go
@@ -104,7 +104,7 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context, ext
panic(err)
}
hCopy := h.DeepCopy()
- hCopy.Status.Parents = mergeRouteParentStatus(h.Namespace, h.Status.Parents, val.Parents)
+ hCopy.Status.Parents = mergeRouteParentStatus(h.Namespace, r.envoyGateway.Gateway.ControllerName, h.Status.Parents, val.Parents)
return hCopy
}),
})
@@ -134,7 +134,7 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context, ext
panic(err)
}
gCopy := g.DeepCopy()
- gCopy.Status.Parents = mergeRouteParentStatus(g.Namespace, g.Status.Parents, val.Parents)
+ gCopy.Status.Parents = mergeRouteParentStatus(g.Namespace, r.envoyGateway.Gateway.ControllerName, g.Status.Parents, val.Parents)
return gCopy
}),
})
@@ -166,7 +166,7 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context, ext
panic(err)
}
tCopy := t.DeepCopy()
- tCopy.Status.Parents = mergeRouteParentStatus(t.Namespace, t.Status.Parents, val.Parents)
+ tCopy.Status.Parents = mergeRouteParentStatus(t.Namespace, r.envoyGateway.Gateway.ControllerName, t.Status.Parents, val.Parents)
return tCopy
}),
})
@@ -198,7 +198,7 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context, ext
panic(err)
}
tCopy := t.DeepCopy()
- tCopy.Status.Parents = mergeRouteParentStatus(t.Namespace, t.Status.Parents, val.Parents)
+ tCopy.Status.Parents = mergeRouteParentStatus(t.Namespace, r.envoyGateway.Gateway.ControllerName, t.Status.Parents, val.Parents)
return tCopy
}),
})
@@ -230,7 +230,7 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context, ext
panic(err)
}
uCopy := u.DeepCopy()
- uCopy.Status.Parents = mergeRouteParentStatus(u.Namespace, u.Status.Parents, val.Parents)
+ uCopy.Status.Parents = mergeRouteParentStatus(u.Namespace, r.envoyGateway.Gateway.ControllerName, u.Status.Parents, val.Parents)
return uCopy
}),
})
@@ -501,21 +501,41 @@ func (r *gatewayAPIReconciler) subscribeAndUpdateStatus(ctx context.Context, ext
// mergeRouteParentStatus merges the old and new RouteParentStatus.
// This is needed because the RouteParentStatus doesn't support strategic merge patch yet.
-func mergeRouteParentStatus(ns string, old, new []gwapiv1.RouteParentStatus) []gwapiv1.RouteParentStatus {
- merged := make([]gwapiv1.RouteParentStatus, len(old))
- _ = copy(merged, old)
- for _, parent := range new {
+func mergeRouteParentStatus(ns, controllerName string, old, new []gwapiv1.RouteParentStatus) []gwapiv1.RouteParentStatus {
+ // Allocating with worst-case capacity to avoid reallocation.
+ merged := make([]gwapiv1.RouteParentStatus, 0, len(old)+len(new))
+
+ // Range over old status parentRefs in order:
+ // 1. The parentRef exists in the new status: append the new one to the final status.
+ // 2. The parentRef doesn't exist in the new status and it's not our controller: append it to the final status.
+ // 3. The parentRef doesn't exist in the new status, and it is our controller: don't append it to the final status.
+ for _, oldP := range old {
found := -1
- for i, existing := range old {
- if isParentRefEqual(parent.ParentRef, existing.ParentRef, ns) {
- found = i
+ for newI, newP := range new {
+ if isParentRefEqual(oldP.ParentRef, newP.ParentRef, ns) {
+ found = newI
break
}
}
if found >= 0 {
- merged[found] = parent
- } else {
- merged = append(merged, parent)
+ merged = append(merged, new[found])
+ } else if oldP.ControllerName != gwapiv1.GatewayController(controllerName) {
+ merged = append(merged, oldP)
+ }
+ }
+
+ // Range over new status parentRefs and make sure every parentRef exists in the final status. If not, append it.
+ for _, newP := range new {
+ found := false
+ for _, mergedP := range merged {
+ if isParentRefEqual(newP.ParentRef, mergedP.ParentRef, ns) {
+ found = true
+ break
+ }
+ }
+
+ if !found {
+ merged = append(merged, newP)
}
}
return merged
diff --git a/internal/provider/kubernetes/status_test.go b/internal/provider/kubernetes/status_test.go
index 5e81c46135..63b7fdea7f 100644
--- a/internal/provider/kubernetes/status_test.go
+++ b/internal/provider/kubernetes/status_test.go
@@ -25,11 +25,11 @@ func Test_mergeRouteParentStatus(t *testing.T) {
want []gwapiv1.RouteParentStatus
}{
{
- name: "merge old and new",
+ name: "old contains one parentRef of ours and one of another controller's, status of ours changed in new.",
args: args{
old: []gwapiv1.RouteParentStatus{
{
- ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ControllerName: "istio.io/gateway-controller",
ParentRef: gwapiv1.ParentReference{
Name: "gateway1",
Namespace: ptr.To[gwapiv1.Namespace]("default"),
@@ -49,6 +49,24 @@ func Test_mergeRouteParentStatus(t *testing.T) {
},
},
},
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway2",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
},
new: []gwapiv1.RouteParentStatus{
{
@@ -59,6 +77,11 @@ func Test_mergeRouteParentStatus(t *testing.T) {
Conditions: []metav1.Condition{
{
Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
Status: metav1.ConditionFalse,
Reason: "SomeReason",
},
@@ -68,7 +91,7 @@ func Test_mergeRouteParentStatus(t *testing.T) {
},
want: []gwapiv1.RouteParentStatus{
{
- ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ControllerName: "istio.io/gateway-controller",
ParentRef: gwapiv1.ParentReference{
Name: "gateway1",
Namespace: ptr.To[gwapiv1.Namespace]("default"),
@@ -96,6 +119,11 @@ func Test_mergeRouteParentStatus(t *testing.T) {
Conditions: []metav1.Condition{
{
Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
Status: metav1.ConditionFalse,
Reason: "SomeReason",
},
@@ -103,15 +131,17 @@ func Test_mergeRouteParentStatus(t *testing.T) {
},
},
},
-
{
- name: "override an existing parent",
+ name: "old contains one parentRef of ours and one of another controller's, status of ours changed in new with an additional parentRef of ours",
args: args{
old: []gwapiv1.RouteParentStatus{
{
- ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ControllerName: "istio.io/gateway-controller",
ParentRef: gwapiv1.ParentReference{
- Name: "gateway1",
+ Name: "gateway1",
+ Namespace: ptr.To[gwapiv1.Namespace]("default"),
+ SectionName: ptr.To[gwapiv1.SectionName]("listener1"),
+ Port: ptr.To[gwapiv1.PortNumber](80),
},
Conditions: []metav1.Condition{
{
@@ -129,8 +159,7 @@ func Test_mergeRouteParentStatus(t *testing.T) {
{
ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
ParentRef: gwapiv1.ParentReference{
- Name: "gateway2",
- Namespace: ptr.To[gwapiv1.Namespace]("default"),
+ Name: "gateway2",
},
Conditions: []metav1.Condition{
{
@@ -155,18 +184,44 @@ func Test_mergeRouteParentStatus(t *testing.T) {
Conditions: []metav1.Condition{
{
Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
Status: metav1.ConditionFalse,
Reason: "SomeReason",
},
},
},
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway3",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
},
},
want: []gwapiv1.RouteParentStatus{
{
- ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ControllerName: "istio.io/gateway-controller",
ParentRef: gwapiv1.ParentReference{
- Name: "gateway1",
+ Name: "gateway1",
+ Namespace: ptr.To[gwapiv1.Namespace]("default"),
+ SectionName: ptr.To[gwapiv1.SectionName]("listener1"),
+ Port: ptr.To[gwapiv1.PortNumber](80),
},
Conditions: []metav1.Condition{
{
@@ -189,22 +244,229 @@ func Test_mergeRouteParentStatus(t *testing.T) {
Conditions: []metav1.Condition{
{
Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
Status: metav1.ConditionFalse,
Reason: "SomeReason",
},
},
},
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway3",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ },
+ },
+ {
+ name: "old contains one parentRef of ours and one of another controller's, ours gets dropped in new and a different parentRef of ours is added",
+ args: args{
+ old: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "istio.io/gateway-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway1",
+ Namespace: ptr.To[gwapiv1.Namespace]("default"),
+ SectionName: ptr.To[gwapiv1.SectionName]("listener1"),
+ Port: ptr.To[gwapiv1.PortNumber](80),
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway2",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ },
+ new: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway3",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ },
+ },
+ want: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "istio.io/gateway-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway1",
+ Namespace: ptr.To[gwapiv1.Namespace]("default"),
+ SectionName: ptr.To[gwapiv1.SectionName]("listener1"),
+ Port: ptr.To[gwapiv1.PortNumber](80),
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway3",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ },
+ },
+ // Practically this will never occur, since having no parentRefs in the new
+ // status means the route doesn't attach (in the spec) to any of our gateways.
+ //
+ // But then we'd consider it irrelevant before ever computing such status for it, i.e, the
+ // route will forever have a dangling status parentRef referencing us that will not be removed.
+ //
+ // TODO: maybe this needs to be fixed.
+ {
+ name: "old contains one parentRef of ours and one of another controller's, ours gets dropped in new.",
+ args: args{
+ old: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "istio.io/gateway-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway1",
+ Namespace: ptr.To[gwapiv1.Namespace]("default"),
+ SectionName: ptr.To[gwapiv1.SectionName]("listener1"),
+ Port: ptr.To[gwapiv1.PortNumber](80),
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway2",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ },
+ new: []gwapiv1.RouteParentStatus{},
+ },
+ want: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "istio.io/gateway-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway1",
+ Namespace: ptr.To[gwapiv1.Namespace]("default"),
+ SectionName: ptr.To[gwapiv1.SectionName]("listener1"),
+ Port: ptr.To[gwapiv1.PortNumber](80),
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
},
},
{
- name: "nothing changed",
+ name: "old contains one parentRef of ours, status of ours changed in new.",
args: args{
old: []gwapiv1.RouteParentStatus{
{
ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
ParentRef: gwapiv1.ParentReference{
- Name: "gateway1",
+ Name: "gateway2",
},
Conditions: []metav1.Condition{
{
@@ -219,6 +481,8 @@ func Test_mergeRouteParentStatus(t *testing.T) {
},
},
},
+ },
+ new: []gwapiv1.RouteParentStatus{
{
ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
ParentRef: gwapiv1.ParentReference{
@@ -227,12 +491,62 @@ func Test_mergeRouteParentStatus(t *testing.T) {
Conditions: []metav1.Condition{
{
Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
Status: metav1.ConditionFalse,
Reason: "SomeReason",
},
},
},
},
+ },
+ want: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway2",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionFalse,
+ Reason: "SomeReason",
+ },
+ },
+ },
+ },
+ },
+ {
+ name: "old contains one parentRef of ours, status of ours changed in new with an additional parentRef of ours",
+ args: args{
+ old: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway2",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ },
new: []gwapiv1.RouteParentStatus{
{
ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
@@ -242,18 +556,59 @@ func Test_mergeRouteParentStatus(t *testing.T) {
Conditions: []metav1.Condition{
{
Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
Status: metav1.ConditionFalse,
Reason: "SomeReason",
},
},
},
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway3",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
},
},
want: []gwapiv1.RouteParentStatus{
{
ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
ParentRef: gwapiv1.ParentReference{
- Name: "gateway1",
+ Name: "gateway2",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionFalse,
+ Reason: "SomeReason",
+ },
+ },
+ },
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway3",
},
Conditions: []metav1.Condition{
{
@@ -268,25 +623,105 @@ func Test_mergeRouteParentStatus(t *testing.T) {
},
},
},
+ },
+ },
+ {
+ name: "old contains one parentRef of ours, ours gets dropped in new and a different parentRef of ours is added",
+ args: args{
+ old: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway2",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ },
+ new: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway3",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ },
+ },
+ want: []gwapiv1.RouteParentStatus{
{
ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
ParentRef: gwapiv1.ParentReference{
- Name: "gateway2",
+ Name: "gateway3",
},
Conditions: []metav1.Condition{
{
Type: string(gwapiv1.RouteConditionAccepted),
- Status: metav1.ConditionFalse,
- Reason: "SomeReason",
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
+ },
+ },
+ },
+ },
+ // Similar note about practicality of occurrence.
+ {
+ name: "old contains one parentRef of ours, and it gets dropped in new.",
+ args: args{
+ old: []gwapiv1.RouteParentStatus{
+ {
+ ControllerName: "gateway.envoyproxy.io/gatewayclass-controller",
+ ParentRef: gwapiv1.ParentReference{
+ Name: "gateway2",
+ },
+ Conditions: []metav1.Condition{
+ {
+ Type: string(gwapiv1.RouteConditionAccepted),
+ Status: metav1.ConditionTrue,
+ Reason: "Accepted",
+ },
+ {
+ Type: string(gwapiv1.RouteConditionResolvedRefs),
+ Status: metav1.ConditionTrue,
+ Reason: "ResolvedRefs",
+ },
},
},
},
+ new: []gwapiv1.RouteParentStatus{},
},
+ want: []gwapiv1.RouteParentStatus{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- if got := mergeRouteParentStatus("default", tt.args.old, tt.args.new); !reflect.DeepEqual(got, tt.want) {
+ if got := mergeRouteParentStatus("default", "gateway.envoyproxy.io/gatewayclass-controller", tt.args.old, tt.args.new); !reflect.DeepEqual(got, tt.want) {
t.Errorf("mergeRouteParentStatus() = %v, want %v", got, tt.want)
}
})
diff --git a/internal/provider/kubernetes/topology_injector.go b/internal/provider/kubernetes/topology_injector.go
index 9a4edea229..c928dfe2f7 100644
--- a/internal/provider/kubernetes/topology_injector.go
+++ b/internal/provider/kubernetes/topology_injector.go
@@ -22,9 +22,9 @@ import (
type ProxyTopologyInjector struct {
client.Client
- Decoder admission.Decoder
-
- Logger logging.Logger
+ APIReader client.Reader
+ Decoder admission.Decoder
+ Logger logging.Logger
}
func (m *ProxyTopologyInjector) Handle(ctx context.Context, req admission.Request) admission.Response {
@@ -50,9 +50,13 @@ func (m *ProxyTopologyInjector) Handle(ctx context.Context, req admission.Reques
pod := &corev1.Pod{}
if err := m.Get(ctx, podName, pod); err != nil {
- logger.Error(err, "get pod failed", "pod", podName.String())
- topologyInjectorEventsTotal.WithFailure(metrics.ReasonError).Increment()
- return admission.Allowed("internal error, skipped")
+ // Cache isn't guaranteed to be updated yet so if m.Get() fails
+ // try getting the pod from API server directly.
+ if err = m.APIReader.Get(ctx, podName, pod); err != nil {
+ logger.Error(err, "get pod failed", "pod", podName.String())
+ topologyInjectorEventsTotal.WithFailure(metrics.ReasonError).Increment()
+ return admission.Allowed("internal error, skipped")
+ }
}
// Skip non-proxy pods
diff --git a/internal/utils/ratelimit/unit.go b/internal/utils/ratelimit/unit.go
index 94c8c7f6fb..3ee12170e3 100644
--- a/internal/utils/ratelimit/unit.go
+++ b/internal/utils/ratelimit/unit.go
@@ -24,6 +24,10 @@ func UnitToSeconds(unit egv1a1.RateLimitUnit) int64 {
seconds = 60 * 60
case egv1a1.RateLimitUnitDay:
seconds = 60 * 60 * 24
+ case egv1a1.RateLimitUnitMonth:
+ seconds = 60 * 60 * 24 * 30
+ case egv1a1.RateLimitUnitYear:
+ seconds = 60 * 60 * 24 * 365
}
return seconds
}
diff --git a/internal/xds/bootstrap/bootstrap.go b/internal/xds/bootstrap/bootstrap.go
index 3986dcf341..65d989a40e 100644
--- a/internal/xds/bootstrap/bootstrap.go
+++ b/internal/xds/bootstrap/bootstrap.go
@@ -99,6 +99,8 @@ type bootstrapParameters struct {
GatewayNamespaceMode bool
// ServiceClusterName is the generated name of the Envoy ServiceCluster.
ServiceClusterName string
+ // TopologyInjectorDisabled controls whether to render the local cluster for use with zone aware routing
+ TopologyInjectorDisabled bool
}
type serverParameters struct {
@@ -136,16 +138,17 @@ type overloadManagerParameters struct {
}
type RenderBootstrapConfigOptions struct {
- IPFamily *egv1a1.IPFamily
- ProxyMetrics *egv1a1.ProxyMetrics
- SdsConfig SdsConfigPath
- ServiceClusterName *string
- XdsServerHost *string
- XdsServerPort *int32
- AdminServerPort *int32
- StatsServerPort *int32
- MaxHeapSizeBytes uint64
- GatewayNamespaceMode bool
+ IPFamily *egv1a1.IPFamily
+ ProxyMetrics *egv1a1.ProxyMetrics
+ SdsConfig SdsConfigPath
+ ServiceClusterName *string
+ XdsServerHost *string
+ XdsServerPort *int32
+ AdminServerPort *int32
+ StatsServerPort *int32
+ MaxHeapSizeBytes uint64
+ GatewayNamespaceMode bool
+ TopologyInjectorDisabled bool
}
type SdsConfigPath struct {
@@ -307,6 +310,7 @@ func GetRenderedBootstrapConfig(opts *RenderBootstrapConfigOptions) (string, err
if opts.ServiceClusterName != nil {
cfg.parameters.ServiceClusterName = *opts.ServiceClusterName
}
+ cfg.parameters.TopologyInjectorDisabled = opts.TopologyInjectorDisabled
}
if err := cfg.render(); err != nil {
diff --git a/internal/xds/bootstrap/bootstrap.yaml.tpl b/internal/xds/bootstrap/bootstrap.yaml.tpl
index c951174c5d..e14a3d70b6 100644
--- a/internal/xds/bootstrap/bootstrap.yaml.tpl
+++ b/internal/xds/bootstrap/bootstrap.yaml.tpl
@@ -8,8 +8,10 @@ admin:
socket_address:
address: {{ .AdminServer.Address }}
port_value: {{ .AdminServer.Port }}
+{{- if not .TopologyInjectorDisabled }}
cluster_manager:
local_cluster_name: {{ .ServiceClusterName }}
+{{- end }}
node:
locality:
zone: $(ENVOY_SERVICE_ZONE)
@@ -171,6 +173,7 @@ static_resources:
address: {{ $sink.Address }}
port_value: {{ $sink.Port }}
{{- end }}
+ {{- if not .TopologyInjectorDisabled }}
- connect_timeout: 10s
eds_cluster_config:
eds_config:
@@ -188,6 +191,7 @@ static_resources:
min_cluster_size: '1'
name: {{ .ServiceClusterName }}
type: EDS
+ {{- end }}
- connect_timeout: 10s
load_assignment:
cluster_name: xds_cluster
diff --git a/internal/xds/bootstrap/bootstrap_test.go b/internal/xds/bootstrap/bootstrap_test.go
index 2c60748151..23bb6e0401 100644
--- a/internal/xds/bootstrap/bootstrap_test.go
+++ b/internal/xds/bootstrap/bootstrap_test.go
@@ -180,6 +180,30 @@ func TestGetRenderedBootstrapConfig(t *testing.T) {
IPFamily: ptr.To(egv1a1.IPv6),
},
},
+ {
+ name: "topology-injector-disabled",
+ opts: &RenderBootstrapConfigOptions{
+ ProxyMetrics: &egv1a1.ProxyMetrics{
+ Prometheus: &egv1a1.ProxyPrometheusProvider{
+ Disable: true,
+ },
+ },
+ SdsConfig: sds,
+ TopologyInjectorDisabled: true,
+ },
+ },
+ {
+ name: "topology-injector-enabled",
+ opts: &RenderBootstrapConfigOptions{
+ ProxyMetrics: &egv1a1.ProxyMetrics{
+ Prometheus: &egv1a1.ProxyPrometheusProvider{
+ Disable: true,
+ },
+ },
+ SdsConfig: sds,
+ TopologyInjectorDisabled: false,
+ },
+ },
}
for _, tc := range cases {
diff --git a/internal/xds/bootstrap/testdata/render/topology-injector-disabled.yaml b/internal/xds/bootstrap/testdata/render/topology-injector-disabled.yaml
new file mode 100644
index 0000000000..280a6d4ce1
--- /dev/null
+++ b/internal/xds/bootstrap/testdata/render/topology-injector-disabled.yaml
@@ -0,0 +1,84 @@
+admin:
+ access_log:
+ - name: envoy.access_loggers.file
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+ path: /dev/null
+ address:
+ socket_address:
+ address: 127.0.0.1
+ port_value: 19000
+node:
+ locality:
+ zone: $(ENVOY_SERVICE_ZONE)
+layered_runtime:
+ layers:
+ - name: global_config
+ static_layer:
+ envoy.restart_features.use_eds_cache_for_ads: true
+ re2.max_program_size.error_level: 4294967295
+ re2.max_program_size.warn_level: 1000
+dynamic_resources:
+ ads_config:
+ api_type: DELTA_GRPC
+ transport_api_version: V3
+ grpc_services:
+ - envoy_grpc:
+ cluster_name: xds_cluster
+ set_node_on_first_message_only: true
+ lds_config:
+ ads: {}
+ resource_api_version: V3
+ cds_config:
+ ads: {}
+ resource_api_version: V3
+static_resources:
+ clusters:
+ - connect_timeout: 10s
+ load_assignment:
+ cluster_name: xds_cluster
+ endpoints:
+ - load_balancing_weight: 1
+ lb_endpoints:
+ - load_balancing_weight: 1
+ endpoint:
+ address:
+ socket_address:
+ address: envoy-gateway
+ port_value: 18000
+ typed_extension_protocol_options:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions"
+ explicit_http_config:
+ http2_protocol_options:
+ connection_keepalive:
+ interval: 30s
+ timeout: 5s
+ name: xds_cluster
+ type: STRICT_DNS
+ transport_socket:
+ name: envoy.transport_sockets.tls
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ common_tls_context:
+ tls_params:
+ tls_maximum_protocol_version: TLSv1_3
+ tls_certificate_sds_secret_configs:
+ - name: xds_certificate
+ sds_config:
+ path_config_source:
+ path: /sds/xds-certificate.json
+ resource_api_version: V3
+ validation_context_sds_secret_config:
+ name: xds_trusted_ca
+ sds_config:
+ path_config_source:
+ path: /sds/xds-trusted-ca.json
+ resource_api_version: V3
+overload_manager:
+ refresh_interval: 0.25s
+ resource_monitors:
+ - name: "envoy.resource_monitors.global_downstream_max_connections"
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig
+ max_active_downstream_connections: 50000
diff --git a/internal/xds/bootstrap/testdata/render/topology-injector-enabled.yaml b/internal/xds/bootstrap/testdata/render/topology-injector-enabled.yaml
new file mode 100644
index 0000000000..2635d26d7b
--- /dev/null
+++ b/internal/xds/bootstrap/testdata/render/topology-injector-enabled.yaml
@@ -0,0 +1,103 @@
+admin:
+ access_log:
+ - name: envoy.access_loggers.file
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
+ path: /dev/null
+ address:
+ socket_address:
+ address: 127.0.0.1
+ port_value: 19000
+cluster_manager:
+ local_cluster_name: local_cluster
+node:
+ locality:
+ zone: $(ENVOY_SERVICE_ZONE)
+layered_runtime:
+ layers:
+ - name: global_config
+ static_layer:
+ envoy.restart_features.use_eds_cache_for_ads: true
+ re2.max_program_size.error_level: 4294967295
+ re2.max_program_size.warn_level: 1000
+dynamic_resources:
+ ads_config:
+ api_type: DELTA_GRPC
+ transport_api_version: V3
+ grpc_services:
+ - envoy_grpc:
+ cluster_name: xds_cluster
+ set_node_on_first_message_only: true
+ lds_config:
+ ads: {}
+ resource_api_version: V3
+ cds_config:
+ ads: {}
+ resource_api_version: V3
+static_resources:
+ clusters:
+ - connect_timeout: 10s
+ eds_cluster_config:
+ eds_config:
+ ads: {}
+ resource_api_version: 'V3'
+ service_name: local_cluster
+ load_balancing_policy:
+ policies:
+ - typed_extension_config:
+ name: 'envoy.load_balancing_policies.least_request'
+ typed_config:
+ '@type': 'type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest'
+ locality_lb_config:
+ zone_aware_lb_config:
+ min_cluster_size: '1'
+ name: local_cluster
+ type: EDS
+ - connect_timeout: 10s
+ load_assignment:
+ cluster_name: xds_cluster
+ endpoints:
+ - load_balancing_weight: 1
+ lb_endpoints:
+ - load_balancing_weight: 1
+ endpoint:
+ address:
+ socket_address:
+ address: envoy-gateway
+ port_value: 18000
+ typed_extension_protocol_options:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions"
+ explicit_http_config:
+ http2_protocol_options:
+ connection_keepalive:
+ interval: 30s
+ timeout: 5s
+ name: xds_cluster
+ type: STRICT_DNS
+ transport_socket:
+ name: envoy.transport_sockets.tls
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
+ common_tls_context:
+ tls_params:
+ tls_maximum_protocol_version: TLSv1_3
+ tls_certificate_sds_secret_configs:
+ - name: xds_certificate
+ sds_config:
+ path_config_source:
+ path: /sds/xds-certificate.json
+ resource_api_version: V3
+ validation_context_sds_secret_config:
+ name: xds_trusted_ca
+ sds_config:
+ path_config_source:
+ path: /sds/xds-trusted-ca.json
+ resource_api_version: V3
+overload_manager:
+ refresh_interval: 0.25s
+ resource_monitors:
+ - name: "envoy.resource_monitors.global_downstream_max_connections"
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig
+ max_active_downstream_connections: 50000
diff --git a/internal/xds/server/runner/runner.go b/internal/xds/runner/runner.go
similarity index 57%
rename from internal/xds/server/runner/runner.go
rename to internal/xds/runner/runner.go
index df47b9951c..51d172b358 100644
--- a/internal/xds/server/runner/runner.go
+++ b/internal/xds/runner/runner.go
@@ -10,6 +10,7 @@ import (
"crypto/tls"
"fmt"
"net"
+ "reflect"
"strconv"
"time"
@@ -25,15 +26,19 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/keepalive"
+ ktypes "k8s.io/apimachinery/pkg/types"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
"github.com/envoyproxy/gateway/internal/crypto"
"github.com/envoyproxy/gateway/internal/envoygateway/config"
+ extension "github.com/envoyproxy/gateway/internal/extension/types"
+ "github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/ratelimit"
+ "github.com/envoyproxy/gateway/internal/ir"
"github.com/envoyproxy/gateway/internal/message"
"github.com/envoyproxy/gateway/internal/xds/bootstrap"
"github.com/envoyproxy/gateway/internal/xds/cache"
"github.com/envoyproxy/gateway/internal/xds/server/kubejwt"
- xdstypes "github.com/envoyproxy/gateway/internal/xds/types"
+ "github.com/envoyproxy/gateway/internal/xds/translator"
)
const (
@@ -63,9 +68,15 @@ const (
type Config struct {
config.Server
- Xds *message.Xds
- grpc *grpc.Server
- cache cache.SnapshotCacheWithCallbacks
+ grpc *grpc.Server
+ cache cache.SnapshotCacheWithCallbacks
+ XdsIR *message.XdsIR
+ ExtensionManager extension.Manager
+ ProviderResources *message.ProviderResources
+ // Test-configurable TLS paths
+ TLSCertPath string
+ TLSKeyPath string
+ TLSCaPath string
}
type Runner struct {
@@ -77,7 +88,7 @@ func New(cfg *Config) *Runner {
}
func (r *Runner) Name() string {
- return string(egv1a1.LogComponentXdsServerRunner)
+ return string(egv1a1.LogComponentXdsRunner)
}
// Close implements Runner interface.
@@ -141,11 +152,10 @@ func (r *Runner) Start(ctx context.Context) (err error) {
// Start and listen xDS gRPC Server.
go r.serveXdsServer(ctx)
- // Start message Subscription.
// Do not call .Subscribe() inside Goroutine since it is supposed to be called from the same
// Goroutine where Close() is called.
- xdsSubCh := r.Xds.Subscribe(ctx)
- go r.subscribeAndTranslate(xdsSubCh)
+ sub := r.XdsIR.Subscribe(ctx)
+ go r.subscribeAndTranslate(sub)
r.Logger.Info("started")
return
}
@@ -186,51 +196,143 @@ func registerServer(srv serverv3.Server, g *grpc.Server) {
runtimev3.RegisterRuntimeDiscoveryServiceServer(g, srv)
}
-func (r *Runner) subscribeAndTranslate(sub <-chan watchable.Snapshot[string, *xdstypes.ResourceVersionTable]) {
- message.HandleSubscription(message.Metadata{Runner: r.Name(), Message: message.XDSMessageName}, sub,
- func(update message.Update[string, *xdstypes.ResourceVersionTable], errChan chan error) {
+func (r *Runner) subscribeAndTranslate(sub <-chan watchable.Snapshot[string, *ir.Xds]) {
+ // Subscribe to resources
+ message.HandleSubscription(message.Metadata{Runner: r.Name(), Message: message.XDSIRMessageName}, sub,
+ func(update message.Update[string, *ir.Xds], errChan chan error) {
+ r.Logger.Info("received an update")
key := update.Key
val := update.Value
- r.Logger.Info("received an update")
- var err error
if update.Delete {
- err = r.cache.GenerateNewSnapshot(key, nil)
- } else if val != nil && val.XdsResources != nil {
- if r.cache == nil {
- r.Logger.Error(err, "failed to init snapshot cache")
+ if err := r.cache.GenerateNewSnapshot(key, nil); err != nil {
+ r.Logger.Error(err, "failed to delete the snapshot")
errChan <- err
- } else {
- // Update snapshot cache
- err = r.cache.GenerateNewSnapshot(key, val.XdsResources)
}
- }
- if err != nil {
- r.Logger.Error(err, "failed to generate a snapshot")
- errChan <- err
+ } else {
+ // Translate to xds resources
+ t := &translator.Translator{
+ ControllerNamespace: r.ControllerNamespace,
+ FilterOrder: val.FilterOrder,
+ RuntimeFlags: r.EnvoyGateway.RuntimeFlags,
+ Logger: r.Logger,
+ }
+
+ // Set the extension manager if an extension is loaded
+ if r.ExtensionManager != nil {
+ t.ExtensionManager = &r.ExtensionManager
+ }
+
+ // Set the rate limit service URL if global rate limiting is enabled.
+ if r.EnvoyGateway.RateLimit != nil {
+ t.GlobalRateLimit = &translator.GlobalRateLimitSettings{
+ ServiceURL: ratelimit.GetServiceURL(r.ControllerNamespace, r.DNSDomain),
+ FailClosed: r.EnvoyGateway.RateLimit.FailClosed,
+ }
+ if r.EnvoyGateway.RateLimit.Timeout != nil {
+ d, err := time.ParseDuration(string(*r.EnvoyGateway.RateLimit.Timeout))
+ if err != nil {
+ r.Logger.Error(err, "invalid rateLimit timeout")
+ errChan <- err
+ } else {
+ t.GlobalRateLimit.Timeout = d
+ }
+ }
+ }
+
+ result, err := t.Translate(val)
+ if err != nil {
+ r.Logger.Error(err, "failed to translate xds ir")
+ errChan <- err
+ }
+
+ // xDS translation is done in a best-effort manner, so the result
+ // may contain partial resources even if there are errors.
+ if result == nil {
+ r.Logger.Info("no xds resources to publish")
+ return
+ }
+
+ // Get all status keys from watchable and save them in the map statusesToDelete.
+ // Iterating through result.EnvoyPatchPolicyStatuses, any valid keys will be removed from statusesToDelete.
+ // Remaining keys will be deleted from watchable before we exit this function.
+ statusesToDelete := make(map[ktypes.NamespacedName]bool)
+ for key := range r.ProviderResources.EnvoyPatchPolicyStatuses.LoadAll() {
+ statusesToDelete[key] = true
+ }
+
+ // Publish EnvoyPatchPolicyStatus
+ for _, e := range result.EnvoyPatchPolicyStatuses {
+ key := ktypes.NamespacedName{
+ Name: e.Name,
+ Namespace: e.Namespace,
+ }
+ // Skip updating status for policies with empty status
+ // They may have been skipped in this translation because
+ // their target is not found (not relevant)
+ if !(reflect.ValueOf(e.Status).IsZero()) {
+ r.ProviderResources.EnvoyPatchPolicyStatuses.Store(key, e.Status)
+ }
+ delete(statusesToDelete, key)
+ }
+ // Discard the EnvoyPatchPolicyStatuses to reduce memory footprint
+ result.EnvoyPatchPolicyStatuses = nil
+
+ // Update snapshot cache
+ if err == nil {
+ if result.XdsResources != nil {
+ if r.cache == nil {
+ r.Logger.Error(err, "failed to init snapshot cache")
+ errChan <- err
+ } else {
+ // Update snapshot cache
+ if err := r.cache.GenerateNewSnapshot(key, result.XdsResources); err != nil {
+ r.Logger.Error(err, "failed to generate a snapshot")
+ errChan <- err
+ }
+ }
+ } else {
+ r.Logger.Error(err, "skipped publishing xds resources")
+ }
+ }
+
+ // Delete all the deletable status keys
+ for key := range statusesToDelete {
+ r.ProviderResources.EnvoyPatchPolicyStatuses.Delete(key)
+ }
}
},
)
-
r.Logger.Info("subscriber shutting down")
}
func (r *Runner) loadTLSConfig() (tlsConfig *tls.Config, err error) {
- switch {
- case r.EnvoyGateway.Provider.IsRunningOnKubernetes():
- tlsConfig, err = crypto.LoadTLSConfig(xdsTLSCertFilepath, xdsTLSKeyFilepath, xdsTLSCaFilepath)
- if err != nil {
- return nil, fmt.Errorf("failed to create tls config: %w", err)
- }
+ var certPath, keyPath, caPath string
- case r.EnvoyGateway.Provider.IsRunningOnHost():
- tlsConfig, err = crypto.LoadTLSConfig(localTLSCertFilepath, localTLSKeyFilepath, localTLSCaFilepath)
- if err != nil {
- return nil, fmt.Errorf("failed to create tls config: %w", err)
+ // Use test-configurable paths if provided
+ if r.TLSCertPath != "" && r.TLSKeyPath != "" && r.TLSCaPath != "" {
+ certPath = r.TLSCertPath
+ keyPath = r.TLSKeyPath
+ caPath = r.TLSCaPath
+ } else {
+ // Use default paths based on provider type
+ switch {
+ case r.EnvoyGateway.Provider.IsRunningOnKubernetes():
+ certPath = xdsTLSCertFilepath
+ keyPath = xdsTLSKeyFilepath
+ caPath = xdsTLSCaFilepath
+ case r.EnvoyGateway.Provider.IsRunningOnHost():
+ certPath = localTLSCertFilepath
+ keyPath = localTLSKeyFilepath
+ caPath = localTLSCaFilepath
+ default:
+ return nil, fmt.Errorf("no valid tls certificates")
}
+ }
- default:
- return nil, fmt.Errorf("no valid tls certificates")
+ tlsConfig, err = crypto.LoadTLSConfig(certPath, keyPath, caPath)
+ if err != nil {
+ return nil, fmt.Errorf("failed to create tls config: %w", err)
}
return
}
diff --git a/internal/xds/runner/runner_test.go b/internal/xds/runner/runner_test.go
new file mode 100644
index 0000000000..cbcc7fb823
--- /dev/null
+++ b/internal/xds/runner/runner_test.go
@@ -0,0 +1,513 @@
+// 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 runner
+
+import (
+ "context"
+ "crypto/tls"
+ "crypto/x509"
+ "errors"
+ "fmt"
+ "io"
+ "net"
+ "os"
+ "path/filepath"
+ "strconv"
+ "testing"
+ "time"
+
+ listenerv3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+ "github.com/tsaarni/certyaml"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/credentials"
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+
+ egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+ "github.com/envoyproxy/gateway/internal/crypto"
+ "github.com/envoyproxy/gateway/internal/envoygateway/config"
+ "github.com/envoyproxy/gateway/internal/extension/types"
+ "github.com/envoyproxy/gateway/internal/ir"
+ "github.com/envoyproxy/gateway/internal/message"
+ "github.com/envoyproxy/gateway/internal/xds/bootstrap"
+)
+
+func TestTLSConfig(t *testing.T) {
+ // Create trusted CA, server and client certs.
+ trustedCACert := certyaml.Certificate{
+ Subject: "cn=trusted-ca",
+ }
+ egCertBeforeRotation := certyaml.Certificate{
+ Subject: "cn=eg-before-rotation",
+ SubjectAltNames: []string{"DNS:localhost"},
+ Issuer: &trustedCACert,
+ }
+ egCertAfterRotation := certyaml.Certificate{
+ Subject: "cn=eg-after-rotation",
+ SubjectAltNames: []string{"DNS:localhost"},
+ Issuer: &trustedCACert,
+ }
+ trustedEnvoyCert := certyaml.Certificate{
+ Subject: "cn=trusted-envoy",
+ Issuer: &trustedCACert,
+ }
+
+ // Create another CA and a client cert to test that untrusted clients are denied.
+ untrustedCACert := certyaml.Certificate{
+ Subject: "cn=untrusted-ca",
+ }
+ untrustedClientCert := certyaml.Certificate{
+ Subject: "cn=untrusted-client",
+ Issuer: &untrustedCACert,
+ }
+
+ caCertPool := x509.NewCertPool()
+ ca, err := trustedCACert.X509Certificate()
+ require.NoError(t, err)
+ caCertPool.AddCert(&ca)
+
+ tests := map[string]struct {
+ serverCredentials *certyaml.Certificate
+ clientCredentials *certyaml.Certificate
+ expectError bool
+ }{
+ "successful TLS connection established": {
+ serverCredentials: &egCertBeforeRotation,
+ clientCredentials: &trustedEnvoyCert,
+ expectError: false,
+ },
+ "rotating server credentials returns new server cert": {
+ serverCredentials: &egCertAfterRotation,
+ clientCredentials: &trustedEnvoyCert,
+ expectError: false,
+ },
+ "rotating server credentials again to ensure rotation can be repeated": {
+ serverCredentials: &egCertBeforeRotation,
+ clientCredentials: &trustedEnvoyCert,
+ expectError: false,
+ },
+ "fail to connect with client certificate which is not signed by correct CA": {
+ serverCredentials: &egCertBeforeRotation,
+ clientCredentials: &untrustedClientCert,
+ expectError: true,
+ },
+ }
+
+ // Create temporary directory to store certificates and key for the server.
+ configDir, err := os.MkdirTemp("", "eg-testdata-")
+ require.NoError(t, err)
+ defer os.RemoveAll(configDir)
+
+ caFile := filepath.Join(configDir, "ca.crt")
+ certFile := filepath.Join(configDir, "tls.crt")
+ keyFile := filepath.Join(configDir, "tls.key")
+
+ // Initial set of credentials must be written into temp directory before
+ // starting the tests to avoid error at server startup.
+ err = trustedCACert.WritePEM(caFile, keyFile)
+ require.NoError(t, err)
+ err = egCertBeforeRotation.WritePEM(certFile, keyFile)
+ require.NoError(t, err)
+
+ // Start a dummy server.
+ tlsCfg, err := crypto.LoadTLSConfig(certFile, keyFile, caFile)
+ require.NoError(t, err)
+
+ g := grpc.NewServer(grpc.Creds(credentials.NewTLS(tlsCfg)))
+ if g == nil {
+ t.Error("failed to create server")
+ }
+
+ address := "localhost:8001"
+ l, err := net.Listen("tcp", address)
+ require.NoError(t, err)
+
+ go func() {
+ err := g.Serve(l)
+ require.NoError(t, err)
+ }()
+ defer g.GracefulStop()
+
+ for name, tc := range tests {
+ t.Run(name, func(t *testing.T) {
+ // Store certificate and key to temp dir used by serveContext.
+ err = tc.serverCredentials.WritePEM(certFile, keyFile)
+ require.NoError(t, err)
+ clientCert, _ := tc.clientCredentials.TLSCertificate()
+ receivedCert, err := tryConnect(address, clientCert, caCertPool)
+ gotError := err != nil
+ if gotError != tc.expectError {
+ t.Errorf("Unexpected result when connecting to the server: %s", err)
+ }
+ if err == nil {
+ expectedCert, _ := tc.serverCredentials.X509Certificate()
+ assert.Equal(t, &expectedCert, receivedCert)
+ }
+ })
+ }
+}
+
+// tryConnect tries to establish TLS connection to the server.
+// If successful, return the server certificate.
+func tryConnect(address string, clientCert tls.Certificate, caCertPool *x509.CertPool) (*x509.Certificate, error) {
+ clientConfig := &tls.Config{
+ ServerName: "localhost",
+ MinVersion: tls.VersionTLS13,
+ Certificates: []tls.Certificate{clientCert},
+ NextProtos: []string{"h2"},
+ RootCAs: caCertPool,
+ }
+ conn, err := tls.Dial("tcp", address, clientConfig)
+ if err != nil {
+ return nil, err
+ }
+ defer conn.Close()
+
+ err = peekError(conn)
+ if err != nil {
+ return nil, err
+ }
+
+ return conn.ConnectionState().PeerCertificates[0], nil
+}
+
+// peekError is a workaround for TLS 1.3: due to shortened handshake, TLS alert
+// from server is received at first read from the socket. To receive alert for
+// bad certificate, this function tries to read one byte.
+// Adapted from https://golang.org/src/crypto/tls/handshake_client_test.go
+func peekError(conn net.Conn) error {
+ _ = conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
+ _, err := conn.Read(make([]byte, 1))
+ if err != nil {
+ if errors.Is(err, io.EOF) {
+ return nil
+ }
+
+ var netErr net.Error
+ if !errors.As(netErr, &netErr) || !netErr.Timeout() {
+ return err
+ }
+ }
+ return nil
+}
+
+// setupTLSCerts creates temporary TLS certificates for testing
+func setupTLSCerts(t *testing.T) (caFile, certFile, keyFile string, cleanup func()) {
+ configDir, err := os.MkdirTemp("", "eg-runner-test-")
+ require.NoError(t, err)
+
+ caFile = filepath.Join(configDir, "ca.crt")
+ certFile = filepath.Join(configDir, "tls.crt")
+ keyFile = filepath.Join(configDir, "tls.key")
+
+ // Create certificates
+ trustedCACert := certyaml.Certificate{
+ Subject: "cn=test-ca",
+ }
+ serverCert := certyaml.Certificate{
+ Subject: "cn=test-server",
+ SubjectAltNames: []string{"DNS:localhost"},
+ Issuer: &trustedCACert,
+ }
+
+ err = trustedCACert.WritePEM(caFile, keyFile)
+ require.NoError(t, err)
+ err = serverCert.WritePEM(certFile, keyFile)
+ require.NoError(t, err)
+
+ return caFile, certFile, keyFile, func() {
+ os.RemoveAll(configDir)
+ }
+}
+
+func TestServeXdsServerListenFailed(t *testing.T) {
+ // Occupy the address to make listening failed
+ addr := net.JoinHostPort(XdsServerAddress, strconv.Itoa(bootstrap.DefaultXdsServerPort))
+ l, err := net.Listen("tcp", addr)
+ require.NoError(t, err)
+ defer l.Close()
+
+ cfg, _ := config.New(os.Stdout)
+ r := New(&Config{
+ Server: *cfg,
+ })
+ r.Logger = r.Logger.WithName(r.Name()).WithValues("runner", r.Name())
+ // Don't crash in this function
+ r.serveXdsServer(context.Background())
+}
+
+func TestRunner(t *testing.T) {
+ // Setup TLS certificates
+ caFile, certFile, keyFile, cleanup := setupTLSCerts(t)
+ defer cleanup()
+
+ // Setup
+ xdsIR := new(message.XdsIR)
+ pResource := new(message.ProviderResources)
+ cfg, err := config.New(os.Stdout)
+ require.NoError(t, err)
+ r := New(&Config{
+ Server: *cfg,
+ ProviderResources: pResource,
+ XdsIR: xdsIR,
+ TLSCertPath: certFile,
+ TLSKeyPath: keyFile,
+ TLSCaPath: caFile,
+ })
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ // Start
+ err = r.Start(ctx)
+ require.NoError(t, err)
+ defer func() {
+ cancel()
+ time.Sleep(100 * time.Millisecond) // Allow graceful shutdown
+ }()
+
+ // xDS is nil at start
+ require.Equal(t, map[string]*ir.Xds{}, xdsIR.LoadAll())
+
+ // test translation
+ path := "example"
+ res := ir.Xds{
+ HTTP: []*ir.HTTPListener{
+ {
+ CoreListenerDetails: ir.CoreListenerDetails{
+ Name: "test",
+ Address: "0.0.0.0",
+ Port: 80,
+ },
+ Hostnames: []string{"example.com"},
+ Routes: []*ir.HTTPRoute{
+ {
+ Name: "test-route",
+ PathMatch: &ir.StringMatch{
+ Exact: &path,
+ },
+ Destination: &ir.RouteDestination{
+ Name: "test-dest",
+ Settings: []*ir.DestinationSetting{
+ {
+ Endpoints: []*ir.DestinationEndpoint{
+ {
+ Host: "10.11.12.13",
+ Port: 8080,
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+ xdsIR.Store("test", &res)
+ require.Eventually(t, func() bool {
+ // Check that the cache has the snapshot for our test key
+ return r.cache.SnapshotHasIrKey("test")
+ }, time.Second*5, time.Millisecond*50)
+
+ // Delete the IR triggering an xds delete
+ xdsIR.Delete("test")
+ require.Eventually(t, func() bool {
+ // Wait for the IR to be empty after deletion
+ return len(xdsIR.LoadAll()) == 0
+ }, time.Second*5, time.Millisecond*50)
+}
+
+func TestRunner_withExtensionManager_FailOpen(t *testing.T) {
+ // Setup TLS certificates
+ caFile, certFile, keyFile, cleanup := setupTLSCerts(t)
+ defer cleanup()
+
+ // Setup
+ xdsIR := new(message.XdsIR)
+ pResource := new(message.ProviderResources)
+
+ cfg, err := config.New(os.Stdout)
+ require.NoError(t, err)
+ require.NotNil(t, cfg)
+
+ extMgr := &extManagerMock{}
+ extMgr.ShouldFailOpen = true
+
+ r := New(&Config{
+ Server: *cfg,
+ ProviderResources: pResource,
+ XdsIR: xdsIR,
+ ExtensionManager: extMgr,
+ TLSCertPath: certFile,
+ TLSKeyPath: keyFile,
+ TLSCaPath: caFile,
+ })
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ // Start
+ err = r.Start(ctx)
+ require.NoError(t, err)
+ defer func() {
+ cancel()
+ time.Sleep(100 * time.Millisecond) // Allow graceful shutdown
+ }()
+
+ // xDS is nil at start
+ require.Equal(t, map[string]*ir.Xds{}, xdsIR.LoadAll())
+
+ // test translation
+ path := "example"
+ res := ir.Xds{
+ HTTP: []*ir.HTTPListener{
+ {
+ CoreListenerDetails: ir.CoreListenerDetails{
+ Name: "test",
+ Address: "0.0.0.0",
+ Port: 80,
+ },
+ Hostnames: []string{"example.com"},
+ Routes: []*ir.HTTPRoute{
+ {
+ Name: "test-route",
+ PathMatch: &ir.StringMatch{
+ Exact: &path,
+ },
+ Destination: &ir.RouteDestination{
+ Name: "test-dest",
+ Settings: []*ir.DestinationSetting{
+ {
+ Endpoints: []*ir.DestinationEndpoint{
+ {
+ Host: "10.11.12.13",
+ Port: 8080,
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+ xdsIR.Store("test", &res)
+ require.Eventually(t, func() bool {
+ // Since the extension manager is configured to fail open, in an event of an error
+ // from the extension manager hooks, xds update should be published.
+ return r.cache.SnapshotHasIrKey("test")
+ }, time.Second*5, time.Millisecond*50)
+}
+
+func TestRunner_withExtensionManager_FailClosed(t *testing.T) {
+ // Setup TLS certificates
+ caFile, certFile, keyFile, cleanup := setupTLSCerts(t)
+ defer cleanup()
+
+ // Setup
+ xdsIR := new(message.XdsIR)
+ pResource := new(message.ProviderResources)
+
+ cfg, err := config.New(os.Stdout)
+ require.NoError(t, err)
+ require.NotNil(t, cfg)
+
+ extMgr := &extManagerMock{}
+
+ r := New(&Config{
+ Server: *cfg,
+ ProviderResources: pResource,
+ XdsIR: xdsIR,
+ ExtensionManager: extMgr,
+ TLSCertPath: certFile,
+ TLSKeyPath: keyFile,
+ TLSCaPath: caFile,
+ })
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ // Start
+ err = r.Start(ctx)
+ require.NoError(t, err)
+ defer func() {
+ cancel()
+ time.Sleep(100 * time.Millisecond) // Allow graceful shutdown
+ }()
+
+ // xDS is nil at start
+ require.Equal(t, map[string]*ir.Xds{}, xdsIR.LoadAll())
+
+ // test translation
+ path := "example"
+ res := ir.Xds{
+ HTTP: []*ir.HTTPListener{
+ {
+ CoreListenerDetails: ir.CoreListenerDetails{
+ Name: "test",
+ Address: "0.0.0.0",
+ Port: 80,
+ },
+ Hostnames: []string{"example.com"},
+ Routes: []*ir.HTTPRoute{
+ {
+ Name: "test-route",
+ PathMatch: &ir.StringMatch{
+ Exact: &path,
+ },
+ Destination: &ir.RouteDestination{
+ Name: "test-dest",
+ Settings: []*ir.DestinationSetting{
+ {
+ Endpoints: []*ir.DestinationEndpoint{
+ {
+ Host: "10.11.12.13",
+ Port: 8080,
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+ xdsIR.Store("test", &res)
+ require.Never(t, func() bool {
+ // Since the extension manager is configured to fail closed, in an event of an error
+ // from the extension manager hooks, xds update should not be published.
+ return r.cache.SnapshotHasIrKey("test")
+ }, time.Second*5, time.Millisecond*50)
+}
+
+type extManagerMock struct {
+ types.Manager
+ ShouldFailOpen bool
+}
+
+func (m *extManagerMock) GetPostXDSHookClient(xdsHookType egv1a1.XDSTranslatorHook) (types.XDSHookClient, error) {
+ if xdsHookType == egv1a1.XDSHTTPListener {
+ return &xdsHookClientMock{}, nil
+ }
+
+ return nil, nil
+}
+
+func (m *extManagerMock) FailOpen() bool {
+ return m.ShouldFailOpen
+}
+
+type xdsHookClientMock struct {
+ types.XDSHookClient
+}
+
+func (c *xdsHookClientMock) PostHTTPListenerModifyHook(*listenerv3.Listener, []*unstructured.Unstructured) (*listenerv3.Listener, error) {
+ return nil, fmt.Errorf("assuming a network error during the call")
+}
diff --git a/internal/xds/server/runner/runner_test.go b/internal/xds/server/runner/runner_test.go
deleted file mode 100644
index 69dd798b81..0000000000
--- a/internal/xds/server/runner/runner_test.go
+++ /dev/null
@@ -1,205 +0,0 @@
-// 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 runner
-
-import (
- "context"
- "crypto/tls"
- "crypto/x509"
- "errors"
- "io"
- "net"
- "os"
- "path/filepath"
- "strconv"
- "testing"
- "time"
-
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
- "github.com/tsaarni/certyaml"
- "google.golang.org/grpc"
- "google.golang.org/grpc/credentials"
-
- "github.com/envoyproxy/gateway/internal/crypto"
- "github.com/envoyproxy/gateway/internal/envoygateway/config"
- "github.com/envoyproxy/gateway/internal/xds/bootstrap"
-)
-
-func TestTLSConfig(t *testing.T) {
- // Create trusted CA, server and client certs.
- trustedCACert := certyaml.Certificate{
- Subject: "cn=trusted-ca",
- }
- egCertBeforeRotation := certyaml.Certificate{
- Subject: "cn=eg-before-rotation",
- SubjectAltNames: []string{"DNS:localhost"},
- Issuer: &trustedCACert,
- }
- egCertAfterRotation := certyaml.Certificate{
- Subject: "cn=eg-after-rotation",
- SubjectAltNames: []string{"DNS:localhost"},
- Issuer: &trustedCACert,
- }
- trustedEnvoyCert := certyaml.Certificate{
- Subject: "cn=trusted-envoy",
- Issuer: &trustedCACert,
- }
-
- // Create another CA and a client cert to test that untrusted clients are denied.
- untrustedCACert := certyaml.Certificate{
- Subject: "cn=untrusted-ca",
- }
- untrustedClientCert := certyaml.Certificate{
- Subject: "cn=untrusted-client",
- Issuer: &untrustedCACert,
- }
-
- caCertPool := x509.NewCertPool()
- ca, err := trustedCACert.X509Certificate()
- require.NoError(t, err)
- caCertPool.AddCert(&ca)
-
- tests := map[string]struct {
- serverCredentials *certyaml.Certificate
- clientCredentials *certyaml.Certificate
- expectError bool
- }{
- "successful TLS connection established": {
- serverCredentials: &egCertBeforeRotation,
- clientCredentials: &trustedEnvoyCert,
- expectError: false,
- },
- "rotating server credentials returns new server cert": {
- serverCredentials: &egCertAfterRotation,
- clientCredentials: &trustedEnvoyCert,
- expectError: false,
- },
- "rotating server credentials again to ensure rotation can be repeated": {
- serverCredentials: &egCertBeforeRotation,
- clientCredentials: &trustedEnvoyCert,
- expectError: false,
- },
- "fail to connect with client certificate which is not signed by correct CA": {
- serverCredentials: &egCertBeforeRotation,
- clientCredentials: &untrustedClientCert,
- expectError: true,
- },
- }
-
- // Create temporary directory to store certificates and key for the server.
- configDir, err := os.MkdirTemp("", "eg-testdata-")
- require.NoError(t, err)
- defer os.RemoveAll(configDir)
-
- caFile := filepath.Join(configDir, "ca.crt")
- certFile := filepath.Join(configDir, "tls.crt")
- keyFile := filepath.Join(configDir, "tls.key")
-
- // Initial set of credentials must be written into temp directory before
- // starting the tests to avoid error at server startup.
- err = trustedCACert.WritePEM(caFile, keyFile)
- require.NoError(t, err)
- err = egCertBeforeRotation.WritePEM(certFile, keyFile)
- require.NoError(t, err)
-
- // Start a dummy server.
- tlsCfg, err := crypto.LoadTLSConfig(certFile, keyFile, caFile)
- require.NoError(t, err)
-
- g := grpc.NewServer(grpc.Creds(credentials.NewTLS(tlsCfg)))
- if g == nil {
- t.Error("failed to create server")
- }
-
- address := "localhost:8001"
- l, err := net.Listen("tcp", address)
- require.NoError(t, err)
-
- go func() {
- err := g.Serve(l)
- require.NoError(t, err)
- }()
- defer g.GracefulStop()
-
- for name, tc := range tests {
- t.Run(name, func(t *testing.T) {
- // Store certificate and key to temp dir used by serveContext.
- err = tc.serverCredentials.WritePEM(certFile, keyFile)
- require.NoError(t, err)
- clientCert, _ := tc.clientCredentials.TLSCertificate()
- receivedCert, err := tryConnect(address, clientCert, caCertPool)
- gotError := err != nil
- if gotError != tc.expectError {
- t.Errorf("Unexpected result when connecting to the server: %s", err)
- }
- if err == nil {
- expectedCert, _ := tc.serverCredentials.X509Certificate()
- assert.Equal(t, &expectedCert, receivedCert)
- }
- })
- }
-}
-
-// tryConnect tries to establish TLS connection to the server.
-// If successful, return the server certificate.
-func tryConnect(address string, clientCert tls.Certificate, caCertPool *x509.CertPool) (*x509.Certificate, error) {
- clientConfig := &tls.Config{
- ServerName: "localhost",
- MinVersion: tls.VersionTLS13,
- Certificates: []tls.Certificate{clientCert},
- NextProtos: []string{"h2"},
- RootCAs: caCertPool,
- }
- conn, err := tls.Dial("tcp", address, clientConfig)
- if err != nil {
- return nil, err
- }
- defer conn.Close()
-
- err = peekError(conn)
- if err != nil {
- return nil, err
- }
-
- return conn.ConnectionState().PeerCertificates[0], nil
-}
-
-// peekError is a workaround for TLS 1.3: due to shortened handshake, TLS alert
-// from server is received at first read from the socket. To receive alert for
-// bad certificate, this function tries to read one byte.
-// Adapted from https://golang.org/src/crypto/tls/handshake_client_test.go
-func peekError(conn net.Conn) error {
- _ = conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
- _, err := conn.Read(make([]byte, 1))
- if err != nil {
- if errors.Is(err, io.EOF) {
- return nil
- }
-
- var netErr net.Error
- if !errors.As(netErr, &netErr) || !netErr.Timeout() {
- return err
- }
- }
- return nil
-}
-
-func TestServeXdsServerListenFailed(t *testing.T) {
- // Occupy the address to make listening failed
- addr := net.JoinHostPort(XdsServerAddress, strconv.Itoa(bootstrap.DefaultXdsServerPort))
- l, err := net.Listen("tcp", addr)
- require.NoError(t, err)
- defer l.Close()
-
- cfg, _ := config.New(os.Stdout)
- r := New(&Config{
- Server: *cfg,
- })
- r.Logger = r.Logger.WithName(r.Name()).WithValues("runner", r.Name())
- // Don't crash in this function
- r.serveXdsServer(context.Background())
-}
diff --git a/internal/xds/translator/cluster.go b/internal/xds/translator/cluster.go
index 3aa5d49520..a4b98ee6b2 100644
--- a/internal/xds/translator/cluster.go
+++ b/internal/xds/translator/cluster.go
@@ -422,9 +422,7 @@ func buildXdsCluster(args *xdsClusterArgs) (*buildClusterResult, error) {
cluster.RespectDnsTtl = true
if args.dns != nil {
if args.dns.DNSRefreshRate != nil {
- if args.dns.DNSRefreshRate.Duration > 0 {
- cluster.DnsRefreshRate = durationpb.New(args.dns.DNSRefreshRate.Duration)
- }
+ cluster.DnsRefreshRate = durationpb.New(args.dns.DNSRefreshRate.Duration)
}
if args.dns.RespectDNSTTL != nil {
cluster.RespectDnsTtl = ptr.Deref(args.dns.RespectDNSTTL, true)
diff --git a/internal/xds/translator/httpfilters.go b/internal/xds/translator/httpfilters.go
index a5e0a25c16..ff68e89d2c 100644
--- a/internal/xds/translator/httpfilters.go
+++ b/internal/xds/translator/httpfilters.go
@@ -130,14 +130,18 @@ func newOrderedHTTPFilter(filter *hcmv3.HttpFilter) *OrderedHTTPFilter {
order = 302
case isFilterType(filter, egv1a1.EnvoyFilterRateLimit):
order = 303
- case isFilterType(filter, egv1a1.EnvoyFilterCustomResponse):
+ case isFilterType(filter, egv1a1.EnvoyFilterGRPCWeb):
order = 304
- case isFilterType(filter, egv1a1.EnvoyFilterCredentialInjector):
+ case isFilterType(filter, egv1a1.EnvoyFilterGRPCStats):
order = 305
- case isFilterType(filter, egv1a1.EnvoyFilterCompressor):
+ case isFilterType(filter, egv1a1.EnvoyFilterCustomResponse):
order = 306
- case isFilterType(filter, egv1a1.EnvoyFilterRouter):
+ case isFilterType(filter, egv1a1.EnvoyFilterCredentialInjector):
order = 307
+ case isFilterType(filter, egv1a1.EnvoyFilterCompressor):
+ order = 308
+ case isFilterType(filter, egv1a1.EnvoyFilterRouter):
+ order = 309
}
return &OrderedHTTPFilter{
diff --git a/internal/xds/translator/listener.go b/internal/xds/translator/listener.go
index f02784e29d..943e46cc5e 100644
--- a/internal/xds/translator/listener.go
+++ b/internal/xds/translator/listener.go
@@ -335,23 +335,13 @@ func (t *Translator) addHCMToXDSListener(
}
// HTTP filter configuration
- var statPrefix string
- if irListener.TLS != nil {
- statPrefix = "https"
- } else {
- statPrefix = "http"
- }
-
- // Append port to the statPrefix.
- statPrefix = strings.Join([]string{statPrefix, strconv.Itoa(int(irListener.Port))}, "-")
-
// Client IP detection
useRemoteAddress := true
originalIPDetectionExtensions := originalIPDetectionExtensions(irListener.ClientIPDetection)
if originalIPDetectionExtensions != nil {
useRemoteAddress = false
}
-
+ statPrefix := hcmStatPrefix(irListener, t.xdsNameSchemeV2())
mgr := &hcmv3.HttpConnectionManager{
AccessLog: al,
CodecType: hcmv3.HttpConnectionManager_AUTO,
@@ -360,7 +350,7 @@ func (t *Translator) addHCMToXDSListener(
Rds: &hcmv3.Rds{
ConfigSource: makeConfigSource(),
// Configure route name to be found via RDS.
- RouteConfigName: routeConfigName(irListener),
+ RouteConfigName: routeConfigName(irListener, t.xdsNameSchemeV2()),
},
},
HttpProtocolOptions: http1ProtocolOptions(irListener.HTTP1),
@@ -500,9 +490,24 @@ func (t *Translator) addHCMToXDSListener(
return nil
}
-func routeConfigName(irListener *ir.HTTPListener) string {
- // TODO(zhaohuabing): change the routeConfig name for HTTP listeners because they are merged into one route config
- return irListener.Name
+func hcmStatPrefix(irListener *ir.HTTPListener, nameSchemeV2 bool) string {
+ statPrefix := "http"
+ if irListener.TLS != nil {
+ statPrefix = "https"
+ }
+
+ if nameSchemeV2 {
+ return fmt.Sprintf("%s-%d", statPrefix, irListener.ExternalPort)
+ }
+ return fmt.Sprintf("%s-%d", statPrefix, irListener.Port)
+}
+
+// use the same name for the route config as the filter chain name, as they're 1:1 mapping.
+func routeConfigName(irListener *ir.HTTPListener, nameSchemeV2 bool) string {
+ if irListener.TLS != nil {
+ return httpsListenerFilterChainName(irListener)
+ }
+ return httpListenerDefaultFilterChainName(irListener, nameSchemeV2)
}
// port value is used for the default filter chain name for HTTP listeners, as multiple HTTP listeners are merged into
@@ -515,7 +520,7 @@ func httpListenerDefaultFilterChainName(irListener *ir.HTTPListener, nameSchemeV
return irListener.Name
}
-// irListener name is used as the filter chain name for HTTPS listener, as Listener is 1:1 mapping to the filter chain
+// irListener name is used as the filter chain name for HTTPS listener, as HTTPS Listener is 1:1 mapping to the filter chain.
// The Gateway API layer ensures that each listener has a unique combination of hostname and port.
func httpsListenerFilterChainName(irListener *ir.HTTPListener) string {
return irListener.Name
diff --git a/internal/xds/translator/proxy_protocol.go b/internal/xds/translator/proxy_protocol.go
index 453cb0ed29..ada9bd3017 100644
--- a/internal/xds/translator/proxy_protocol.go
+++ b/internal/xds/translator/proxy_protocol.go
@@ -6,6 +6,8 @@
package translator
import (
+ "slices"
+
listenerv3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
proxyprotocolv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/listener/proxy_protocol/v3"
"github.com/envoyproxy/go-control-plane/pkg/wellknown"
@@ -37,7 +39,7 @@ func patchProxyProtocolFilter(xdsListener *listenerv3.Listener, proxyProtocolSet
// Build and patch the Proxy Protocol Filter.
filter := buildProxyProtocolFilter(proxyProtocolSettings)
if filter != nil {
- xdsListener.ListenerFilters = append(xdsListener.ListenerFilters, filter)
+ xdsListener.ListenerFilters = slices.Insert(xdsListener.ListenerFilters, 0, filter)
}
}
diff --git a/internal/xds/translator/route.go b/internal/xds/translator/route.go
index f07f80d8ea..5cda9f0634 100644
--- a/internal/xds/translator/route.go
+++ b/internal/xds/translator/route.go
@@ -626,7 +626,11 @@ func buildHashPolicy(httpRoute *ir.HTTPRoute) []*routev3.RouteAction_HashPolicy
},
}
if ch.Cookie.TTL != nil {
- hashPolicy.GetCookie().Ttl = durationpb.New(ch.Cookie.TTL.Duration)
+ d, err := time.ParseDuration(string(*ch.Cookie.TTL))
+ if err != nil {
+ return nil
+ }
+ hashPolicy.GetCookie().Ttl = durationpb.New(d)
}
if ch.Cookie.Attributes != nil {
attributes := make([]*routev3.RouteAction_HashPolicy_CookieAttribute, 0, len(ch.Cookie.Attributes))
diff --git a/internal/xds/translator/runner/runner.go b/internal/xds/translator/runner/runner.go
deleted file mode 100644
index c3e33c1969..0000000000
--- a/internal/xds/translator/runner/runner.go
+++ /dev/null
@@ -1,151 +0,0 @@
-// 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 runner
-
-import (
- "context"
- "reflect"
-
- "github.com/telepresenceio/watchable"
- ktypes "k8s.io/apimachinery/pkg/types"
-
- egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
- "github.com/envoyproxy/gateway/internal/envoygateway/config"
- extension "github.com/envoyproxy/gateway/internal/extension/types"
- "github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/ratelimit"
- "github.com/envoyproxy/gateway/internal/ir"
- "github.com/envoyproxy/gateway/internal/message"
- "github.com/envoyproxy/gateway/internal/xds/translator"
-)
-
-type Config struct {
- config.Server
- XdsIR *message.XdsIR
- Xds *message.Xds
- ExtensionManager extension.Manager
- ProviderResources *message.ProviderResources
-}
-
-type Runner struct {
- Config
-}
-
-func New(cfg *Config) *Runner {
- return &Runner{Config: *cfg}
-}
-
-// Close implements Runner interface.
-func (r *Runner) Close() error { return nil }
-
-// Name implements Runner interface.
-func (r *Runner) Name() string {
- return string(egv1a1.LogComponentXdsTranslatorRunner)
-}
-
-// Start starts the xds-translator runner
-func (r *Runner) Start(ctx context.Context) (err error) {
- r.Logger = r.Logger.WithName(r.Name()).WithValues("runner", r.Name())
- // Do not call .Subscribe() inside Goroutine since it is supposed to be called from the same
- // Goroutine where Close() is called.
- sub := r.XdsIR.Subscribe(ctx)
- go r.subscribeAndTranslate(sub)
- r.Logger.Info("started")
- return
-}
-
-func (r *Runner) subscribeAndTranslate(sub <-chan watchable.Snapshot[string, *ir.Xds]) {
- // Subscribe to resources
- message.HandleSubscription(message.Metadata{Runner: r.Name(), Message: message.XDSIRMessageName}, sub,
- func(update message.Update[string, *ir.Xds], errChan chan error) {
- r.Logger.Info("received an update")
- key := update.Key
- val := update.Value
-
- if update.Delete {
- r.Xds.Delete(key)
- } else {
- // Translate to xds resources
- t := &translator.Translator{
- ControllerNamespace: r.ControllerNamespace,
- FilterOrder: val.FilterOrder,
- RuntimeFlags: r.EnvoyGateway.RuntimeFlags,
- Logger: r.Logger,
- }
-
- // Set the extension manager if an extension is loaded
- if r.ExtensionManager != nil {
- t.ExtensionManager = &r.ExtensionManager
- }
-
- // Set the rate limit service URL if global rate limiting is enabled.
- if r.EnvoyGateway.RateLimit != nil {
- t.GlobalRateLimit = &translator.GlobalRateLimitSettings{
- ServiceURL: ratelimit.GetServiceURL(r.ControllerNamespace, r.DNSDomain),
- FailClosed: r.EnvoyGateway.RateLimit.FailClosed,
- }
- if r.EnvoyGateway.RateLimit.Timeout != nil {
- t.GlobalRateLimit.Timeout = r.EnvoyGateway.RateLimit.Timeout.Duration
- }
- }
-
- result, err := t.Translate(val)
- if err != nil {
- r.Logger.Error(err, "failed to translate xds ir")
- errChan <- err
- }
-
- // xDS translation is done in a best-effort manner, so the result
- // may contain partial resources even if there are errors.
- if result == nil {
- r.Logger.Info("no xds resources to publish")
- return
- }
-
- // Get all status keys from watchable and save them in the map statusesToDelete.
- // Iterating through result.EnvoyPatchPolicyStatuses, any valid keys will be removed from statusesToDelete.
- // Remaining keys will be deleted from watchable before we exit this function.
- statusesToDelete := make(map[ktypes.NamespacedName]bool)
- for key := range r.ProviderResources.EnvoyPatchPolicyStatuses.LoadAll() {
- statusesToDelete[key] = true
- }
-
- // Publish EnvoyPatchPolicyStatus
- for _, e := range result.EnvoyPatchPolicyStatuses {
- key := ktypes.NamespacedName{
- Name: e.Name,
- Namespace: e.Namespace,
- }
- // Skip updating status for policies with empty status
- // They may have been skipped in this translation because
- // their target is not found (not relevant)
- if !(reflect.ValueOf(e.Status).IsZero()) {
- r.ProviderResources.EnvoyPatchPolicyStatuses.Store(key, e.Status)
- }
- delete(statusesToDelete, key)
- }
- // Discard the EnvoyPatchPolicyStatuses to reduce memory footprint
- result.EnvoyPatchPolicyStatuses = nil
-
- // Publish
- if err == nil {
- message.HandleStore(message.Metadata{
- Runner: r.Name(),
- Message: message.XDSMessageName,
- },
- key, result, &r.Xds.Map)
- } else {
- r.Logger.Error(err, "skipped publishing xds resources")
- }
-
- // Delete all the deletable status keys
- for key := range statusesToDelete {
- r.ProviderResources.EnvoyPatchPolicyStatuses.Delete(key)
- }
- }
- },
- )
- r.Logger.Info("subscriber shutting down")
-}
diff --git a/internal/xds/translator/runner/runner_test.go b/internal/xds/translator/runner/runner_test.go
deleted file mode 100644
index 45f3f46bf4..0000000000
--- a/internal/xds/translator/runner/runner_test.go
+++ /dev/null
@@ -1,274 +0,0 @@
-// 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 runner
-
-import (
- "context"
- "fmt"
- "os"
- "testing"
- "time"
-
- listenerv3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
- resourcev3 "github.com/envoyproxy/go-control-plane/pkg/resource/v3"
- "github.com/stretchr/testify/require"
- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
-
- egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
- "github.com/envoyproxy/gateway/internal/envoygateway/config"
- "github.com/envoyproxy/gateway/internal/extension/types"
- "github.com/envoyproxy/gateway/internal/ir"
- "github.com/envoyproxy/gateway/internal/message"
-)
-
-func TestRunner(t *testing.T) {
- // Setup
- xdsIR := new(message.XdsIR)
- xds := new(message.Xds)
- pResource := new(message.ProviderResources)
- cfg, err := config.New(os.Stdout)
- require.NoError(t, err)
- r := New(&Config{
- Server: *cfg,
- ProviderResources: pResource,
- XdsIR: xdsIR,
- Xds: xds,
- })
-
- ctx := context.Background()
- // Start
- err = r.Start(ctx)
- require.NoError(t, err)
-
- // xDS is nil at start
- require.Equal(t, map[string]*ir.Xds{}, xdsIR.LoadAll())
-
- // test translation
- path := "example"
- res := ir.Xds{
- HTTP: []*ir.HTTPListener{
- {
- CoreListenerDetails: ir.CoreListenerDetails{
- Name: "test",
- Address: "0.0.0.0",
- Port: 80,
- },
- Hostnames: []string{"example.com"},
- Routes: []*ir.HTTPRoute{
- {
- Name: "test-route",
- PathMatch: &ir.StringMatch{
- Exact: &path,
- },
- Destination: &ir.RouteDestination{
- Name: "test-dest",
- Settings: []*ir.DestinationSetting{
- {
- Endpoints: []*ir.DestinationEndpoint{
- {
- Host: "10.11.12.13",
- Port: 8080,
- },
- },
- },
- },
- },
- },
- },
- },
- },
- }
- xdsIR.Store("test", &res)
- require.Eventually(t, func() bool {
- out := xds.LoadAll()
- if out == nil {
- return false
- }
- if out["test"] == nil {
- return false
- }
- // Ensure an xds listener is created
- return len(out["test"].XdsResources[resourcev3.ListenerType]) == 1
- }, time.Second*5, time.Millisecond*50)
-
- // Delete the IR triggering an xds delete
- xdsIR.Delete("test")
- require.Eventually(t, func() bool {
- out := xds.LoadAll()
- // Ensure that xds has no key, value pairs
- return len(out) == 0
- }, time.Second*5, time.Millisecond*50)
-}
-
-func TestRunner_withExtensionManager_FailOpen(t *testing.T) {
- // Setup
- xdsIR := new(message.XdsIR)
- xds := new(message.Xds)
- pResource := new(message.ProviderResources)
-
- cfg, err := config.New(os.Stdout)
- require.NoError(t, err)
- require.NotNil(t, cfg)
-
- extMgr := &extManagerMock{}
- extMgr.ShouldFailOpen = true
-
- r := New(&Config{
- Server: *cfg,
- ProviderResources: pResource,
- XdsIR: xdsIR,
- Xds: xds,
- ExtensionManager: extMgr,
- })
-
- ctx := context.Background()
- // Start
- err = r.Start(ctx)
- require.NoError(t, err)
-
- // xDS is nil at start
- require.Equal(t, map[string]*ir.Xds{}, xdsIR.LoadAll())
-
- // test translation
- path := "example"
- res := ir.Xds{
- HTTP: []*ir.HTTPListener{
- {
- CoreListenerDetails: ir.CoreListenerDetails{
- Name: "test",
- Address: "0.0.0.0",
- Port: 80,
- },
- Hostnames: []string{"example.com"},
- Routes: []*ir.HTTPRoute{
- {
- Name: "test-route",
- PathMatch: &ir.StringMatch{
- Exact: &path,
- },
- Destination: &ir.RouteDestination{
- Name: "test-dest",
- Settings: []*ir.DestinationSetting{
- {
- Endpoints: []*ir.DestinationEndpoint{
- {
- Host: "10.11.12.13",
- Port: 8080,
- },
- },
- },
- },
- },
- },
- },
- },
- },
- }
- xdsIR.Store("test", &res)
- require.Eventually(t, func() bool {
- out := xds.LoadAll()
- // Since the extension manager is configured to fail open, in an event of an error
- // from the extension manager hooks, xds update should be published.
- return len(out) == 1
- }, time.Second*5, time.Millisecond*50)
-}
-
-func TestRunner_withExtensionManager_FailClosed(t *testing.T) {
- // Setup
- xdsIR := new(message.XdsIR)
- xds := new(message.Xds)
- pResource := new(message.ProviderResources)
-
- cfg, err := config.New(os.Stdout)
- require.NoError(t, err)
- require.NotNil(t, cfg)
-
- extMgr := &extManagerMock{}
-
- r := New(&Config{
- Server: *cfg,
- ProviderResources: pResource,
- XdsIR: xdsIR,
- Xds: xds,
- ExtensionManager: extMgr,
- })
-
- ctx := context.Background()
- // Start
- err = r.Start(ctx)
- require.NoError(t, err)
-
- // xDS is nil at start
- require.Equal(t, map[string]*ir.Xds{}, xdsIR.LoadAll())
-
- // test translation
- path := "example"
- res := ir.Xds{
- HTTP: []*ir.HTTPListener{
- {
- CoreListenerDetails: ir.CoreListenerDetails{
- Name: "test",
- Address: "0.0.0.0",
- Port: 80,
- },
- Hostnames: []string{"example.com"},
- Routes: []*ir.HTTPRoute{
- {
- Name: "test-route",
- PathMatch: &ir.StringMatch{
- Exact: &path,
- },
- Destination: &ir.RouteDestination{
- Name: "test-dest",
- Settings: []*ir.DestinationSetting{
- {
- Endpoints: []*ir.DestinationEndpoint{
- {
- Host: "10.11.12.13",
- Port: 8080,
- },
- },
- },
- },
- },
- },
- },
- },
- },
- }
- xdsIR.Store("test", &res)
- require.Never(t, func() bool {
- out := xds.LoadAll()
- // Since the extension manager is configured to fail closed, in an event of an error
- // from the extension manager hooks, xds update should not be published.
- return len(out) > 0
- }, time.Second*5, time.Millisecond*50)
-}
-
-type extManagerMock struct {
- types.Manager
- ShouldFailOpen bool
-}
-
-func (m *extManagerMock) GetPostXDSHookClient(xdsHookType egv1a1.XDSTranslatorHook) (types.XDSHookClient, error) {
- if xdsHookType == egv1a1.XDSHTTPListener {
- return &xdsHookClientMock{}, nil
- }
-
- return nil, nil
-}
-
-func (m *extManagerMock) FailOpen() bool {
- return m.ShouldFailOpen
-}
-
-type xdsHookClientMock struct {
- types.XDSHookClient
-}
-
-func (c *xdsHookClientMock) PostHTTPListenerModifyHook(*listenerv3.Listener, []*unstructured.Unstructured) (*listenerv3.Listener, error) {
- return nil, fmt.Errorf("assuming a network error during the call")
-}
diff --git a/internal/xds/translator/testdata/in/ratelimit-config/month-year-rule.yaml b/internal/xds/translator/testdata/in/ratelimit-config/month-year-rule.yaml
new file mode 100644
index 0000000000..56d705b405
--- /dev/null
+++ b/internal/xds/translator/testdata/in/ratelimit-config/month-year-rule.yaml
@@ -0,0 +1,47 @@
+name: "first-listener"
+address: "0.0.0.0"
+port: 10080
+hostnames:
+- "*"
+path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+routes:
+- name: "first-route"
+ traffic:
+ rateLimit:
+ global:
+ rules:
+ - headerMatches:
+ - name: "x-user-id"
+ exact: "one"
+ limit:
+ requests: 5
+ unit: month
+ pathMatch:
+ exact: "foo/bar"
+ destination:
+ name: "first-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+- name: "second-route"
+ traffic:
+ rateLimit:
+ global:
+ rules:
+ - headerMatches:
+ - name: "x-user-id"
+ exact: "two"
+ limit:
+ requests: 1
+ unit: year
+ pathMatch:
+ exact: "foo/foo"
+ destination:
+ name: "second-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
diff --git a/internal/xds/translator/testdata/in/xds-ir/backend-tls-skip-verify.yaml b/internal/xds/translator/testdata/in/xds-ir/backend-tls-skip-verify.yaml
index fc74c38f36..f446ca58e5 100644
--- a/internal/xds/translator/testdata/in/xds-ir/backend-tls-skip-verify.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/backend-tls-skip-verify.yaml
@@ -19,7 +19,3 @@ http:
name: "first-route-dest/backend/0"
tls:
insecureSkipVerify: true
- useSystemTrustStore: true
- CACertificate:
- name: policy-btls/default-ca
- sni: example.com
diff --git a/internal/xds/translator/testdata/in/xds-ir/listener-proxy-protocol-multi.yaml b/internal/xds/translator/testdata/in/xds-ir/listener-proxy-protocol-multi.yaml
new file mode 100644
index 0000000000..bd6e7acb73
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/listener-proxy-protocol-multi.yaml
@@ -0,0 +1,44 @@
+http:
+- name: "listener"
+ address: "::"
+ port: 10080
+ hostnames:
+ - "foo.com"
+ - "bar.com"
+ path:
+ mergeSlashes: true
+ escapedSlashesAction: UnescapeAndRedirect
+ tls:
+ alpnProtocols:
+ - h2
+ - http/1.1
+ certificates:
+ - name: secret-1
+ # byte slice representation of "key-data"
+ certificate: [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
+ certificate: [99, 101, 114, 116, 45, 100, 97, 116, 97]
+ privateKey: [107, 101, 121, 45, 100, 97, 116, 97]
+ proxyProtocol:
+ optional: false
+ routes:
+ - name: "first-route"
+ hostname: "foo.com"
+ destination:
+ name: "first-route-dest"
+ settings:
+ - endpoints:
+ - host: "1.2.3.4"
+ port: 50000
+ name: "first-route-dest/backend/0"
+ - name: "second-route"
+ hostname: "bar.com"
+ destination:
+ name: "second-route-dest"
+ settings:
+ - endpoints:
+ - host: "5.6.7.8"
+ port: 50000
+ name: "second-route-dest/backend/0"
diff --git a/internal/xds/translator/testdata/out/ratelimit-config/month-year-rule.yaml b/internal/xds/translator/testdata/out/ratelimit-config/month-year-rule.yaml
new file mode 100644
index 0000000000..60bd7ecffb
--- /dev/null
+++ b/internal/xds/translator/testdata/out/ratelimit-config/month-year-rule.yaml
@@ -0,0 +1,37 @@
+name: first-listener
+domain: first-listener
+descriptors:
+ - key: first-route
+ value: first-route
+ rate_limit: null
+ descriptors:
+ - key: rule-0-match-0
+ value: rule-0-match-0
+ rate_limit:
+ requests_per_unit: 5
+ unit: MONTH
+ unlimited: false
+ name: ""
+ replaces: []
+ descriptors: []
+ shadow_mode: false
+ detailed_metric: false
+ shadow_mode: false
+ detailed_metric: false
+ - key: second-route
+ value: second-route
+ rate_limit: null
+ descriptors:
+ - key: rule-0-match-0
+ value: rule-0-match-0
+ rate_limit:
+ requests_per_unit: 1
+ unit: YEAR
+ unlimited: false
+ name: ""
+ replaces: []
+ descriptors: []
+ shadow_mode: false
+ detailed_metric: false
+ shadow_mode: false
+ detailed_metric: false
diff --git a/internal/xds/translator/testdata/out/xds-ir/backend-tls-skip-verify.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/backend-tls-skip-verify.clusters.yaml
index 540ba4fd71..915a64ca87 100644
--- a/internal/xds/translator/testdata/out/xds-ir/backend-tls-skip-verify.clusters.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/backend-tls-skip-verify.clusters.yaml
@@ -30,5 +30,4 @@
typedConfig:
'@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
commonTlsContext: {}
- sni: example.com
type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/dns-lookup-family.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/dns-lookup-family.listeners.yaml
index c5fb9a58f8..584a9f8d68 100644
--- a/internal/xds/translator/testdata/out/xds-ir/dns-lookup-family.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/dns-lookup-family.listeners.yaml
@@ -138,14 +138,6 @@
transportApiVersion: V3
withRequestBody:
maxRequestBytes: 8192
- - name: envoy.filters.http.grpc_stats
- typedConfig:
- '@type': type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig
- emitFilterState: true
- statsForAllMethods: true
- - name: envoy.filters.http.grpc_web
- typedConfig:
- '@type': type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
- disabled: true
name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-httproute/extproc/0
typedConfig:
@@ -160,6 +152,14 @@
requestTrailerMode: SKIP
responseHeaderMode: SKIP
responseTrailerMode: SKIP
+ - name: envoy.filters.http.grpc_web
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
+ - name: envoy.filters.http.grpc_stats
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig
+ emitFilterState: true
+ statsForAllMethods: true
- name: envoy.filters.http.router
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
diff --git a/internal/xds/translator/testdata/out/xds-ir/http2-route.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http2-route.listeners.yaml
index 2a7c6641af..b2e4d2fb20 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http2-route.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http2-route.listeners.yaml
@@ -14,14 +14,14 @@
initialStreamWindowSize: 65536
maxConcurrentStreams: 100
httpFilters:
+ - name: envoy.filters.http.grpc_web
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
- name: envoy.filters.http.grpc_stats
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig
emitFilterState: true
statsForAllMethods: true
- - name: envoy.filters.http.grpc_web
- typedConfig:
- '@type': type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
- name: envoy.filters.http.router
typedConfig:
'@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol-multi.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol-multi.clusters.yaml
new file mode 100644
index 0000000000..7e9eb80719
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol-multi.clusters.yaml
@@ -0,0 +1,48 @@
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: first-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ loadBalancingPolicy:
+ policies:
+ - typedExtensionConfig:
+ name: envoy.load_balancing_policies.least_request
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest
+ localityLbConfig:
+ localityWeightedLbConfig: {}
+ name: first-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
+- circuitBreakers:
+ thresholds:
+ - maxRetries: 1024
+ commonLbConfig: {}
+ connectTimeout: 10s
+ dnsLookupFamily: V4_PREFERRED
+ edsClusterConfig:
+ edsConfig:
+ ads: {}
+ resourceApiVersion: V3
+ serviceName: second-route-dest
+ ignoreHealthOnHostRemoval: true
+ lbPolicy: LEAST_REQUEST
+ loadBalancingPolicy:
+ policies:
+ - typedExtensionConfig:
+ name: envoy.load_balancing_policies.least_request
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest
+ localityLbConfig:
+ localityWeightedLbConfig: {}
+ name: second-route-dest
+ perConnectionBufferLimitBytes: 32768
+ type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol-multi.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol-multi.endpoints.yaml
new file mode 100644
index 0000000000..39102da400
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol-multi.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: 5.6.7.8
+ portValue: 50000
+ loadBalancingWeight: 1
+ loadBalancingWeight: 1
+ locality:
+ region: second-route-dest/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol-multi.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol-multi.listeners.yaml
new file mode 100644
index 0000000000..4a01e1c2f6
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol-multi.listeners.yaml
@@ -0,0 +1,65 @@
+- address:
+ socketAddress:
+ address: '::'
+ portValue: 10080
+ filterChains:
+ - filterChainMatch:
+ serverNames:
+ - foo.com
+ - bar.com
+ 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: listener
+ serverHeaderTransformation: PASS_THROUGH
+ statPrefix: https-10080
+ useRemoteAddress: true
+ name: 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
+ disableStatefulSessionResumption: true
+ disableStatelessSessionResumption: true
+ listenerFilters:
+ - name: envoy.filters.listener.proxy_protocol
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.listener.proxy_protocol.v3.ProxyProtocol
+ - name: envoy.filters.listener.tls_inspector
+ typedConfig:
+ '@type': type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector
+ maxConnectionsToAcceptPerSocketEvent: 1
+ name: listener
+ perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol-multi.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol-multi.routes.yaml
new file mode 100644
index 0000000000..21193de51f
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol-multi.routes.yaml
@@ -0,0 +1,25 @@
+- ignorePortInHostMatching: true
+ name: listener
+ virtualHosts:
+ - domains:
+ - foo.com
+ name: listener/foo_com
+ routes:
+ - match:
+ prefix: /
+ name: first-route
+ route:
+ cluster: first-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
+ - domains:
+ - bar.com
+ name: listener/bar_com
+ routes:
+ - match:
+ prefix: /
+ name: second-route
+ route:
+ cluster: second-route-dest
+ upgradeConfigs:
+ - upgradeType: websocket
diff --git a/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol-multi.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol-multi.secrets.yaml
new file mode 100644
index 0000000000..ad88ffe43c
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/listener-proxy-protocol-multi.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/xds-name-scheme-v2.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/xds-name-scheme-v2.listeners.yaml
index b1b39aa28e..51f8b8f0e9 100644
--- a/internal/xds/translator/testdata/out/xds-ir/xds-name-scheme-v2.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/xds-name-scheme-v2.listeners.yaml
@@ -25,9 +25,9 @@
configSource:
ads: {}
resourceApiVersion: V3
- routeConfigName: envoy-gateway/gateway-1/http1
+ routeConfigName: http-80
serverHeaderTransformation: PASS_THROUGH
- statPrefix: http-10080
+ statPrefix: http-80
useRemoteAddress: true
name: http-80
maxConnectionsToAcceptPerSocketEvent: 1
@@ -65,7 +65,7 @@
resourceApiVersion: V3
routeConfigName: envoy-gateway/gateway-1/https1
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https-10443
+ statPrefix: https-443
useRemoteAddress: true
name: envoy-gateway/gateway-1/https1
transportSocket:
@@ -110,7 +110,7 @@
resourceApiVersion: V3
routeConfigName: envoy-gateway/gateway-1/https2
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https-10443
+ statPrefix: https-443
useRemoteAddress: true
name: envoy-gateway/gateway-1/https2
transportSocket:
@@ -168,7 +168,7 @@
resourceApiVersion: V3
routeConfigName: envoy-gateway/gateway-2/https-http3
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https-11443
+ statPrefix: https-1443
useRemoteAddress: true
name: envoy-gateway/gateway-2/https-http3
transportSocket:
@@ -222,7 +222,7 @@
resourceApiVersion: V3
routeConfigName: envoy-gateway/gateway-2/https-http3
serverHeaderTransformation: PASS_THROUGH
- statPrefix: https-11443
+ statPrefix: https-1443
useRemoteAddress: true
name: envoy-gateway/gateway-2/https-http3
transportSocket:
diff --git a/internal/xds/translator/testdata/out/xds-ir/xds-name-scheme-v2.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/xds-name-scheme-v2.routes.yaml
index 01d3a93d1b..5c5dbe25f6 100644
--- a/internal/xds/translator/testdata/out/xds-ir/xds-name-scheme-v2.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/xds-name-scheme-v2.routes.yaml
@@ -1,9 +1,9 @@
- ignorePortInHostMatching: true
- name: envoy-gateway/gateway-1/http1
+ name: http-80
virtualHosts:
- domains:
- foo.net
- name: envoy-gateway/gateway-1/http1/foo_net
+ name: foo_net
routes:
- match:
prefix: /
@@ -14,7 +14,7 @@
- upgradeType: websocket
- domains:
- bar.net
- name: envoy-gateway/gateway-1/http2/bar_net
+ name: bar_net
routes:
- match:
prefix: /
@@ -28,7 +28,7 @@
virtualHosts:
- domains:
- foo.com
- name: envoy-gateway/gateway-1/https1/foo_com
+ name: foo_com
routes:
- match:
prefix: /
@@ -42,7 +42,7 @@
virtualHosts:
- domains:
- bar.com
- name: envoy-gateway/gateway-1/https2/bar_com
+ name: bar_com
routes:
- match:
prefix: /
@@ -56,7 +56,7 @@
virtualHosts:
- domains:
- '*'
- name: envoy-gateway/gateway-2/https-http3/*
+ name: '*'
routes:
- match:
prefix: /
diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go
index 862d8d7133..f79bbd6618 100644
--- a/internal/xds/translator/translator.go
+++ b/internal/xds/translator/translator.go
@@ -446,7 +446,7 @@ func (t *Translator) processHTTPListenerXdsTranslation(
routeCfgName = findXdsHTTPRouteConfigName(tcpXDSListener)
// If the route config name is not found, we use the current ir Listener name as the route config name to create a new route config.
if routeCfgName == "" {
- routeCfgName = routeConfigName(httpListener)
+ routeCfgName = routeConfigName(httpListener, t.xdsNameSchemeV2())
}
// Create a route config if we have not found one yet
@@ -504,7 +504,7 @@ func (t *Translator) addRouteToRouteConfig(
underscoredHostname := strings.ReplaceAll(httpRoute.Hostname, ".", "_")
// Allocate virtual host for this httpRoute.
vHost = &routev3.VirtualHost{
- Name: virtualHostName(httpListener, underscoredHostname),
+ Name: virtualHostName(httpListener, underscoredHostname, t.xdsNameSchemeV2()),
Domains: []string{httpRoute.Hostname},
Metadata: buildXdsMetadata(httpListener.Metadata),
}
@@ -656,7 +656,10 @@ func (t *Translator) addRouteToRouteConfig(
return errs
}
-func virtualHostName(httpListener *ir.HTTPListener, underscoredHostname string) string {
+func virtualHostName(httpListener *ir.HTTPListener, underscoredHostname string, xdsNameSchemeV2 bool) string {
+ if xdsNameSchemeV2 {
+ return underscoredHostname
+ }
return fmt.Sprintf("%s/%s", httpListener.Name, underscoredHostname)
}
@@ -1060,7 +1063,8 @@ func addXdsCluster(tCtx *types.ResourceVersionTable, args *xdsClusterArgs) error
preferLocal := ptr.Deref(args.loadBalancer, ir.LoadBalancer{}).PreferLocal
xdsEndpoints := buildXdsClusterLoadAssignment(args.name, args.settings, preferLocal)
for _, ds := range args.settings {
- if ds.TLS != nil {
+ shouldValidateTLS := ds.TLS != nil && !ds.TLS.InsecureSkipVerify
+ if shouldValidateTLS {
// Create an SDS secret for the CA certificate - either with inline bytes or with a filesystem ref
secret := buildXdsUpstreamTLSCASecret(ds.TLS)
if err := tCtx.AddXdsResource(resourcev3.SecretType, secret); err != nil {
diff --git a/internal/xds/types/resourceversiontable.go b/internal/xds/types/resourceversiontable.go
index dc186475bc..f6914aa03a 100644
--- a/internal/xds/types/resourceversiontable.go
+++ b/internal/xds/types/resourceversiontable.go
@@ -11,7 +11,6 @@ import (
"github.com/envoyproxy/go-control-plane/pkg/cache/types"
resourcev3 "github.com/envoyproxy/go-control-plane/pkg/resource/v3"
- protobuf "google.golang.org/protobuf/proto"
"github.com/envoyproxy/gateway/internal/ir"
"github.com/envoyproxy/gateway/internal/utils/proto"
@@ -28,45 +27,6 @@ type ResourceVersionTable struct {
EnvoyPatchPolicyStatuses
}
-// DeepCopyInto copies the contents into the output object
-// This was generated by controller-gen, moved from
-// zz_generated.deepcopy.go and updated to use proto.Clone
-// to deep copy the proto.Message
-func (t *ResourceVersionTable) DeepCopyInto(out *ResourceVersionTable) {
- *out = *t
- if t.XdsResources != nil {
- in, out := &t.XdsResources, &out.XdsResources
- *out = make(map[resourcev3.Type][]types.Resource, len(*in))
- for key, val := range *in {
- var outVal []types.Resource
- if val == nil {
- (*out)[key] = nil
- } else {
- // Snippet was generated by controller-gen
- // G601: Implicit memory aliasing in for loop.
- in, out := &val, &outVal //nolint:gosec,scopelint
- *out = make([]types.Resource, len(*in))
- for i := range *in {
- (*out)[i] = protobuf.Clone((*in)[i])
- }
- }
- (*out)[key] = outVal
- }
- }
-}
-
-// DeepCopy generates a deep copy of the ResourceVersionTable object.
-// This was generated by controller-gen and moved over from
-// zz_generated.deepcopy.go to this file.
-func (t *ResourceVersionTable) DeepCopy() *ResourceVersionTable {
- if t == nil {
- return nil
- }
- out := new(ResourceVersionTable)
- t.DeepCopyInto(out)
- return out
-}
-
// GetXdsResources retrieves the translated xds resources saved in the translator context.
func (t *ResourceVersionTable) GetXdsResources() XdsResources {
return t.XdsResources
diff --git a/internal/xds/types/resourceversiontable_test.go b/internal/xds/types/resourceversiontable_test.go
index 5fd7a42dd1..6f9032dff0 100644
--- a/internal/xds/types/resourceversiontable_test.go
+++ b/internal/xds/types/resourceversiontable_test.go
@@ -21,65 +21,8 @@ import (
"google.golang.org/protobuf/testing/protocmp"
)
-var (
- testListener = &listenerv3.Listener{
- Name: "test-listener",
- }
- testSecret = &tlsv3.Secret{
- Name: "test-secret",
- }
-)
-
-func TestDeepCopy(t *testing.T) {
- testCases := []struct {
- name string
- in *ResourceVersionTable
- out *ResourceVersionTable
- }{
- {
- name: "nil",
- in: nil,
- out: nil,
- },
- {
- name: "listener",
- in: &ResourceVersionTable{
- XdsResources: XdsResources{
- resourcev3.ListenerType: []types.Resource{testListener},
- },
- },
- out: &ResourceVersionTable{
- XdsResources: XdsResources{
- resourcev3.ListenerType: []types.Resource{testListener},
- },
- },
- },
- {
- name: "kitchen-sink",
- in: &ResourceVersionTable{
- XdsResources: XdsResources{
- resourcev3.ListenerType: []types.Resource{testListener},
- resourcev3.SecretType: []types.Resource{testSecret},
- },
- },
- out: &ResourceVersionTable{
- XdsResources: XdsResources{
- resourcev3.ListenerType: []types.Resource{testListener},
- resourcev3.SecretType: []types.Resource{testSecret},
- },
- },
- },
- }
- for _, tc := range testCases {
- t.Run(tc.name, func(t *testing.T) {
- if tc.out == nil {
- require.Nil(t, tc.in.DeepCopy())
- } else {
- diff := cmp.Diff(tc.out, tc.in.DeepCopy(), protocmp.Transform())
- require.Empty(t, diff)
- }
- })
- }
+var testListener = &listenerv3.Listener{
+ Name: "test-listener",
}
func TestAddOrReplaceXdsResource(t *testing.T) {
@@ -533,7 +476,7 @@ func TestAddOrReplaceXdsResource(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
err := tc.tableIn.AddOrReplaceXdsResource(tc.typeIn, tc.resourceIn, tc.funcIn)
require.NoError(t, err)
- diff := cmp.Diff(tc.tableOut, tc.tableIn.DeepCopy(), protocmp.Transform())
+ diff := cmp.Diff(tc.tableOut, tc.tableIn, protocmp.Transform())
require.Empty(t, diff)
})
}
diff --git a/release-notes/v1.5.0-rc1.yaml b/release-notes/v1.5.0-rc.1.yaml
similarity index 100%
rename from release-notes/v1.5.0-rc1.yaml
rename to release-notes/v1.5.0-rc.1.yaml
diff --git a/release-notes/v1.5.0-rc.2.yaml b/release-notes/v1.5.0-rc.2.yaml
new file mode 100644
index 0000000000..67dcd0fbaa
--- /dev/null
+++ b/release-notes/v1.5.0-rc.2.yaml
@@ -0,0 +1,26 @@
+date: August 5, 2025
+
+# Changes that are expected to cause an incompatibility with previous versions, such as deletions or modifications to existing APIs.
+breaking changes: |
+ Removed `xds-translator` and `xds-server` values from the `runner` label in `watchable_subscribe_total`. Use `xds` instead.
+
+# Updates addressing vulnerabilities, security flaws, or compliance requirements.
+security updates: |
+ Disable automountServiceAccountToken for proxy and ratelimit deployments and serviceAccounts
+
+# New features or capabilities added in this release.
+new features: |
+ Added Gateway Listeners to the xDS listener metadata.
+
+bug fixes: |
+ Fixed an issue that controller panic when reloading configuration.
+ Reverted to use Store directly instead of HandleStore wrapper to improve GC cleanup.
+
+# Enhancements that improve performance.
+performance improvements: |
+
+# Deprecated features or APIs.
+deprecations: |
+
+# Other notable changes not covered by the above sections.
+Other changes: |
diff --git a/release-notes/v1.5.0.yaml b/release-notes/v1.5.0.yaml
new file mode 100644
index 0000000000..4c36db5cf6
--- /dev/null
+++ b/release-notes/v1.5.0.yaml
@@ -0,0 +1,83 @@
+date: August 8, 2025
+
+# Changes that are expected to cause an incompatibility with previous versions, such as deletions or modifications to existing APIs.
+breaking changes: |
+ Use gateway name as proxy fleet name for gateway namespace mode.
+ Endpoints that are absent from service discovery are removed even if their active health checks succeed.
+ The xDS listener name are now renamed based on its listening port and protocol, instead of the Gateway name and section name. This breaks existing EnvoyPatchPolicies and ExtensionManagers as they depend on the old naming scheme. This change is guarded by the `XDSNameSchemeV2` runtime flag. This flag is disabled by default in v1.5, and it will be enabled in v1.6. We recommend users to migrate their EnvoyPatchPolicies and ExtensionManagers to use the new listener names before v1.6. Visit https://gateway.envoyproxy.io/tasks/extensibility/envoy-patch-policy/#xds-name-scheme-v2 to view the new naming scheme.
+ Removed `xds-translator` and `xds-server` values from the `runner` label in `watchable_subscribe_total`. Use `xds` instead.
+ Accessloggers of type ALS now have http2 enabled on the cluster by default.
+
+# Updates addressing vulnerabilities, security flaws, or compliance requirements.
+security updates: |
+ Disable automountServiceAccountToken for proxy and ratelimit deployments and serviceAccounts.
+
+# New features or capabilities added in this release.
+new features: |
+ Added support for setting `initialJitter` in the BackendTrafficPolicy active health check.
+ Add an option to OIDC authentication to bypass it and defer to JWT when the request contains an "Authorization: Bearer ..." header.
+ Added support for configuring Subject Alternative Names (SANs) for upstream TLS validation via `BackendTLSPolicy.validation.subjectAltNames`.
+ Added support for local rate limit header.
+ Added XDS metadata for clusters and endpoints from xRoutes and referenced backend resources (Backend, Service, ServiceImport).
+ Added support for setting ownerreference to infra resources when enable gateway namespace mode.
+ Added support for configuring hostname in active HTTP healthchecks.
+ Added support for configuring maxConnectionsToAcceptPerSocketEvent in listener via ClientTrafficPolicy.
+ Added support for setting GatewayClass ownerreference to infra resources when all cases except gateway namespace mode.
+ Added support for setting previous priorities retry predicate.
+ Added support for using extension server policies to in PostTranslateModify hook.
+ Added support for configuring cluster stat name for HTTPRoute and GRPCRoute in EnvoyProxy CRD.
+ Added support for configuring `SameSite` attribute for Oauth cookies for OIDC authentication.
+ Added support for configuring the cache sync period for K8s provider.
+ Added support for fallback to first key when load ca certificate from Secret or ConfigMap.
+ Added support for configuring user provided name to generated HorizontalPodAutoscaler and PodDisruptionBudget resources.
+ Added support for client certificate validation (SPKI, hash, SAN) in ClientTrafficPolicy.
+ Added support for OIDC RP initialized logout. If the end session endpoint is explicitly specified or discovered from the issuer's well-known url, the end session endpoint will be invoked when the user logs out.
+ Added support for specifying deployment annotations through the helm chart.
+ Added support for customizing the name of the ServiceAccount used by the Proxy.
+ Added support for custom backendRefs via extension server using PostClusterModify hook.
+ Added support for SecurityPolicy and EnvoyExtensionPolicy to target ServiceImport via BackendRefs.
+ Added metric `watchable_publish_total` counting store events in watchable message queues.
+ Added support for forwarding client ID header and sanitizing API keys for API Key authentication in SecurityPolicy.
+ Added support for using ClusterTrustBundle as CA.
+ Added support for using Secret as a source of the OIDC client ID.
+ Added support for listeners and routes in PostTranslateModifyHook extension hook.
+ Added admin console support with web UI for the Envoy Gateway admin server.
+ Added support for configuring Zone Aware Routing via BackendTrafficPolicy.
+ Added support for endpoint override policy based on Header.
+ Added rate limiting support for month and year periods.
+ Introduce validation strictness levels for Lua scripts in EnvoyExtensionPolicies.
+ Extends BackendTLSSettings support to all Backend types.
+ Enhanced route rule support in SecurityPolicy target.
+
+bug fixes: |
+ Fixed issue where WASM cache init failure caused routes with WASM-less EnvoyExtensionPolicies to have 500 direct responses.
+ Fixed issue which UDP listeners were not created in the Envoy proxy config when Gateway was created.
+ Keep ALPN configuration for listeners with overlapping certificates when ALPN is explicitly set in ClientTrafficPolicy.
+ Fixed issue that switch on wrong SubjectAltNameType enum value in BackendTLSPolicy.
+ Fixed issue that BackendTLSPolicy should not reference ConfigMap or Secret across namespace.
+ Fixed bug in certificate SANs overlap detection in listeners.
+ Fixed issue where EnvoyExtensionPolicy ExtProc body processing mode is set to FullDuplexStreamed, but trailers were not sent.
+ Fixed validation issue where EnvoyExtensionPolicy ExtProc failOpen is true, and body processing mode FullDuplexStreamed is not rejected.
+ Add ConfigMap indexers for EnvoyExtensionPolicies to reconcile Lua changes
+ Fixed issue that default accesslog format not working.
+ Fixed validation errors when the rateLimit url for Redis in the EnvoyGateway API includes multiple comma separated hosts.
+ Fixes addresses in status of DualStack NodePort Gateways.
+ Fixed issue that not able to override the prometheus annotation in EnvoyProxy CRD.
+ Skipped ExtProc, Wasm, and ExtAuth when they are configured FailOpen and the configuration is invalid, e.g. missing backendRefs or invalid port.
+ Fixed issue that failed to update policy status when there are more than 16 ancestors.
+ Fixed race condition in watchable.Map Snapshot subscription.
+ Fixed issue where HTTPRoutes with sessionPersistence caused the Envoy listeners to drain.
+ Fixed deployment creation blocking when EnvoyProxy secret is missing.
+ Increased earlyRequestHeaders limit from 16 to 64.
+
+# Enhancements that improve performance.
+performance improvements: |
+ Reduced xDS cluster DNS lookups for improved performance.
+ Combined xds-translator and xds-server runners into xds runner reducing memory by upto 25%
+ Removed custom Equal functions for watchable types by pre sorting Gateway API resources in the provider layer
+
+# Deprecated features or APIs.
+deprecations: |
+
+# Other notable changes not covered by the above sections.
+Other changes: |
diff --git a/release-notes/v1.5.1.yaml b/release-notes/v1.5.1.yaml
new file mode 100644
index 0000000000..0cbbda2ccc
--- /dev/null
+++ b/release-notes/v1.5.1.yaml
@@ -0,0 +1,31 @@
+date: September 16, 2024
+
+# Changes that are expected to cause an incompatibility with previous versions, such as deletions or modifications to existing APIs.
+breaking changes: |
+
+# Updates addressing vulnerabilities, security flaws, or compliance requirements.
+security updates: |
+
+# New features or capabilities added in this release.
+new features: |
+
+bug fixes: |
+ Fixed %ROUTE_KIND% operator to be lower-cased when used by clusterStatName in EnvoyProxy API.
+ Fixed maxAcceptPerSocketEvent being ignored in ClientTrafficPolicy.
+ Fixed the topologyInjectorDisabled and the local cluster was not defined.
+ Fixed log formatting of improper key-value pairs to avoid DPANIC in controller-runtime logger.
+ Fixed handling of context-related transient errors to prevent incorrect state reconciliation and unintended behavior.
+ Fixed the controller cannot read the EnvoyProxy attached gatewayclass only.
+ Fixed indexer and controller crashing when BackendTrafficPolicy has a redirect response override.
+ Fixed Lua validator log level to be suppressed by default.
+ Fixed ProxyTopologyInjector cache sync race condition that caused injection failures
+ Fixed validation for grpc routes with extension ref filters.
+
+# Enhancements that improve performance.
+performance improvements: |
+
+# Deprecated features or APIs.
+deprecations: |
+
+# Other notable changes not covered by the above sections.
+Other changes: |
diff --git a/site/content/en/contributions/RELEASING.md b/site/content/en/contributions/RELEASING.md
index 5d27ed1b06..809e2af598 100644
--- a/site/content/en/contributions/RELEASING.md
+++ b/site/content/en/contributions/RELEASING.md
@@ -40,48 +40,48 @@ export GITHUB_REMOTE=origin
__Note:__ The release candidate version should be in the format `${MAJOR_VERSION}.${MINOR_VERSION}.0-rc.${RELEASE_CANDIDATE_NUMBER}`.
3. Sign, commit, and push your changes to your fork.
-4. Submit a [Pull Request][] to merge the changes into the `main` branch. Do not proceed until your PR has merged and
- the [Build and Test][] has successfully completed.
-5. Create a new release branch from `main`. The release branch should be named
+4. Submit a [Pull Request][] to merge the changes into the `main` branch.
+5. Do not proceed until your PR has merged and the [Build and Test][] has successfully completed.
+6. Create a new release branch from `main`. The release branch should be named
`release/v${MAJOR_VERSION}.${MINOR_VERSION}`, e.g. `release/v0.3`.
```shell
git checkout -b release/v${MAJOR_VERSION}.${MINOR_VERSION}
```
-6. Push the branch to the Envoy Gateway repo.
+7. Push the branch to the Envoy Gateway repo.
```shell
git push ${GITHUB_REMOTE} release/v${MAJOR_VERSION}.${MINOR_VERSION}
```
-7. Create a topic branch for updating the Envoy proxy image and Envoy Ratelimit image to the tag supported by the release.
+8. Create a topic branch for updating the Envoy proxy image and Envoy Ratelimit image to the tag supported by the release.
Please note that the tags should be updated in both the source code and the Helm chart. Reference [PR #2098][]
for additional details on updating the image tag.
-8. Sign, commit, and push your changes to your fork.
-9. Submit a [Pull Request][] to merge the changes into the `release/v${MAJOR_VERSION}.${MINOR_VERSION}` branch. Do not
- proceed until your PR has merged into the release branch and the [Build and Test][] has completed for your PR.
-10. Ensure your release branch is up-to-date and tag the head of your release branch with the release candidate number.
+9. Sign, commit, and push your changes to your fork.
+10. Submit a [Pull Request][] to merge the changes into the `release/v${MAJOR_VERSION}.${MINOR_VERSION}` branch.
+11. Do not proceed until your PR has merged into the release branch and the [Build and Test][] has completed for your PR.
+12. Ensure your release branch is up-to-date and tag the head of your release branch with the release candidate number.
```shell
git tag -a v${MAJOR_VERSION}.${MINOR_VERSION}.0-rc.${RELEASE_CANDIDATE_NUMBER} -m 'Envoy Gateway v${MAJOR_VERSION}.${MINOR_VERSION}.0-rc.${RELEASE_CANDIDATE_NUMBER} Release Candidate'
```
-11. Push the tag to the Envoy Gateway repository.
+13. Push the tag to the Envoy Gateway repository.
```shell
git push ${GITHUB_REMOTE} v${MAJOR_VERSION}.${MINOR_VERSION}.0-rc.${RELEASE_CANDIDATE_NUMBER}
```
-12. This will trigger the [release GitHub action][] that generates the release, release artifacts, etc.
-13. Confirm that the [release workflow][] completed successfully.
-14. Confirm that the Envoy Gateway [image][] with the correct release tag was published to Docker Hub.
-15. Confirm that the [release][] was created.
-16. Note that the [Quickstart][] references are __not__ updated for release candidates. However, test
+14. This will trigger the [release GitHub action][] that generates the release, release artifacts, etc.
+15. Confirm that the [release workflow][] completed successfully.
+16. Confirm that the Envoy Gateway [image][] with the correct release tag was published to Docker Hub.
+17. Confirm that the [release][] was created.
+18. Note that the [Quickstart][] references are __not__ updated for release candidates. However, test
the quickstart steps using the release candidate by manually updating the links.
-17. [Generate][] the GitHub changelog.
-18. Ensure you check the "This is a pre-release" checkbox when editing the GitHub release.
-19. If you find any bugs in this process, please create an issue.
+19. [Generate][] the GitHub changelog.
+20. Ensure you check the "This is a pre-release" checkbox when editing the GitHub release.
+21. If you find any bugs in this process, please create an issue.
## Minor Release
@@ -170,16 +170,17 @@ export GITHUB_REMOTE=origin
```
3. Sign, commit, and push your changes to your fork.
-4. Submit a [Pull Request][] to merge the changes into the `main` branch. Do not proceed until all your PRs have merged
- and the [Build and Test][] has completed for your final PR.
+4. Submit a [Pull Request][] to merge the changes into the `main` branch.
-5. Checkout the release branch.
+5. Do not proceed until all your PRs have merged and the [Build and Test][] has completed for your final PR.
+
+6. Checkout the release branch.
```shell
git checkout release/v${MAJOR_VERSION}.${MINOR_VERSION} $GITHUB_REMOTE/release/v${MAJOR_VERSION}.${MINOR_VERSION}
```
-6. If the tip of the release branch does not match the tip of `main`, perform the following:
+7. If the tip of the release branch does not match the tip of `main`, perform the following:
1. Create a topic branch from the release branch.
2. Cherry-pick the commits from `main` that differ from the release branch, e.g. `git cherry-pick .. -s`
@@ -199,7 +200,7 @@ export GITHUB_REMOTE=origin
git pull $GITHUB_REMOTE release/v${MAJOR_VERSION}.${MINOR_VERSION}
```
-7. Tag the head of your release branch with the release tag. For example:
+8. Tag the head of your release branch with the release tag. For example:
```shell
git tag -a v${MAJOR_VERSION}.${MINOR_VERSION}.0 -m 'Envoy Gateway v${MAJOR_VERSION}.${MINOR_VERSION}.0 Release'
@@ -207,18 +208,18 @@ export GITHUB_REMOTE=origin
__Note:__ The tag version differs from the release branch by including the `.0` patch version.
-8. Push the tag to the Envoy Gateway repository.
+9. Push the tag to the Envoy Gateway repository.
```shell
git push origin v${MAJOR_VERSION}.${MINOR_VERSION}.0
```
-9. This will trigger the [release GitHub action][] that generates the release, release artifacts, etc.
-10. Confirm that the [release workflow][] completed successfully.
-11. Confirm that the Envoy Gateway [image][] with the correct release tag was published to Docker Hub.
-12. Confirm that the [release][] was created.
-13. Confirm that the steps in the [Quickstart][] work as expected.
-14. [Generate][] the GitHub changelog and include the following text at the beginning of the release page:
+10. This will trigger the [release GitHub action][] that generates the release, release artifacts, etc.
+11. Confirm that the [release workflow][] completed successfully.
+12. Confirm that the Envoy Gateway [image][] with the correct release tag was published to Docker Hub.
+13. Confirm that the [release][] was created.
+14. Confirm that the steps in the [Quickstart][] work as expected.
+15. [Generate][] the GitHub changelog and include the following text at the beginning of the release page:
```console
# Release Announcement
@@ -227,7 +228,7 @@ export GITHUB_REMOTE=origin
(https://gateway.envoyproxy.io/news/releases/notes/v${MAJOR_VERSION}.${MINOR_VERSION}.html) to learn more about the release.
```
-15. Update the `lastVersionTag` in `test/e2e/tests/eg_upgrade.go` to reflect the latest prior release. Refer to [PR #4666] as an example.
+16. Update the `lastVersionTag` in `test/e2e/tests/eg_upgrade.go` to reflect the latest prior release. Refer to [PR #4666] as an example.
If you find any bugs in this process, please create an issue.
@@ -313,21 +314,20 @@ export GITHUB_REMOTE=origin
```
3. Sign, commit, and push your changes to your fork.
-4. Submit a [Pull Request][] to merge the changes into the `main` branch. Do not proceed until all your PRs have merged
- and the [Build and Test][] has completed for your final PR.
-
-5. Checkout the release branch.
+4. Submit a [Pull Request][] to merge the changes into the `main` branch.
+5. Do not proceed until all your PRs have merged and the [Build and Test][] has completed for your final PR.
+6. Checkout the release branch.
```shell
git checkout release/v${MAJOR_VERSION}.${MINOR_VERSION} $GITHUB_REMOTE/release/v${MAJOR_VERSION}.${MINOR_VERSION}
```
-6. Cherry-pick the release note and release announcement that you created in the previous step to the release branch. The release note will be included in the release artifacts.
+7. Cherry-pick the release note and release announcement that you created in the previous step to the release branch. The release note will be included in the release artifacts.
1. Create a topic branch from the release branch.
2. Cherry-pick the release note and release announcement commit from `main` to the topic branch.
3. Submit a PR to merge the topic from of your fork into the release branch.
-7. Cherry-pick the commits that you want to include in the patch release.
+8. Cherry-pick the commits that you want to include in the patch release.
1. Create a topic branch from the release branch.
2. Cherry-pick the commits from `main` that you want to include in the patch release.
3. Run tests locally, e.g. `make lint`.
@@ -346,24 +346,24 @@ export GITHUB_REMOTE=origin
git pull $GITHUB_REMOTE release/v${MAJOR_VERSION}.${MINOR_VERSION}
```
-7. Tag the head of your release branch with the release tag. For example:
+9. Tag the head of your release branch with the release tag. For example:
```shell
git tag -a v${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION} -m 'Envoy Gateway v${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION} Release'
```
-8. Push the tag to the Envoy Gateway repository.
+10. Push the tag to the Envoy Gateway repository.
- ```shell
- git push origin v${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION
- ```
+ ```shell
+ git push origin v${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION
+ ```
-9. This will trigger the [release GitHub action][] that generates the release, release artifacts, etc.
-10. Confirm that the [release workflow][] completed successfully.
-11. Confirm that the Envoy Gateway [image][] with the correct release tag was published to Docker Hub.
-12. Confirm that the [release][] was created.
-13. Confirm that the steps in the [Quickstart][] work as expected.
-14. [Generate][] the GitHub changelog and include the following text at the beginning of the release page:
+11. This will trigger the [release GitHub action][] that generates the release, release artifacts, etc.
+12. Confirm that the [release workflow][] completed successfully.
+13. Confirm that the Envoy Gateway [image][] with the correct release tag was published to Docker Hub.
+14. Confirm that the [release][] was created.
+15. Confirm that the steps in the [Quickstart][] work as expected.
+16. [Generate][] the GitHub changelog and include the following text at the beginning of the release page:
```console
# Release Announcement
@@ -372,7 +372,7 @@ export GITHUB_REMOTE=origin
(https://gateway.envoyproxy.io/news/releases/notes/v${MAJOR_VERSION}.${MINOR_VERSION}.${MINOR_VERSION}.html) to learn more about the release.
```
-15. If this patch release is the latest release, update the `lastVersionTag` in `test/e2e/tests/eg_upgrade.go` to reflect the latest prior release. Refer to [PR #4666] as an example.
+17. If this patch release is the latest release, update the `lastVersionTag` in `test/e2e/tests/eg_upgrade.go` to reflect the latest prior release. Refer to [PR #4666] as an example.
### Announce the Release
diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md
index 0aa4d2f41a..018a5f6e20 100644
--- a/site/content/en/latest/api/extension_types.md
+++ b/site/content/en/latest/api/extension_types.md
@@ -129,8 +129,8 @@ _Appears in:_
| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
-| `timeout` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | 1s | Timeout defines the time to wait for a health check response. |
-| `interval` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | 3s | Interval defines the time between active health checks. |
+| `timeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | 1s | Timeout defines the time to wait for a health check response. |
+| `interval` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | 3s | Interval defines the time between active health checks. |
| `initialJitter` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | | InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value. |
| `unhealthyThreshold` | _integer_ | false | 3 | UnhealthyThreshold defines the number of unhealthy health checks required before a backend host is marked unhealthy. |
| `healthyThreshold` | _integer_ | false | 1 | HealthyThreshold defines the number of healthy health checks required before a backend host is marked healthy. |
@@ -280,8 +280,8 @@ _Appears in:_
| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
-| `baseInterval` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | | BaseInterval is the base interval between retries. |
-| `maxInterval` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | | MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval |
+| `baseInterval` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | | BaseInterval is the base interval between retries. |
+| `maxInterval` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | | MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval |
#### Backend
@@ -630,7 +630,7 @@ _Appears in:_
| `allowMethods` | _string array_ | false | | AllowMethods defines the methods that are allowed to make requests.
It specifies the allowed methods in the Access-Control-Allow-Methods CORS response header..
The value "*" allows any method to be used. |
| `allowHeaders` | _string array_ | false | | AllowHeaders defines the headers that are allowed to be sent with requests.
It specifies the allowed headers in the Access-Control-Allow-Headers CORS response header..
The value "*" allows any header to be sent. |
| `exposeHeaders` | _string array_ | false | | ExposeHeaders defines which response headers should be made accessible to
scripts running in the browser.
It specifies the headers in the Access-Control-Expose-Headers CORS response header..
The value "*" allows any header to be exposed. |
-| `maxAge` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | | MaxAge defines how long the results of a preflight request can be cached.
It specifies the value in the Access-Control-Max-Age CORS response header.. |
+| `maxAge` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | | MaxAge defines how long the results of a preflight request can be cached.
It specifies the value in the Access-Control-Max-Age CORS response header.. |
| `allowCredentials` | _boolean_ | false | | AllowCredentials indicates whether a request can include user credentials
like cookies, authentication headers, or TLS client certificates.
It specifies the value in the Access-Control-Allow-Credentials CORS response header. |
@@ -960,7 +960,7 @@ _Appears in:_
| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `name` | _string_ | true | | 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. |
-| `ttl` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | | TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value. |
+| `ttl` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | | TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value. |
| `attributes` | _object (keys:string, values:string)_ | false | | Additional Attributes to set for the generated cookie. |
@@ -1093,8 +1093,8 @@ _Appears in:_
| Field | Type | Required | Default | 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. |
+| `dnsRefreshRate` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | | DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds. |
+| `respectDnsTtl` | _boolean_ | false | | 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. |
| `lookupFamily` | _[DNSLookupFamily](#dnslookupfamily)_ | false | | LookupFamily determines how Envoy would resolve DNS for Routes where the backend is specified as a fully qualified domain name (FQDN).
If set, this configuration overrides other defaults. |
@@ -1224,6 +1224,8 @@ _Appears in:_
| `envoy.filters.http.rbac` | EnvoyFilterRBAC defines the Envoy RBAC filter.
|
| `envoy.filters.http.local_ratelimit` | EnvoyFilterLocalRateLimit defines the Envoy HTTP local rate limit filter.
|
| `envoy.filters.http.ratelimit` | EnvoyFilterRateLimit defines the Envoy HTTP rate limit filter.
|
+| `envoy.filters.http.grpc_web` | EnvoyFilterGRPCWeb defines the Envoy HTTP gRPC-web filter.
|
+| `envoy.filters.http.grpc_stats` | EnvoyFilterGRPCStats defines the Envoy HTTP gRPC stats filter.
|
| `envoy.filters.http.custom_response` | EnvoyFilterCustomResponse defines the Envoy HTTP custom response filter.
|
| `envoy.filters.http.credential_injector` | EnvoyFilterCredentialInjector defines the Envoy HTTP credential injector filter.
|
| `envoy.filters.http.compressor` | EnvoyFilterCompressor defines the Envoy HTTP compressor filter.
|
@@ -1378,6 +1380,7 @@ _Appears in:_
| `gateway-api` | LogComponentGatewayAPIRunner defines the "gateway-api" runner component.
|
| `xds-translator` | LogComponentXdsTranslatorRunner defines the "xds-translator" runner component.
|
| `xds-server` | LogComponentXdsServerRunner defines the "xds-server" runner component.
|
+| `xds` | LogComponentXdsRunner defines the "xds" runner component.
|
| `infrastructure` | LogComponentInfrastructureRunner defines the "infrastructure" runner component.
|
| `global-ratelimit` | LogComponentGlobalRateLimitRunner defines the "global-ratelimit" runner component.
|
@@ -1992,7 +1995,7 @@ _Appears in:_
| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
-| `fixedDelay` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | | FixedDelay specifies the fixed delay duration |
+| `fixedDelay` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | true | | FixedDelay specifies the fixed delay duration |
| `percentage` | _float_ | false | 100 | Percentage specifies the percentage of requests to be delayed. Default 100%, if set 0, no requests will be delayed. Accuracy to 0.0001%. |
@@ -2278,6 +2281,27 @@ _Appears in:_
| `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. |
+#### HTTPHeaderFilter
+
+
+
+HTTPHeaderFilter defines a filter that modifies the headers of an HTTP
+request or response. Only one action for a given header name is
+permitted. Filters specifying multiple actions of the same or different
+type for any one header name are invalid. Configuration to set or add
+multiple values for a header must use RFC 7230 header value formatting,
+separating each value with a comma.
+
+_Appears in:_
+- [HeaderSettings](#headersettings)
+
+| Field | Type | Required | Default | Description |
+| --- | --- | --- | --- | --- |
+| `set` | _HTTPHeader array_ | false | | 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 |
+| `add` | _HTTPHeader array_ | false | | 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 |
+| `remove` | _string array_ | false | | 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 |
+
+
#### HTTPHostnameModifier
@@ -3073,9 +3097,9 @@ _Appears in:_
| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
-| `leaseDuration` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | true | | LeaseDuration defines the time non-leader contenders will wait before attempting to claim leadership.
It's based on the timestamp of the last acknowledged signal. The default setting is 15 seconds. |
-| `renewDeadline` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | true | | RenewDeadline represents the time frame within which the current leader will attempt to renew its leadership
status before relinquishing its position. The default setting is 10 seconds. |
-| `retryPeriod` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | true | | RetryPeriod denotes the interval at which LeaderElector clients should perform action retries.
The default setting is 2 seconds. |
+| `leaseDuration` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | | LeaseDuration defines the time non-leader contenders will wait before attempting to claim leadership.
It's based on the timestamp of the last acknowledged signal.
The default setting is 15 seconds. |
+| `renewDeadline` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | | RenewDeadline represents the time frame within which the current leader will attempt to renew its leadership
status before relinquishing its position.
The default setting is 10 seconds. |
+| `retryPeriod` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | | RetryPeriod denotes the interval at which LeaderElector clients should perform action retries.
The default setting is 2 seconds. |
| `disable` | _boolean_ | true | | Disable provides the option to turn off leader election, which is enabled by default. |
@@ -3123,6 +3147,7 @@ _Appears in:_
| `consistentHash` | _[ConsistentHash](#consistenthash)_ | false | | ConsistentHash defines the configuration when the load balancer type is
set to ConsistentHash |
| `endpointOverride` | _[EndpointOverride](#endpointoverride)_ | false | | EndpointOverride defines the configuration for endpoint override.
When specified, the load balancer will attempt to route requests to endpoints
based on the override information extracted from request headers or metadata.
If the override endpoints are not available, the configured load balancer policy will be used as fallback. |
| `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 |
+| `zoneAware` | _[ZoneAware](#zoneaware)_ | false | | ZoneAware defines the configuration related to the distribution of requests between locality zones. |
#### LoadBalancerType
@@ -3309,9 +3334,9 @@ _Appears in:_
| `denyRedirect` | _[OIDCDenyRedirect](#oidcdenyredirect)_ | false | | Any request that matches any of the provided matchers (with either tokens that are expired or missing tokens) will not be redirected to the OIDC Provider.
This behavior can be useful for AJAX or machine requests. |
| `logoutPath` | _string_ | true | | The path to log a user out, clearing their credential cookies.
If not specified, uses a default logout path "/logout" |
| `forwardAccessToken` | _boolean_ | false | | ForwardAccessToken indicates whether the Envoy should forward the access token
via the Authorization header Bearer scheme to the upstream.
If not specified, defaults to false. |
-| `defaultTokenTTL` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | | DefaultTokenTTL is the default lifetime of the id token and access token.
Please note that Envoy will always use the expiry time from the response
of the authorization server if it is provided. This field is only used when
the expiry time is not provided by the authorization.
If not specified, defaults to 0. In this case, the "expires_in" field in
the authorization response must be set by the authorization server, or the
OAuth flow will fail. |
+| `defaultTokenTTL` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | | DefaultTokenTTL is the default lifetime of the id token and access token.
Please note that Envoy will always use the expiry time from the response
of the authorization server if it is provided. This field is only used when
the expiry time is not provided by the authorization.
If not specified, defaults to 0. In this case, the "expires_in" field in
the authorization response must be set by the authorization server, or the
OAuth flow will fail. |
| `refreshToken` | _boolean_ | false | | RefreshToken indicates whether the Envoy should automatically refresh the
id token and access token when they expire.
When set to true, the Envoy will use the refresh token to get a new id token
and access token when they expire.
If not specified, defaults to false. |
-| `defaultRefreshTokenTTL` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | | DefaultRefreshTokenTTL is the default lifetime of the refresh token.
This field is only used when the exp (expiration time) claim is omitted in
the refresh token or the refresh token is not JWT.
If not specified, defaults to 604800s (one week).
Note: this field is only applicable when the "refreshToken" field is set to true. |
+| `defaultRefreshTokenTTL` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | | DefaultRefreshTokenTTL is the default lifetime of the refresh token.
This field is only used when the exp (expiration time) claim is omitted in
the refresh token or the refresh token is not JWT.
If not specified, defaults to 604800s (one week).
Note: this field is only applicable when the "refreshToken" field is set to true. |
| `passThroughAuthHeader` | _boolean_ | false | | Skips OIDC authentication when the request contains a header that will be extracted by the JWT filter. Unless
explicitly stated otherwise in the extractFrom field, this will be the "Authorization: Bearer ..." header.
The passThroughAuthHeader option is typically used for non-browser clients that may not be able to handle OIDC
redirects and wish to directly supply a token instead.
If not specified, defaults to false. |
@@ -3326,7 +3351,7 @@ _Appears in:_
| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
-| `sameSite` | _string_ | false | Strict | |
+| `sameSite` | _string_ | false | | |
#### OIDCCookieNames
@@ -3479,11 +3504,11 @@ _Appears in:_
| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `splitExternalLocalOriginErrors` | _boolean_ | false | false | SplitExternalLocalOriginErrors enables splitting of errors between external and local origin. |
-| `interval` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | 3s | Interval defines the time between passive health checks. |
+| `interval` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | 3s | Interval defines the time between passive health checks. |
| `consecutiveLocalOriginFailures` | _integer_ | false | 5 | 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. |
| `consecutiveGatewayErrors` | _integer_ | false | 0 | ConsecutiveGatewayErrors sets the number of consecutive gateway errors triggering ejection. |
| `consecutive5XxErrors` | _integer_ | false | 5 | Consecutive5xxErrors sets the number of consecutive 5xx errors triggering ejection. |
-| `baseEjectionTime` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | 30s | BaseEjectionTime defines the base duration for which a host will be ejected on consecutive failures. |
+| `baseEjectionTime` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | 30s | BaseEjectionTime defines the base duration for which a host will be ejected on consecutive failures. |
| `maxEjectionPercent` | _integer_ | false | 10 | MaxEjectionPercent sets the maximum percentage of hosts in a cluster that can be ejected. |
@@ -3545,7 +3570,7 @@ _Appears in:_
| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
-| `timeout` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | | Timeout is the timeout per retry attempt. |
+| `timeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | | Timeout is the timeout per retry attempt. |
| `backOff` | _[BackOffPolicy](#backoffpolicy)_ | false | | Backoff is the backoff policy to be applied per retry attempt. gateway uses a fully jittered exponential
back-off algorithm for retries. For additional details,
see https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#config-http-filters-router-x-envoy-max-retries |
@@ -3579,6 +3604,8 @@ _Appears in:_
| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
+| `force` | _[ForceLocalZone](#forcelocalzone)_ | false | | ForceLocalZone defines override configuration for forcing all traffic to stay within the local zone instead of the default behavior
which maintains equal distribution among upstream endpoints while sending as much traffic as possible locally. |
+| `minEndpointsThreshold` | _integer_ | false | | MinEndpointsThreshold is the minimum number of total upstream endpoints across all zones required to enable zone-aware routing. |
#### Principal
@@ -3976,7 +4003,7 @@ _Appears in:_
| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `backend` | _[RateLimitDatabaseBackend](#ratelimitdatabasebackend)_ | true | | Backend holds the configuration associated with the
database backend used by the rate limit service to store
state associated with global ratelimiting. |
-| `timeout` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | | Timeout specifies the timeout period for the proxy to access the ratelimit server
If not set, timeout is 20ms. |
+| `timeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | | Timeout specifies the timeout period for the proxy to access the ratelimit server
If not set, timeout is 20ms. |
| `failClosed` | _boolean_ | true | | FailClosed is a switch used to control the flow of traffic
when the response from the ratelimit server cannot be obtained.
If FailClosed is false, let the traffic pass,
otherwise, don't let the traffic pass and return 500.
If not set, FailClosed is False. |
| `telemetry` | _[RateLimitTelemetry](#ratelimittelemetry)_ | false | | Telemetry defines telemetry configuration for RateLimit. |
@@ -4245,7 +4272,7 @@ _Appears in:_
_Underlying type:_ _string_
RateLimitUnit specifies the intervals for setting rate limits.
-Valid RateLimitUnit values are "Second", "Minute", "Hour", and "Day".
+Valid RateLimitUnit values are "Second", "Minute", "Hour", "Day", "Month" and "Year".
_Appears in:_
- [RateLimitValue](#ratelimitvalue)
@@ -4256,6 +4283,8 @@ _Appears in:_
| `Minute` | RateLimitUnitMinute specifies the rate limit interval to be 1 minute.
|
| `Hour` | RateLimitUnitHour specifies the rate limit interval to be 1 hour.
|
| `Day` | RateLimitUnitDay specifies the rate limit interval to be 1 day.
|
+| `Month` | RateLimitUnitMonth specifies the rate limit interval to be 1 month.
|
+| `Year` | RateLimitUnitYear specifies the rate limit interval to be 1 year.
|
#### RateLimitValue
@@ -4646,8 +4675,8 @@ _Appears in:_
| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
-| `drainTimeout` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | | DrainTimeout defines the graceful drain timeout. This should be less than the pod's terminationGracePeriodSeconds.
If unspecified, defaults to 60 seconds. |
-| `minDrainDuration` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | | MinDrainDuration defines the minimum drain duration allowing time for endpoint deprogramming to complete.
If unspecified, defaults to 10 seconds. |
+| `drainTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | | DrainTimeout defines the graceful drain timeout. This should be less than the pod's terminationGracePeriodSeconds.
If unspecified, defaults to 60 seconds. |
+| `minDrainDuration` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | | MinDrainDuration defines the minimum drain duration allowing time for endpoint deprogramming to complete.
If unspecified, defaults to 10 seconds. |
#### ShutdownManager
@@ -4675,7 +4704,7 @@ _Appears in:_
| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
-| `window` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | | 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 |
+| `window` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | true | | 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 |
#### SourceMatch
@@ -5322,5 +5351,6 @@ _Appears in:_
| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
+| `preferLocal` | _[PreferLocalZone](#preferlocalzone)_ | false | | PreferLocalZone configures zone-aware routing to prefer sending traffic to the local locality zone. |
diff --git a/site/content/en/latest/concepts/gateway_api_extensions/backend-traffic-policy.md b/site/content/en/latest/concepts/gateway_api_extensions/backend-traffic-policy.md
index 1cc981a1bb..06c99d39e3 100644
--- a/site/content/en/latest/concepts/gateway_api_extensions/backend-traffic-policy.md
+++ b/site/content/en/latest/concepts/gateway_api_extensions/backend-traffic-policy.md
@@ -29,17 +29,58 @@ Think of it as a traffic controller between your gateway and backend services. I
`BackendTrafficPolicy` is part of the Envoy Gateway API suite, which extends the Kubernetes Gateway API with additional capabilities. It's implemented as a Custom Resource Definition (CRD) that you can use to configure how Envoy Gateway manages traffic to your backend services.
-You can attach it to Gateway API resources in two ways:
+### Targets
-1. Using `targetRefs` to directly reference specific Gateway resources
-2. Using `targetSelectors` to match Gateway resources based on labels
+BackendTrafficPolicy can be attached to Gateway API resources using two targeting mechanisms:
-The policy applies to all resources that match either targeting method. When multiple policies target the same resource, the most specific configuration wins.
+1. **Direct Reference (`targetRefs`)**: Explicitly reference specific resources by name and kind.
+2. **Label Selection (`targetSelectors`)**: Match resources based on their labels (see [targetSelectors API reference](../../api/extension_types#targetselectors))
-For example, consider these two policies:
+```yaml
+# Direct reference targeting
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: BackendTrafficPolicy
+metadata:
+ name: direct-policy
+spec:
+ targetRefs:
+ - kind: HTTPRoute
+ name: my-route
+ circuitBreaker:
+ maxConnections: 50
+
+---
+# Label-based targeting
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: BackendTrafficPolicy
+metadata:
+ name: selector-policy
+spec:
+ targetSelectors:
+ - kind: HTTPRoute
+ matchLabels:
+ app: payment-service
+ rateLimit:
+ type: Local
+ local:
+ requests: 10
+ unit: Second
+```
+
+The policy applies to all resources that match either targeting method. You can target various Gateway API resource types including
+`Gateway`, `HTTPRoute`, `GRPCRoute`, `TCPRoute`, `UDPRoute`, `TLSRoute`.
+
+**Important**: A BackendTrafficPolicy can only target resources in the same namespace as the policy itself.
+
+### Precedence
+
+When multiple BackendTrafficPolicies apply to the same resource, Envoy Gateway resolves conflicts using a precedence hierarchy based on the target resource type, regardless of how the policy was attached:
+
+1. **Route-level policies** (HTTPRoute, GRPCRoute, etc.) - Highest precedence
+2. **Gateway-level policies** - Lower precedence
```yaml
-# Policy 1: Applies to all routes in the gateway
+# Gateway-level policy (lower precedence) - Applies to all routes in the gateway
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
@@ -52,7 +93,7 @@ spec:
maxConnections: 100
---
-# Policy 2: Applies to a specific route
+# Route-level policy (higher precedence)
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
@@ -65,9 +106,47 @@ spec:
maxConnections: 50
```
-In this example `my-route` and `my-gateway` would both affect the route. However, since Policy 2 targets the route directly while Policy 1 targets the gateway, Policy 2's configuration (`maxConnections: 50`) will take precedence for that specific route.
+In this example, the HTTPRoute `my-route` would use `maxConnections: 50` from the route-level policy, overriding the gateway-level setting of 100.
+
+#### Multiple Policies at the Same Level
+
+When multiple BackendTrafficPolicies target the same resource at the same hierarchy level (e.g., multiple policies targeting the same HTTPRoute), Envoy Gateway uses the following tie-breaking rules:
+
+1. **Creation Time Priority**: The oldest policy (earliest `creationTimestamp`) takes precedence
+2. **Name-based Sorting**: If policies have identical creation timestamps, they are sorted alphabetically by namespaced name, with the first policy taking precedence
+
+```yaml
+# Policy created first - takes precedence
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: BackendTrafficPolicy
+metadata:
+ name: alpha-policy
+ creationTimestamp: "2023-01-01T10:00:00Z"
+spec:
+ targetRefs:
+ - kind: HTTPRoute
+ name: my-route
+ circuitBreaker:
+ maxConnections: 30
+
+---
+# Policy created later - lower precedence
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: BackendTrafficPolicy
+metadata:
+ name: beta-policy
+ creationTimestamp: "2023-01-01T11:00:00Z"
+spec:
+ targetRefs:
+ - kind: HTTPRoute
+ name: my-route
+ circuitBreaker:
+ maxConnections: 40
+```
+
+In this example, `alpha-policy` would take precedence due to its earlier creation time, so the HTTPRoute would use `maxConnections: 30`.
-Lastly, it's important to note that even when you apply a policy to a Gateway, the policy's effects are tracked separately for each backend service referenced in your routes. For example, if you set up circuit breaking on a Gateway with multiple backend services, each backend service will have its own independent circuit breaker counter. This ensures that issues with one backend service don't affect the others.
+When the `mergeType` field is unset, no merging occurs and only the most specific configuration takes effect. However, policies can be configured to merge with parent policies using the `mergeType` field (see [Policy Merging](#policy-merging) section below).
## Policy Merging
diff --git a/site/content/en/latest/concepts/gateway_api_extensions/client-traffic-policy.md b/site/content/en/latest/concepts/gateway_api_extensions/client-traffic-policy.md
index 8dc47a3063..b5afbfb06d 100644
--- a/site/content/en/latest/concepts/gateway_api_extensions/client-traffic-policy.md
+++ b/site/content/en/latest/concepts/gateway_api_extensions/client-traffic-policy.md
@@ -36,14 +36,67 @@ Think of `ClientTrafficPolicy` as a set of rules for your Gateway's entry points
`ClientTrafficPolicy` is part of the Envoy Gateway API suite, which extends the Kubernetes Gateway API with additional capabilities. It's implemented as a Custom Resource Definition (CRD) that you can use to configure how Envoy Gateway manages incoming client traffic.
-You can attach it to Gateway API resources in two ways:
+### Targets
-1. Using `targetRefs` to directly reference specific Gateway resources
-2. Using `targetSelectors` to match Gateway resources based on labels
+ClientTrafficPolicy can be attached to Gateway API resources using two targeting mechanisms:
-The policy applies to all Gateway resources that match either targeting method. When multiple policies target the same resource, the most specific configuration wins.
+1. **Direct Reference (`targetRefs`)**: Explicitly reference specific Gateway resources by name and kind.
+2. **Label Selection (`targetSelectors`)**: Match Gateway resources based on their labels (see [targetSelectors API reference](../../api/extension_types#targetselectors))
-For example, consider these policies targeting the same Gateway Listener:
+The policy applies to all Gateway resources that match either targeting method.
+
+**Important**: A ClientTrafficPolicy can only target Gateway resources in the same namespace as the policy itself.
+
+### Precedence
+
+When multiple ClientTrafficPolicies apply to the same resource, Envoy Gateway resolves conflicts using section-level specificity and creation-time priority:
+
+1. **Section-specific policies** (targeting specific listeners via `sectionName`) - Highest precedence
+2. **Gateway-wide policies** (targeting entire Gateway) - Lower precedence
+
+#### Multiple Policies at the Same Level
+
+When multiple ClientTrafficPolicies target the same resource at the same specificity level (e.g., multiple policies targeting the same Gateway listener section), Envoy Gateway uses the following tie-breaking rules:
+
+1. **Creation Time Priority**: The oldest policy (earliest `creationTimestamp`) takes precedence
+2. **Name-based Sorting**: If policies have identical creation timestamps, they are sorted alphabetically by namespaced name, with the first policy taking precedence
+
+```yaml
+# Policy created first - takes precedence
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: ClientTrafficPolicy
+metadata:
+ name: alpha-policy
+ creationTimestamp: "2023-01-01T10:00:00Z"
+spec:
+ targetRefs:
+ - kind: Gateway
+ name: my-gateway
+ sectionName: https-listener
+ timeout:
+ http:
+ idleTimeout: 30s
+
+---
+# Policy created later - lower precedence
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: ClientTrafficPolicy
+metadata:
+ name: beta-policy
+ creationTimestamp: "2023-01-01T11:00:00Z"
+spec:
+ targetRefs:
+ - kind: Gateway
+ name: my-gateway
+ sectionName: https-listener
+ timeout:
+ http:
+ idleTimeout: 40s
+```
+
+In this example, `alpha-policy` would take precedence due to its earlier creation time, so the listener would use `idleTimeout: 30s`.
+
+For example, consider these policies with different specificity levels targeting the same Gateway:
```yaml
# Policy A: Targets a specific listener in the gateway
diff --git a/site/content/en/latest/concepts/gateway_api_extensions/security-policy.md b/site/content/en/latest/concepts/gateway_api_extensions/security-policy.md
index 12f0eccfdd..4eac2fb50e 100644
--- a/site/content/en/latest/concepts/gateway_api_extensions/security-policy.md
+++ b/site/content/en/latest/concepts/gateway_api_extensions/security-policy.md
@@ -27,14 +27,146 @@ title: "SecurityPolicy"
## SecurityPolicy in Envoy Gateway
-`SecurityPolicy` is implemented as a Kubernetes Custom Resource Definition (CRD) and follows the policy attachment model. You can attach it to Gateway API resources in two ways:
+`SecurityPolicy` is implemented as a Kubernetes Custom Resource Definition (CRD) and follows the policy attachment model.
-1. Using `targetRefs` to directly reference specific Gateway resources
-2. Using `targetSelectors` to match Gateway resources based on labels
+### Targets
-The policy applies to all resources that match either targeting method. When multiple policies target the same resource, the most specific configuration wins.
+SecurityPolicy can be attached to Gateway API resources using two targeting mechanisms:
-For example, consider these policies targeting the same Gateway Listener:
+1. **Direct Reference (`targetRefs`)**: Explicitly reference specific resources by name and kind.
+2. **Label Selection (`targetSelectors`)**: Match resources based on their labels (see [targetSelectors API reference](../../api/extension_types#targetselectors))
+
+The policy applies to all resources that match either targeting method. You can target various Gateway API resource types including `Gateway`, `HTTPRoute`, and `GRPCRoute`.
+
+**Important**: A SecurityPolicy can only target resources in the same namespace as the policy itself.
+
+### Precedence
+
+When multiple SecurityPolicies apply to the same resource, Envoy Gateway resolves conflicts using a precedence hierarchy based on the target resource type and section-level specificity:
+
+1. **Route rule-level policies** (HTTPRoute/GRPCRoute with `sectionName` targeting specific rules) - Highest precedence
+2. **Route-level policies** (HTTPRoute, GRPCRoute without `sectionName`) - High precedence
+3. **Listener-level policies** (Gateway with `sectionName` targeting specific listeners) - Medium precedence
+4. **Gateway-level policies** (Gateway without `sectionName`) - Lowest precedence
+
+#### Multiple Policies at the Same Level
+
+When multiple SecurityPolicies target the same resource at the same hierarchy level (e.g., multiple policies targeting the same HTTPRoute), Envoy Gateway uses the following tie-breaking rules:
+
+1. **Creation Time Priority**: The oldest policy (earliest `creationTimestamp`) takes precedence
+2. **Name-based Sorting**: If policies have identical creation timestamps, they are sorted alphabetically by namespaced name, with the first policy taking precedence
+
+```yaml
+# Policy created first - takes precedence
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: SecurityPolicy
+metadata:
+ name: alpha-policy
+ creationTimestamp: "2023-01-01T10:00:00Z"
+spec:
+ targetRefs:
+ - kind: HTTPRoute
+ name: my-route
+ cors:
+ allowOrigins:
+ - exact: https://example.com
+
+---
+# Policy created later - lower precedence
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: SecurityPolicy
+metadata:
+ name: beta-policy
+ creationTimestamp: "2023-01-01T11:00:00Z"
+spec:
+ targetRefs:
+ - kind: HTTPRoute
+ name: my-route
+ cors:
+ allowOrigins:
+ - exact: https://different.com
+```
+
+In this example, `alpha-policy` would take precedence due to its earlier creation time, so the HTTPRoute would use the CORS setting from `alpha-policy`.
+
+```yaml
+# HTTPRoute with named rules
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: my-route
+spec:
+ rules:
+ - name: rule-1 # Named rule for sectionName targeting
+ matches:
+ - path:
+ value: "/api"
+ backendRefs:
+ - name: api-service
+ port: 80
+
+---
+# Route rule-level policy (highest precedence)
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: SecurityPolicy
+metadata:
+ name: rule-policy
+spec:
+ targetRef:
+ kind: HTTPRoute
+ name: my-route
+ sectionName: rule-1 # Targets specific named rule
+ cors:
+ allowOrigins:
+ - exact: https://rule.example.com
+
+---
+# Route-level policy (high precedence)
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: SecurityPolicy
+metadata:
+ name: route-policy
+spec:
+ targetRef:
+ kind: HTTPRoute
+ name: my-route # No sectionName = entire route
+ cors:
+ allowOrigins:
+ - exact: https://route.example.com
+
+---
+# Listener-level policy (medium precedence)
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: SecurityPolicy
+metadata:
+ name: listener-policy
+spec:
+ targetRef:
+ kind: Gateway
+ name: my-gateway
+ sectionName: https-listener # Targets specific listener
+ cors:
+ allowOrigins:
+ - exact: https://listener.example.com
+
+---
+# Gateway-level policy (lowest precedence)
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: SecurityPolicy
+metadata:
+ name: gateway-policy
+spec:
+ targetRef:
+ kind: Gateway
+ name: my-gateway # No sectionName = entire gateway
+ cors:
+ allowOrigins:
+ - exact: https://gateway.example.com
+```
+
+In this example, the specific rule `rule-1` within HTTPRoute `my-route` would use the CORS settings from the route rule-level policy (`https://rule.example.com`), overriding the route-level, listener-level, and gateway-level settings.
+
+For section-specific targeting, consider these policies with different hierarchy levels targeting the same Gateway:
```yaml
# Policy A: Applies to a specific listener
diff --git a/site/content/en/latest/install/gateway-crds-helm-api.md b/site/content/en/latest/install/gateway-crds-helm-api.md
index febf9f9bd5..b331653392 100644
--- a/site/content/en/latest/install/gateway-crds-helm-api.md
+++ b/site/content/en/latest/install/gateway-crds-helm-api.md
@@ -2,9 +2,22 @@
title = "Gateway Crds Helm Chart"
+++
-  
+  
-A Helm chart for Kubernetes
+A Helm chart for Envoy Gateway CRDs
+
+**Homepage:**
+
+## Maintainers
+
+| Name | Email | Url |
+| ---- | ------ | --- |
+| envoy-gateway-steering-committee | | |
+| envoy-gateway-maintainers | | |
+
+## Source Code
+
+*
## Values
diff --git a/site/content/en/latest/install/gateway-helm-api.md b/site/content/en/latest/install/gateway-helm-api.md
index bd2abbec9f..0ec84dd251 100644
--- a/site/content/en/latest/install/gateway-helm-api.md
+++ b/site/content/en/latest/install/gateway-helm-api.md
@@ -67,7 +67,7 @@ The Helm chart for Envoy Gateway
| global.images.envoyGateway.image | string | `nil` | |
| global.images.envoyGateway.pullPolicy | string | `nil` | |
| global.images.envoyGateway.pullSecrets | list | `[]` | |
-| global.images.ratelimit.image | string | `"docker.io/envoyproxy/ratelimit:master"` | |
+| global.images.ratelimit.image | string | `"docker.io/envoyproxy/ratelimit:e74a664a"` | |
| global.images.ratelimit.pullPolicy | string | `"IfNotPresent"` | |
| global.images.ratelimit.pullSecrets | list | `[]` | |
| hpa.behavior | object | `{}` | |
diff --git a/site/content/en/latest/install/install-egctl.md b/site/content/en/latest/install/install-egctl.md
index cbd8238574..72081ce79b 100644
--- a/site/content/en/latest/install/install-egctl.md
+++ b/site/content/en/latest/install/install-egctl.md
@@ -22,7 +22,7 @@ The Envoy Gateway project provides two ways to fetch and install egctl. These ar
Every [release](https://github.com/envoyproxy/gateway/releases) of egctl provides binary releases for a variety of OSes. These binary versions can be manually downloaded and installed.
1. Download your [desired version](https://github.com/envoyproxy/gateway/releases)
-2. Unpack it (tar -zxvf egctl_latest_linux_amd64.tar.gz)
+2. Unpack it (tar -zxvf egctl_{{< yaml-version >}}_linux_amd64.tar.gz)
3. Find the egctl binary in the unpacked directory, and move it to its desired destination (mv bin/linux/amd64/egctl /usr/local/bin/egctl)
From there, you should be able to run: `egctl help`.
@@ -41,15 +41,12 @@ chmod +x get-egctl.sh
# get help info of the
bash get-egctl.sh --help
-
-# install the latest development version of egctl
-bash VERSION=latest get-egctl.sh
```
Yes, you can just use the below command if you want to live on the edge.
```shell
-curl -fsSL https://gateway.envoyproxy.io/get-egctl.sh | VERSION=latest bash
+curl -fsSL https://gateway.envoyproxy.io/get-egctl.sh | VERSION={{< yaml-version >}} bash
```
{{% /tab %}}
diff --git a/site/content/en/latest/tasks/extensibility/_index.md b/site/content/en/latest/tasks/extensibility/_index.md
index 664c734aec..3079bb6844 100644
--- a/site/content/en/latest/tasks/extensibility/_index.md
+++ b/site/content/en/latest/tasks/extensibility/_index.md
@@ -3,3 +3,16 @@ title: "Extensibility"
weight: 4
description: This section includes Extensibility tasks.
---
+
+Envoy Gateway provides several ways to extend its functionality beyond the built-in features.
+
+## Extension Options
+
+**Need access to Envoy Proxy features not available through the API ?**
+- [Envoy Patch Policy](envoy-patch-policy) - Directly modify Envoy xDS configuration
+- [Extension Server](extension-server) - Build external services to transform xDS configuration
+
+**Want to add custom processing logic?**
+- [WASM Extensions](wasm) - Run WebAssembly modules for high-performance custom logic
+- [External Processing](ext-proc) - Call external gRPC services during request processing
+- [Lua Extensions](lua) - Write lightweight scripting extensions
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 9fddf7dc57..72b047e3bc 100644
--- a/site/content/en/latest/tasks/extensibility/envoy-patch-policy.md
+++ b/site/content/en/latest/tasks/extensibility/envoy-patch-policy.md
@@ -82,6 +82,89 @@ data:
{{< boilerplate rollout-envoy-gateway >}}
+## XDS Name Scheme V2
+
+Starting from v1.5, Envoy Gateway uses version 2 of the xDS name scheme when generating xDS resources.
+Because [EnvoyPatchPolicy][] relies on specific xDS resource names, it’s important to use the correct naming format when authoring a patch policy.
+
+| Component | Scheme Version | Format Description | Example |
+|----------------------|----------------|------------------------------------------------------------------------------|----------------------------------|
+| **Listener name** | Old | `//` | `default/eg/http` |
+| | V2 | `-` | `tcp-80` |
+| **RouteConfig name** | Old | `//` | `default/eg/http` |
+| | V2 (HTTP) | `http-` | `http-80` |
+| | V2 (HTTPS) | `//` | `default/eg/https` |
+| **FilterChain name** | Old | `//` | `default/eg/http` |
+| | V2 (HTTP) | `http-` | `http-80` |
+| | V2 (HTTPS) | `//` | `default/eg/https` |
+| **VirtualHost name** | Old | `///` | `default/eg/http/www_example_com` |
+| | V2 | `` | `www_example_com` |
+| **HCM StatPrefix** | Old | `/` | `http-10080`, `https-10443` |
+| | V2 (HTTP) | `http-` | `http-80` |
+| | V2 (HTTPS) | `https-` | `https-443` |
+
+
+This change is gated by the XDSNameSchemeV2 runtime flag. The flag is disabled by default in v1.5 and will be enabled by default starting in v1.6.
+
+We recommend users begin migrating their [EnvoyPatchPolicy][] resources to use the version 2 naming scheme before upgrading to v1.6.
+
+To opt in to the new naming scheme early, add the`XDSNameSchemeV2` runtime flag to the `runtimeFlags.enabled` field in your [EnvoyGateway][] configuration.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
## Testing
### Customize Response
diff --git a/site/content/en/latest/tasks/operations/gateway-namespace-mode.md b/site/content/en/latest/tasks/operations/gateway-namespace-mode.md
index ad7f3cd51b..892794132c 100644
--- a/site/content/en/latest/tasks/operations/gateway-namespace-mode.md
+++ b/site/content/en/latest/tasks/operations/gateway-namespace-mode.md
@@ -2,22 +2,19 @@
title: "Gateway Namespace Mode"
---
-{{% alert title="Notice" color="warning" %}}
-
-Gateway Namespace Mode is currently an **alpha** feature. We recommend against using it in production workloads until it reaches beta status.
-
-For status updates or to provide feedback, please follow our [GitHub issues](https://github.com/envoyproxy/gateway/issues).
-
-{{% /alert %}}
-
## Overview
In standard deployment mode, Envoy Gateway creates all data plane resources in the controller namespace (typically `envoy-gateway-system`).
-Gateway Namespace Mode changes this behavior by placing Envoy Proxy data plane resources like Deployments, Services and ServiceAccounts in each Gateway's namespace, providing stronger isolation and multi-tenancy.
+The motivation behind this was to operate with minimum permissions needed to be given for Envoy Gateway controller, as the control plane and data plane was deployed in the same namespace.
+
+Gateway Namespace Mode changes this behavior by placing Envoy Proxy data plane resources like Deployments, Services and ServiceAccounts in each Gateway's namespace, which provides stronger isolation and multi-tenancy compared to the Controller Namespace mode, as it isolates Envoy proxy data plane across different tenants.
+This distributed architecture requires additional RBAC permissions for the Envoy Gateway controller to manage Kubernetes resources across multiple namespaces.
-Traditional deployment mode uses mTLS where both the client and server authenticate each other. However, in Gateway Namespace Mode, we've shifted to server-side TLS and JWT token validation between infra and control-plane.
+The default (Controller Namespace) deployment mode uses mTLS where both the client and server authenticate each other. However, in Gateway Namespace Mode, we've shifted to server-side TLS and JWT token validation between infra and control-plane.
+* **Envoy proxy pods** (running in Gateway namespaces) act as clients and authenticate using JWT tokens
+* **Envoy Gateway controller pod** (running in controller namespace) acts as the server and validates JWT tokens
* Only the CA certificate is available in pods running in Gateway namespaces
* Client certificates are not mounted in these namespaces
* The Envoy proxy still validates server certificates using the CA certificate
diff --git a/site/content/en/latest/tasks/operations/graceful-shutdown.md b/site/content/en/latest/tasks/operations/graceful-shutdown.md
new file mode 100644
index 0000000000..3f6bc08f20
--- /dev/null
+++ b/site/content/en/latest/tasks/operations/graceful-shutdown.md
@@ -0,0 +1,91 @@
+---
+title: "Graceful Shutdown and Hitless Upgrades"
+---
+
+Envoy Gateway enables zero-downtime deployments through graceful connection draining during pod termination.
+
+## Overview
+
+The shutdown manager sidecar coordinates graceful connection draining during pod termination, providing:
+
+- Zero-downtime rolling updates
+- Configurable drain timeouts
+- Automatic health check failure to remove pods from load balancer rotation
+
+### Shutdown Process
+
+1. Kubernetes sends SIGTERM to the pod
+2. Shutdown manager fails health checks via `/healthcheck/fail`
+ - This causes Kubernetes readiness probes to fail
+ - External load balancers and services stop routing new traffic to the pod
+ - Existing connections continue to be served while draining
+3. Connection monitoring begins, polling `server.total_connections`
+4. Process exits when connections reach zero or drain timeout is exceeded
+
+## Configuration
+
+Graceful shutdown behavior includes default values that can be overridden using the EnvoyProxy resource. The EnvoyProxy resource can be referenced in two ways:
+1. **Gateway-level**: Referenced from a Gateway via `infrastructure.parametersRef`
+2. **GatewayClass-level**: Referenced from a GatewayClass via `parametersRef`
+
+**Default Values:**
+- `drainTimeout`: 60 seconds - Maximum time for connection draining
+- `minDrainDuration`: 10 seconds - Minimum wait before allowing exit
+
+{{< tabpane text=true >}}
+{{% tab header="Gateway-Level Configuration" %}}
+
+```yaml
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+ name: eg
+spec:
+ gatewayClassName: eg
+ infrastructure:
+ parametersRef:
+ group: gateway.envoyproxy.io
+ kind: EnvoyProxy
+ name: graceful-shutdown-config
+ listeners:
+ - name: http
+ port: 80
+ protocol: HTTP
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyProxy
+metadata:
+ name: graceful-shutdown-config
+spec:
+ shutdown:
+ drainTimeout: "90s" # Override default 60s
+ minDrainDuration: "15s" # Override default 10s
+```
+
+{{% /tab %}}
+{{% tab header="GatewayClass-Level Configuration" %}}
+
+```yaml
+apiVersion: gateway.networking.k8s.io/v1
+kind: GatewayClass
+metadata:
+ name: eg
+spec:
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+ parametersRef:
+ group: gateway.envoyproxy.io
+ kind: EnvoyProxy
+ name: graceful-shutdown-config
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyProxy
+metadata:
+ name: graceful-shutdown-config
+spec:
+ shutdown:
+ drainTimeout: "90s" # Override default 60s
+ minDrainDuration: "15s" # Override default 10s
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
diff --git a/site/content/en/latest/tasks/security/backend-skip-tls-verification.md b/site/content/en/latest/tasks/security/backend-skip-tls-verification.md
new file mode 100644
index 0000000000..4d862b0b18
--- /dev/null
+++ b/site/content/en/latest/tasks/security/backend-skip-tls-verification.md
@@ -0,0 +1,341 @@
+---
+title: "Backend TLS: Skip TLS Verification"
+---
+
+This task demonstrates how to skip TLS verification for a backend service in Envoy Gateway.
+
+By default, you must configure a [BackendTLSPolicy][] to validate the TLS certificate of a backend service when it uses TLS.
+
+However, in certain scenarios—such as development or testing—you might want to skip TLS verification for a backend service.
+To do this, you can use the [Backend][] API and set the `tls.insecureSkipVerify` field to true in the [Backend][] resource.
+
+Warning: Skipping TLS verification disables certificate validation, which can expose your connection to man-in-the-middle
+attacks. This setting is typically used only for development or testing and is not recommended in production environments.
+
+## Prerequisites
+
+- OpenSSL to generate TLS assets.
+
+## Installation
+
+{{< boilerplate prerequisites >}}
+
+## Enable Backend
+
+The [Backend][] API is disabled by default in Envoy Gateway. To enable it, follow the steps outlined in [Backend Routing][] to configure the [EnvoyGateway][] startup settings accordingly.
+
+## TLS Certificates
+
+Generate the certificates and keys used by the backend to terminate TLS connections from the Gateways.
+
+Create a root certificate and private key to sign certificates:
+
+```shell
+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`.
+
+First, create an openssl configuration file:
+
+```shell
+cat > openssl.conf <}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+## Skip TLS Verification
+
+In the following example, we will create a [Backend][] resource that routes to the `tls-backend` service, and an [HTTPRoute][]
+that references the [Backend][] resource.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Send a request to the backend service:
+
+```shell
+curl -v -HHost:www.example.com --resolve "www.example.com:80:${GATEWAY_HOST}" \
+http://www.example.com:80/get
+```
+
+Because the backend service is using TLS, and no [BackendTLSPolicy][] is configured to validate the TLS certificate,
+the request will fail with a `400 Bad Request` error:
+
+```bash
+* Connected to www.example.com (172.18.0.200) port 80
+* using HTTP/1.x
+> GET /get HTTP/1.1
+> Host:www.example.com
+> User-Agent: curl/8.14.1
+> Accept: */*
+>
+* Request completely sent off
+< HTTP/1.1 400 Bad Request
+< date: Thu, 31 Jul 2025 06:09:51 GMT
+< transfer-encoding: chunked
+```
+
+Disabling TLS verification by setting the `InsecureSkipVerify` field to `true` allows the request to succeed:
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <}}
+
+Send the request again:
+
+```shell
+curl -v -HHost:www.example.com --resolve "www.example.com:80:${GATEWAY_HOST}" \
+http://www.example.com:80/get
+```
+
+You should now see a successful response from the backend service. Since TLS verification has been skipped, the request
+proceeds without validating the backend’s TLS certificate. The response will include TLS details such as the protocol
+version and cipher suite used for the connection.
+
+
+```shell
+< HTTP/1.1 200 OK
+[...]
+ "tls": {
+ "version": "TLSv1.2",
+ "serverName": "",
+ "negotiatedProtocol": "http/1.1",
+ "cipherSuite": "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
+ }
+```
+
+[Backend Routing]: ../traffic/backend/#enable-backend
+[Backend]: ../../../api/extension_types#backend
+[EnvoyGateway]: ../../../api/extension_types#envoygateway
+[HTTPRoute]: https://gateway-api.sigs.k8s.io/api-types/httproute
+[BackendTLSPolicy]: https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/
diff --git a/site/content/en/latest/tasks/security/backend-tls.md b/site/content/en/latest/tasks/security/backend-tls.md
index 8da5195aa4..866e22cb50 100644
--- a/site/content/en/latest/tasks/security/backend-tls.md
+++ b/site/content/en/latest/tasks/security/backend-tls.md
@@ -59,12 +59,35 @@ Store the cert/key in a Secret:
kubectl create secret tls example-cert --key=www.example.com.key --cert=www.example.com.crt
```
-Store the CA Cert in another Secret:
+Store the CA Cert in different ways:
+
+{{< tabpane text=true >}}
+{{% tab header="ConfigMap" %}}
```shell
kubectl create configmap example-ca --from-file=ca.crt
```
+{{% /tab %}}
+
+{{% tab header="ClusterTrustBundle" %}}
+
+Save and apply the following resource to your cluster:
+
+```shell
+apiVersion: certificates.k8s.io/v1beta1
+kind: ClusterTrustBundle
+metadata:
+ name: example-ca
+spec:
+ trustBundle: |
+ [content from ca.crt]
+```
+
+{{% /tab %}}
+
+{{< /tabpane >}}
+
## Setup TLS on the backend
Patch the existing quickstart backend to enable TLS. The patch will mount the TLS certificate secret into the backend as volume.
@@ -159,7 +182,7 @@ Note: SectionName is an optional field that specifies the name of the port in th
If the target is a [Backend] resource, the `sectionName` field should be set to the port number of the backend.
{{< tabpane text=true >}}
-{{% tab header="Apply from stdin" %}}
+{{% tab header="ConfigMap" %}}
```shell
cat <}}
+### Option 2: BackendTrafficPolicy
+Zone aware routing can also be enabled directly with a [BackendTrafficPolicy][BackendTrafficPolicy].
+The example below configures similar behavior to Kubernetes Traffic Distribution and forces all traffic to the local zone via the `force` field instead
+of Envoy's default behavior which _prefers_ routing locally as much as possible while still achieving overall equal request distribution across all endpoints.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+```shell
+cat <}}
+
### Example deployments and HTTPRoute
Next apply the example manifests to create two Deployments and an HTTPRoute. For the test configuration one Deployment
(zone-aware-routing-backend-local) includes affinity for EnvoyProxy Pods to ensure its Pods are scheduled in the same
-zone and the second Deployment (zone-aware-routing-backend-nonlocal) uses anti-affinity to ensure its Pods _don't_
-schedule to the same zone in order to demonstrate functionality.
+zone and the second Deployment (zone-aware-routing-backend-nonlocal) uses anti-affinity to ensure its Pods _don't_
+schedule to the same zone in order to demonstrate functionality.
```shell
kubectl apply -f https://raw.githubusercontent.com/envoyproxy/gateway/latest/examples/kubernetes/zone-aware-routing.yaml -n default
```
@@ -129,7 +188,7 @@ zone-aware-routing-backend-nonlocal 3/3 3 3 9m1s
```
-An HTTPRoute resource is created for the `/zone-aware-routing` path prefix along with two example Deployment resources that
+An HTTPRoute resource is created for the `/zone-aware-routing` path prefix along with two example Deployment resources that
are respectively configured with pod affinity/anti-affinity targeting the Envoy Proxy Pods for testing.
Verify the HTTPRoute configuration and status:
@@ -138,6 +197,12 @@ Verify the HTTPRoute configuration and status:
kubectl get httproute/zone-aware-routing -o yaml
```
+If used during configuration, verify the [BackendTrafficPolicy][BackendTrafficPolicy]:
+
+```shell
+kubectl get backendtrafficpolicy/zone-aware-routing -o yaml
+```
+
## Testing
Ensure the `GATEWAY_HOST` environment variable from the [Quickstart](../../quickstart) is set. If not, follow the
@@ -204,9 +269,11 @@ kubectl delete service/zone-aware-routing-backend
kubectl delete deployment/zone-aware-routing-backend-local
kubectl delete deployment/zone-aware-routing-backend-nonlocal
kubectl delete httproute/zone-aware-routing
+kubectl delete backendtrafficpolicy/zone-aware-routing
```
[Traffic Distribution]: https://kubernetes.io/docs/concepts/services-networking/service/#traffic-distribution
[Topology Aware Routing]: https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/
[Kubernetes well-known metadata]: https://kubernetes.io/docs/reference/labels-annotations-taints/#topologykubernetesiozone
-[Envoy Zone Aware Routing]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/zone_aware
\ No newline at end of file
+[Envoy Zone Aware Routing]: https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/load_balancing/zone_aware
+[BackendTrafficPolicy]: ../../../api/extension_types#backendtrafficpolicy
\ No newline at end of file
diff --git a/site/content/en/latest/troubleshooting/admin-console.md b/site/content/en/latest/troubleshooting/admin-console.md
index b0aa56ce41..1289f75802 100644
--- a/site/content/en/latest/troubleshooting/admin-console.md
+++ b/site/content/en/latest/troubleshooting/admin-console.md
@@ -6,7 +6,7 @@ Envoy Gateway provides a built-in web-based admin console that offers a comprehe
## Prerequisites
-{{< boilerplate o11y_prerequisites >}}
+{{< boilerplate prerequisites >}}
## Overview
diff --git a/site/content/en/news/releases/matrix.md b/site/content/en/news/releases/matrix.md
index 172ec40eaa..1d3d741506 100644
--- a/site/content/en/news/releases/matrix.md
+++ b/site/content/en/news/releases/matrix.md
@@ -5,16 +5,17 @@ description: This section includes Compatibility Matrix of Envoy Gateway.
Envoy Gateway relies on the Envoy Proxy and the Gateway API, and runs within a Kubernetes cluster. Not all versions of each of these products can function together for Envoy Gateway. Supported version combinations are listed below; **bold** type indicates the versions of the Envoy Proxy and the Gateway API actually compiled into each Envoy Gateway release.
-| Envoy Gateway version | Envoy Proxy version | Rate Limit version | Gateway API version | Kubernetes version | End of Life |
-|-----------------------|-----------------------------|--------------------|---------------------|----------------------------|--------------|
-| latest | **dev-latest** | **master** | **v1.3.0** | v1.30, v1.31, v1.32, v1.33 | n/a |
-| v1.4 | **distroless-v1.34.1** | **3e085e5b** | **v1.3.0** | v1.30, v1.31, v1.32, v1.33 | 2025/11/13 |
-| v1.3 | **distroless-v1.33.0** | **60d8e81b** | **v1.2.1** | v1.29, v1.30, v1.31, v1.32 | 2025/07/30 |
-| v1.2 | **distroless-v1.32.1** | **28b1629a** | **v1.2.0** | v1.28, v1.29, v1.30, v1.31 | 2025/05/06 |
-| v1.1 | **distroless-v1.31.0** | **91484c59** | **v1.1.0** | v1.27, v1.28, v1.29, v1.30 | 2025/01/22 |
-| v1.0 | **distroless-v1.29.2** | **19f2079f** | **v1.0.0** | v1.26, v1.27, v1.28, v1.29 | 2024/09/13 |
-| v0.6 | **distroless-v1.28-latest** | **b9796237** | **v1.0.0** | v1.26, v1.27, v1.28 | 2024/05/02 |
-| v0.5 | **v1.27-latest** | **e059638d** | **v0.7.1** | v1.25, v1.26, v1.27 | 2024/01/02 |
-| v0.4 | **v1.26-latest** | **542a6047** | **v0.6.2** | v1.25, v1.26, v1.27 | 2023/10/24 |
-| v0.3 | **v1.25-latest** | **f28024e3** | **v0.6.1** | v1.24, v1.25, v1.26 | 2023/08/09 |
-| v0.2 | **v1.23-latest** | | **v0.5.1** | v1.24 | 2023/04/20 |
+| Envoy Gateway version | Envoy Proxy version | Rate Limit version | Gateway API version | Kubernetes version | End of Life |
+| --------------------- | --------------------------- | ------------------ | ------------------- | -------------------------- | ----------- |
+| latest | **dev-latest** | **master** | **v1.3.0** | v1.30, v1.31, v1.32, v1.33 | n/a |
+| v1.5 | **distroless-v1.35.0** | **a90e0e5d** | **v1.3.0** | v1.30, v1.31, v1.32, v1.33 | 2026/02/13 |
+| v1.4 | **distroless-v1.34.1** | **3e085e5b** | **v1.3.0** | v1.30, v1.31, v1.32, v1.33 | 2025/11/13 |
+| v1.3 | **distroless-v1.33.0** | **60d8e81b** | **v1.2.1** | v1.29, v1.30, v1.31, v1.32 | 2025/07/30 |
+| v1.2 | **distroless-v1.32.1** | **28b1629a** | **v1.2.0** | v1.28, v1.29, v1.30, v1.31 | 2025/05/06 |
+| v1.1 | **distroless-v1.31.0** | **91484c59** | **v1.1.0** | v1.27, v1.28, v1.29, v1.30 | 2025/01/22 |
+| v1.0 | **distroless-v1.29.2** | **19f2079f** | **v1.0.0** | v1.26, v1.27, v1.28, v1.29 | 2024/09/13 |
+| v0.6 | **distroless-v1.28-latest** | **b9796237** | **v1.0.0** | v1.26, v1.27, v1.28 | 2024/05/02 |
+| v0.5 | **v1.27-latest** | **e059638d** | **v0.7.1** | v1.25, v1.26, v1.27 | 2024/01/02 |
+| v0.4 | **v1.26-latest** | **542a6047** | **v0.6.2** | v1.25, v1.26, v1.27 | 2023/10/24 |
+| v0.3 | **v1.25-latest** | **f28024e3** | **v0.6.1** | v1.24, v1.25, v1.26 | 2023/08/09 |
+| v0.2 | **v1.23-latest** | | **v0.5.1** | v1.24 | 2023/04/20 |
diff --git a/site/content/en/v1.3/api/extension_types.md b/site/content/en/v1.3/api/extension_types.md
index 935701739c..c90039f816 100644
--- a/site/content/en/v1.3/api/extension_types.md
+++ b/site/content/en/v1.3/api/extension_types.md
@@ -3716,7 +3716,7 @@ _Appears in:_
_Underlying type:_ _string_
RateLimitUnit specifies the intervals for setting rate limits.
-Valid RateLimitUnit values are "Second", "Minute", "Hour", and "Day".
+Valid RateLimitUnit values are "Second", "Minute", "Hour", "Day", "Month" and "Year".
_Appears in:_
- [RateLimitValue](#ratelimitvalue)
@@ -3727,6 +3727,8 @@ _Appears in:_
| `Minute` | RateLimitUnitMinute specifies the rate limit interval to be 1 minute.
|
| `Hour` | RateLimitUnitHour specifies the rate limit interval to be 1 hour.
|
| `Day` | RateLimitUnitDay specifies the rate limit interval to be 1 day.
|
+| `Month` | RateLimitUnitMonth specifies the rate limit interval to be 1 month.
|
+| `Year` | RateLimitUnitYear specifies the rate limit interval to be 1 year.
|
#### RateLimitValue
diff --git a/site/content/en/v1.4/install/install-egctl.md b/site/content/en/v1.4/install/install-egctl.md
index cbd8238574..72081ce79b 100644
--- a/site/content/en/v1.4/install/install-egctl.md
+++ b/site/content/en/v1.4/install/install-egctl.md
@@ -22,7 +22,7 @@ The Envoy Gateway project provides two ways to fetch and install egctl. These ar
Every [release](https://github.com/envoyproxy/gateway/releases) of egctl provides binary releases for a variety of OSes. These binary versions can be manually downloaded and installed.
1. Download your [desired version](https://github.com/envoyproxy/gateway/releases)
-2. Unpack it (tar -zxvf egctl_latest_linux_amd64.tar.gz)
+2. Unpack it (tar -zxvf egctl_{{< yaml-version >}}_linux_amd64.tar.gz)
3. Find the egctl binary in the unpacked directory, and move it to its desired destination (mv bin/linux/amd64/egctl /usr/local/bin/egctl)
From there, you should be able to run: `egctl help`.
@@ -41,15 +41,12 @@ chmod +x get-egctl.sh
# get help info of the
bash get-egctl.sh --help
-
-# install the latest development version of egctl
-bash VERSION=latest get-egctl.sh
```
Yes, you can just use the below command if you want to live on the edge.
```shell
-curl -fsSL https://gateway.envoyproxy.io/get-egctl.sh | VERSION=latest bash
+curl -fsSL https://gateway.envoyproxy.io/get-egctl.sh | VERSION={{< yaml-version >}} bash
```
{{% /tab %}}
diff --git a/site/content/en/v1.4/tasks/operations/gateway-namespace-mode.md b/site/content/en/v1.4/tasks/operations/gateway-namespace-mode.md
index f71b2c688f..7789274463 100644
--- a/site/content/en/v1.4/tasks/operations/gateway-namespace-mode.md
+++ b/site/content/en/v1.4/tasks/operations/gateway-namespace-mode.md
@@ -14,10 +14,15 @@ For status updates or to provide feedback, please follow our [GitHub issues](htt
In standard deployment mode, Envoy Gateway creates all data plane resources in the controller namespace (typically `envoy-gateway-system`).
-Gateway Namespace Mode changes this behavior by placing Envoy Proxy data plane resources like Deployments, Services and ServiceAccounts in each Gateway's namespace, providing stronger isolation and multi-tenancy.
+The motivation behind this was to operate with minimum permissions needed to be given for Envoy Gateway controller, as the control plane and data plane was deployed in the same namespace.
-Traditional deployment mode uses mTLS where both the client and server authenticate each other. However, in Gateway Namespace Mode, we've shifted to server-side TLS and JWT token validation between infra and control-plane.
+Gateway Namespace Mode changes this behavior by placing Envoy Proxy data plane resources like Deployments, Services and ServiceAccounts in each Gateway's namespace, which provides stronger isolation and multi-tenancy compared to the Controller Namespace mode, as it isolates Envoy proxy data plane across different tenants.
+This distributed architecture requires additional RBAC permissions for the Envoy Gateway controller to manage Kubernetes resources across multiple namespaces.
+The default (Controller Namespace) deployment mode uses mTLS where both the client and server authenticate each other. However, in Gateway Namespace Mode, we've shifted to server-side TLS and JWT token validation between infra and control-plane.
+
+* **Envoy proxy pods** (running in Gateway namespaces) act as clients and authenticate using JWT tokens
+* **Envoy Gateway controller pod** (running in controller namespace) acts as the server and validates JWT tokens
* Only the CA certificate is available in pods running in Gateway namespaces
* Client certificates are not mounted in these namespaces
* The Envoy proxy still validates server certificates using the CA certificate
diff --git a/site/go.mod b/site/go.mod
index 91bba45182..f4700f1891 100644
--- a/site/go.mod
+++ b/site/go.mod
@@ -1,6 +1,6 @@
module github.com/google/docsy-example
-go 1.24.4
+go 1.24.7
require (
github.com/FortAwesome/Font-Awesome v0.0.0-20241216213156-af620534bfc3 // indirect
diff --git a/test/cel-validation/backendtrafficpolicy_test.go b/test/cel-validation/backendtrafficpolicy_test.go
index f0259ad112..2f500539d4 100644
--- a/test/cel-validation/backendtrafficpolicy_test.go
+++ b/test/cel-validation/backendtrafficpolicy_test.go
@@ -432,9 +432,7 @@ func TestBackendTrafficPolicyTarget(t *testing.T) {
LoadBalancer: &egv1a1.LoadBalancer{
Type: egv1a1.LeastRequestLoadBalancerType,
SlowStart: &egv1a1.SlowStart{
- Window: &metav1.Duration{
- Duration: 10000000,
- },
+ Window: ptr.To(gwapiv1.Duration("10ms")),
},
},
},
@@ -459,9 +457,7 @@ func TestBackendTrafficPolicyTarget(t *testing.T) {
LoadBalancer: &egv1a1.LoadBalancer{
Type: egv1a1.RoundRobinLoadBalancerType,
SlowStart: &egv1a1.SlowStart{
- Window: &metav1.Duration{
- Duration: 10000000,
- },
+ Window: ptr.To(gwapiv1.Duration("10ms")),
},
},
},
@@ -486,9 +482,7 @@ func TestBackendTrafficPolicyTarget(t *testing.T) {
LoadBalancer: &egv1a1.LoadBalancer{
Type: egv1a1.RandomLoadBalancerType,
SlowStart: &egv1a1.SlowStart{
- Window: &metav1.Duration{
- Duration: 10000000,
- },
+ Window: ptr.To(gwapiv1.Duration("10ms")),
},
},
},
@@ -515,9 +509,7 @@ func TestBackendTrafficPolicyTarget(t *testing.T) {
LoadBalancer: &egv1a1.LoadBalancer{
Type: egv1a1.ConsistentHashLoadBalancerType,
SlowStart: &egv1a1.SlowStart{
- Window: &metav1.Duration{
- Duration: 10000000,
- },
+ Window: ptr.To(gwapiv1.Duration("10ms")),
},
},
},
@@ -653,9 +645,7 @@ func TestBackendTrafficPolicyTarget(t *testing.T) {
},
FaultInjection: &egv1a1.FaultInjection{
Delay: &egv1a1.FaultInjectionDelay{
- FixedDelay: &metav1.Duration{
- Duration: 10000000,
- },
+ FixedDelay: ptr.To(gwapiv1.Duration("10ms")),
},
},
}
@@ -953,7 +943,7 @@ func TestBackendTrafficPolicyTarget(t *testing.T) {
}
},
wantErrors: []string{
- `spec.HealthCheck.active.http.expectedStatuses[2]: Invalid value: 601: spec.HealthCheck.active.http.expectedStatuses[2] in body should be less than 600`,
+ `spec.HealthCheck.active.http.expectedStatuses[2]: Invalid value: 601: spec.HealthCheck.active.http.expectedStatuses[2] in body should be less than or equal to 599`,
},
},
{
diff --git a/test/cel-validation/envoyproxy_test.go b/test/cel-validation/envoyproxy_test.go
index cd0e379956..34b76adc0e 100644
--- a/test/cel-validation/envoyproxy_test.go
+++ b/test/cel-validation/envoyproxy_test.go
@@ -1616,7 +1616,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
wantErrors: []string{},
},
{
- desc: "valid: imageRepository set without tag, image not set",
+ desc: "valid: image set with digest, imageRepository not set",
mutate: func(envoy *egv1a1.EnvoyProxy) {
envoy.Spec = egv1a1.EnvoyProxySpec{
Provider: &egv1a1.EnvoyProxyProvider{
@@ -1624,7 +1624,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
Container: &egv1a1.KubernetesContainerSpec{
- ImageRepository: ptr.To("envoyproxy/envoy"),
+ Image: ptr.To("envoyproxy/envoy:v1.2.3@sha256:da99c47f08546492d19973920dc76334c592f59ad5b732a514320d959db9fa40"),
},
},
},
@@ -1634,7 +1634,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
wantErrors: []string{},
},
{
- desc: "invalid: both image and imageRepository set",
+ desc: "valid: image with sha256, imageRepository not set",
mutate: func(envoy *egv1a1.EnvoyProxy) {
envoy.Spec = egv1a1.EnvoyProxySpec{
Provider: &egv1a1.EnvoyProxyProvider{
@@ -1642,18 +1642,17 @@ func TestEnvoyProxyProvider(t *testing.T) {
Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
Container: &egv1a1.KubernetesContainerSpec{
- Image: ptr.To("envoyproxy/envoy:v1.2.3"),
- ImageRepository: ptr.To("envoyproxy/envoy"),
+ Image: ptr.To("envoyproxy/envoy@sha256:da99c47f08546492d19973920dc76334c592f59ad5b732a514320d959db9fa40"),
},
},
},
},
}
},
- wantErrors: []string{"Either image or imageRepository can be set."},
+ wantErrors: []string{},
},
{
- desc: "invalid: image set without tag",
+ desc: "valid: image set without tag",
mutate: func(envoy *egv1a1.EnvoyProxy) {
envoy.Spec = egv1a1.EnvoyProxySpec{
Provider: &egv1a1.EnvoyProxyProvider{
@@ -1668,7 +1667,80 @@ func TestEnvoyProxyProvider(t *testing.T) {
},
}
},
- wantErrors: []string{"Image must include a tag and allowed characters only (e.g., 'repo:tag')."},
+ wantErrors: []string{},
+ },
+ {
+ desc: "valid: imageRepository with ip and port",
+ mutate: func(envoy *egv1a1.EnvoyProxy) {
+ envoy.Spec = egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
+ Container: &egv1a1.KubernetesContainerSpec{
+ ImageRepository: ptr.To("192.168.1.1:8000"),
+ },
+ },
+ },
+ },
+ }
+ },
+ wantErrors: []string{},
+ },
+ {
+ desc: "valid: imageRepository with domain and port",
+ mutate: func(envoy *egv1a1.EnvoyProxy) {
+ envoy.Spec = egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
+ Container: &egv1a1.KubernetesContainerSpec{
+ ImageRepository: ptr.To("registry.com:8000"),
+ },
+ },
+ },
+ },
+ }
+ },
+ wantErrors: []string{},
+ },
+ {
+ desc: "valid: imageRepository set without tag, image not set",
+ mutate: func(envoy *egv1a1.EnvoyProxy) {
+ envoy.Spec = egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
+ Container: &egv1a1.KubernetesContainerSpec{
+ ImageRepository: ptr.To("envoyproxy/envoy"),
+ },
+ },
+ },
+ },
+ }
+ },
+ wantErrors: []string{},
+ },
+ {
+ desc: "invalid: both image and imageRepository set",
+ mutate: func(envoy *egv1a1.EnvoyProxy) {
+ envoy.Spec = egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
+ Container: &egv1a1.KubernetesContainerSpec{
+ Image: ptr.To("envoyproxy/envoy:v1.2.3"),
+ ImageRepository: ptr.To("envoyproxy/envoy"),
+ },
+ },
+ },
+ },
+ }
+ },
+ wantErrors: []string{"Either image or imageRepository can be set."},
},
{
desc: "invalid: image ends with colon",
@@ -1724,6 +1796,42 @@ func TestEnvoyProxyProvider(t *testing.T) {
},
wantErrors: []string{"Image must include a tag and allowed characters only (e.g., 'repo:tag')."},
},
+ {
+ desc: "valid: image with domain and port",
+ mutate: func(envoy *egv1a1.EnvoyProxy) {
+ envoy.Spec = egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
+ Container: &egv1a1.KubernetesContainerSpec{
+ Image: ptr.To("registry.com:3000/envoy:v1.2.3"),
+ },
+ },
+ },
+ },
+ }
+ },
+ wantErrors: []string{},
+ },
+ {
+ desc: "valid: image with ip and port",
+ mutate: func(envoy *egv1a1.EnvoyProxy) {
+ envoy.Spec = egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
+ Container: &egv1a1.KubernetesContainerSpec{
+ Image: ptr.To("127.0.0.1:3000/envoy:v1.2.3"),
+ },
+ },
+ },
+ },
+ }
+ },
+ wantErrors: []string{},
+ },
{
desc: "invalid: imageRepository contains tag",
mutate: func(envoy *egv1a1.EnvoyProxy) {
@@ -1740,7 +1848,43 @@ func TestEnvoyProxyProvider(t *testing.T) {
},
}
},
- wantErrors: []string{"ImageRepository must contain only allowed characters and must not include a tag or any colons."},
+ wantErrors: []string{"ImageRepository must contain only allowed characters and must not include a tag."},
+ },
+ {
+ desc: "valid: imageRepository set with port",
+ mutate: func(envoy *egv1a1.EnvoyProxy) {
+ envoy.Spec = egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
+ Container: &egv1a1.KubernetesContainerSpec{
+ ImageRepository: ptr.To("docker.io:443/envoyproxy/envoy"),
+ },
+ },
+ },
+ },
+ }
+ },
+ wantErrors: []string{},
+ },
+ {
+ desc: "invalid: imageRepository set with port and tag",
+ mutate: func(envoy *egv1a1.EnvoyProxy) {
+ envoy.Spec = egv1a1.EnvoyProxySpec{
+ Provider: &egv1a1.EnvoyProxyProvider{
+ Type: egv1a1.ProviderTypeKubernetes,
+ Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
+ EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
+ Container: &egv1a1.KubernetesContainerSpec{
+ ImageRepository: ptr.To("docker.io:443/envoyproxy/envoy:v1.2.3"),
+ },
+ },
+ },
+ },
+ }
+ },
+ wantErrors: []string{"ImageRepository must contain only allowed characters and must not include a tag."},
},
}
diff --git a/test/cel-validation/securitypolicy_test.go b/test/cel-validation/securitypolicy_test.go
index 10a057894e..9f8f8b4d44 100644
--- a/test/cel-validation/securitypolicy_test.go
+++ b/test/cel-validation/securitypolicy_test.go
@@ -1315,12 +1315,8 @@ func TestSecurityPolicyTarget(t *testing.T) {
NumRetries: ptr.To(int32(3)),
PerRetry: &egv1a1.PerRetryPolicy{
BackOff: &egv1a1.BackOffPolicy{
- BaseInterval: &metav1.Duration{
- Duration: time.Second * 1,
- },
- MaxInterval: &metav1.Duration{
- Duration: time.Second * 10,
- },
+ BaseInterval: ptr.To(gwapiv1.Duration("1s")),
+ MaxInterval: ptr.To(gwapiv1.Duration("10s")),
},
},
RetryOn: &egv1a1.RetryOn{
@@ -1366,9 +1362,7 @@ func TestSecurityPolicyTarget(t *testing.T) {
Retry: &egv1a1.Retry{
NumRetries: ptr.To(int32(3)),
PerRetry: &egv1a1.PerRetryPolicy{
- Timeout: &metav1.Duration{
- Duration: time.Second * 10,
- },
+ Timeout: ptr.To(gwapiv1.Duration("10s")),
},
RetryOn: &egv1a1.RetryOn{
HTTPStatusCodes: []egv1a1.HTTPStatus{500},
diff --git a/test/e2e/testdata/backend-tls.yaml b/test/e2e/testdata/backend-tls.yaml
index b95dbaa900..1f6f7d0637 100644
--- a/test/e2e/testdata/backend-tls.yaml
+++ b/test/e2e/testdata/backend-tls.yaml
@@ -153,7 +153,7 @@ spec:
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: Backend
metadata:
- name: backend-insecure-tls-verify
+ name: backend-insecure-tls-verify-and-mismatch-ca
namespace: gateway-conformance-infra
spec:
endpoints:
@@ -166,7 +166,7 @@ spec:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
- name: http-with-backend-insecure-skip-verify
+ name: http-with-backend-insecure-skip-verify-and-mismatch-ca
namespace: gateway-conformance-infra
spec:
parentRefs:
@@ -175,9 +175,40 @@ spec:
- matches:
- path:
type: PathPrefix
- value: /backend-tls-skip-verify
+ value: /backend-tls-skip-verify-and-mismatch-ca
backendRefs:
- - name: backend-insecure-tls-verify
+ - name: backend-insecure-tls-verify-and-mismatch-ca
+ group: gateway.envoyproxy.io
+ kind: Backend
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: Backend
+metadata:
+ name: backend-insecure-tls-verify-without-backend-tls-policy
+ namespace: gateway-conformance-infra
+spec:
+ endpoints:
+ - fqdn:
+ hostname: tls-backend-2.gateway-conformance-infra.svc.cluster.local
+ port: 443
+ tls:
+ insecureSkipVerify: true
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: http-with-backend-insecure-skip-verify-without-backend-tls-policy
+ namespace: gateway-conformance-infra
+spec:
+ parentRefs:
+ - name: same-namespace
+ rules:
+ - matches:
+ - path:
+ type: PathPrefix
+ value: /backend-tls-skip-verify-without-backend-tls-policy
+ backendRefs:
+ - name: backend-insecure-tls-verify-without-backend-tls-policy
group: gateway.envoyproxy.io
kind: Backend
---
diff --git a/test/e2e/testdata/zone-aware-routing-backendref-enabled.yaml b/test/e2e/testdata/zone-aware-routing-backendref-enabled.yaml
new file mode 100644
index 0000000000..fdec6ba43c
--- /dev/null
+++ b/test/e2e/testdata/zone-aware-routing-backendref-enabled.yaml
@@ -0,0 +1,33 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: topology-aware-routing
+ namespace: gateway-conformance-infra
+ annotations:
+ service.kubernetes.io/topology-mode: Auto
+spec:
+ selector:
+ app: zone-aware-backend
+ ports:
+ - protocol: TCP
+ port: 8080
+ name: http11
+ targetPort: 3000
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: topology-aware-routing
+ namespace: gateway-conformance-infra
+spec:
+ parentRefs:
+ - name: same-namespace
+ rules:
+ - matches:
+ - path:
+ type: PathPrefix
+ value: /topology-aware-routing
+ backendRefs:
+ - name: topology-aware-routing
+ port: 8080
+ weight: 1
diff --git a/test/e2e/testdata/zone-aware-routing-btp-force-local-zone.yaml b/test/e2e/testdata/zone-aware-routing-btp-force-local-zone.yaml
new file mode 100644
index 0000000000..eadc25c0f7
--- /dev/null
+++ b/test/e2e/testdata/zone-aware-routing-btp-force-local-zone.yaml
@@ -0,0 +1,49 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: btp-force-local-zone
+ namespace: gateway-conformance-infra
+spec:
+ selector:
+ app: zone-aware-backend
+ ports:
+ - protocol: TCP
+ port: 8080
+ name: http11
+ targetPort: 3000
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: btp-force-local-zone
+ namespace: gateway-conformance-infra
+spec:
+ parentRefs:
+ - name: same-namespace
+ rules:
+ - matches:
+ - path:
+ type: PathPrefix
+ value: /btp-force-local-zone
+ backendRefs:
+ - name: btp-force-local-zone
+ port: 8080
+ weight: 1
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: BackendTrafficPolicy
+metadata:
+ name: btp-force-local-zone
+ namespace: gateway-conformance-infra
+spec:
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: btp-force-local-zone
+ loadBalancer:
+ type: RoundRobin
+ zoneAware:
+ preferLocal:
+ minEndpointsThreshold: 1
+ force:
+ minEndpointsInZoneThreshold: 1
diff --git a/test/e2e/testdata/zone-aware-routing-btp-no-force-local-zone.yaml b/test/e2e/testdata/zone-aware-routing-btp-no-force-local-zone.yaml
new file mode 100644
index 0000000000..740896187c
--- /dev/null
+++ b/test/e2e/testdata/zone-aware-routing-btp-no-force-local-zone.yaml
@@ -0,0 +1,47 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: btp-no-force-local-zone
+ namespace: gateway-conformance-infra
+spec:
+ selector:
+ app: zone-aware-backend
+ ports:
+ - protocol: TCP
+ port: 8080
+ name: http11
+ targetPort: 3000
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: btp-no-force-local-zone
+ namespace: gateway-conformance-infra
+spec:
+ parentRefs:
+ - name: same-namespace
+ rules:
+ - matches:
+ - path:
+ type: PathPrefix
+ value: /btp-no-force-local-zone
+ backendRefs:
+ - name: btp-no-force-local-zone
+ port: 8080
+ weight: 1
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: BackendTrafficPolicy
+metadata:
+ name: btp-no-force-local-zone
+ namespace: gateway-conformance-infra
+spec:
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: btp-no-force-local-zone
+ loadBalancer:
+ type: RoundRobin
+ zoneAware:
+ preferLocal:
+ minEndpointsThreshold: 1
diff --git a/test/e2e/testdata/zone-aware-routing.yaml b/test/e2e/testdata/zone-aware-routing-deployments.yaml
similarity index 82%
rename from test/e2e/testdata/zone-aware-routing.yaml
rename to test/e2e/testdata/zone-aware-routing-deployments.yaml
index 63a2414fca..492ff92a16 100644
--- a/test/e2e/testdata/zone-aware-routing.yaml
+++ b/test/e2e/testdata/zone-aware-routing-deployments.yaml
@@ -99,37 +99,3 @@ spec:
- proxy
topologyKey: topology.kubernetes.io/zone
namespaceSelector: {}
----
-apiVersion: v1
-kind: Service
-metadata:
- name: zone-aware-backend
- namespace: gateway-conformance-infra
- annotations:
- service.kubernetes.io/topology-mode: Auto
-spec:
- selector:
- app: zone-aware-backend
- ports:
- - protocol: TCP
- port: 8080
- name: http11
- targetPort: 3000
----
-apiVersion: gateway.networking.k8s.io/v1
-kind: HTTPRoute
-metadata:
- name: zone-aware-http-route
- namespace: gateway-conformance-infra
-spec:
- parentRefs:
- - name: same-namespace
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /
- backendRefs:
- - name: zone-aware-backend
- port: 8080
- weight: 1
diff --git a/test/e2e/testdata/zone-aware-routing-gateways.yaml b/test/e2e/testdata/zone-aware-routing-gateways.yaml
new file mode 100644
index 0000000000..90d6781697
--- /dev/null
+++ b/test/e2e/testdata/zone-aware-routing-gateways.yaml
@@ -0,0 +1,91 @@
+# zone-aware-routing-gtw should be similar to `same-namespace` gateway, only difference
+# is having a hard-coded service name in the EnvoyProxy attached, to test zone-aware-routing
+# in that case when no ForceLocal is specified.
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+ name: zone-aware-routing-gtw
+ namespace: gateway-conformance-infra
+spec:
+ gatewayClassName: "{GATEWAY_CLASS_NAME}"
+ listeners:
+ - name: http
+ port: 80
+ protocol: HTTP
+ allowedRoutes:
+ namespaces:
+ from: Same
+ - name: tls
+ protocol: TLS
+ port: 443
+ tls:
+ mode: Passthrough
+ allowedRoutes:
+ namespaces:
+ from: Same
+ infrastructure:
+ parametersRef:
+ group: gateway.envoyproxy.io
+ kind: EnvoyProxy
+ name: zone-aware-routing
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyProxy
+metadata:
+ name: zone-aware-routing
+ namespace: gateway-conformance-infra
+spec:
+ ipFamily: IPv4
+ provider:
+ type: Kubernetes
+ kubernetes:
+ envoyService:
+ name: zone-aware-routing-gtw
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: btp-no-force-local-zone-hardcoded-svc-name
+ namespace: gateway-conformance-infra
+spec:
+ selector:
+ app: zone-aware-backend
+ ports:
+ - protocol: TCP
+ port: 8080
+ name: http11
+ targetPort: 3000
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: btp-no-force-local-zone-hardcoded-svc-name
+ namespace: gateway-conformance-infra
+spec:
+ parentRefs:
+ - name: zone-aware-routing-gtw
+ rules:
+ - matches:
+ - path:
+ type: PathPrefix
+ value: /btp-no-force-local-zone-hardcoded-svc-name
+ backendRefs:
+ - name: btp-no-force-local-zone-hardcoded-svc-name
+ port: 8080
+ weight: 1
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: BackendTrafficPolicy
+metadata:
+ name: btp-no-force-local-zone-hardcoded-svc-name
+ namespace: gateway-conformance-infra
+spec:
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: btp-no-force-local-zone-hardcoded-svc-name
+ loadBalancer:
+ type: RoundRobin
+ zoneAware:
+ preferLocal:
+ minEndpointsThreshold: 1
diff --git a/test/e2e/tests/backend_tls.go b/test/e2e/tests/backend_tls.go
index bb76ed9ef3..e711f79492 100644
--- a/test/e2e/tests/backend_tls.go
+++ b/test/e2e/tests/backend_tls.go
@@ -88,12 +88,29 @@ var BackendTLSTest = suite.ConformanceTest{
})
t.Run("with CA mismatch and skip tls verify", func(t *testing.T) {
- routeNN := types.NamespacedName{Name: "http-with-backend-insecure-skip-verify", Namespace: ConformanceInfraNamespace}
+ routeNN := types.NamespacedName{Name: "http-with-backend-insecure-skip-verify-and-mismatch-ca", Namespace: ConformanceInfraNamespace}
gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
expectedResponse := http.ExpectedResponse{
Request: http.Request{
- Path: "/backend-tls-skip-verify",
+ Path: "/backend-tls-skip-verify-and-mismatch-ca",
+ },
+ Response: http.Response{
+ StatusCode: 200, // Bad Request: Client sent an HTTP request to an HTTPS server
+ },
+ Namespace: ConformanceInfraNamespace,
+ }
+
+ http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
+ })
+
+ t.Run("without BackendTLSPolicy and skip tls verify", func(t *testing.T) {
+ routeNN := types.NamespacedName{Name: "http-with-backend-insecure-skip-verify-without-backend-tls-policy", Namespace: ConformanceInfraNamespace}
+ gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+
+ expectedResponse := http.ExpectedResponse{
+ Request: http.Request{
+ Path: "/backend-tls-skip-verify-without-backend-tls-policy",
},
Response: http.Response{
StatusCode: 200, // Bad Request: Client sent an HTTP request to an HTTPS server
diff --git a/test/e2e/tests/connection_limit.go b/test/e2e/tests/connection_limit.go
index 15e316fec4..c60dfaf2ce 100644
--- a/test/e2e/tests/connection_limit.go
+++ b/test/e2e/tests/connection_limit.go
@@ -85,6 +85,9 @@ var ConnectionLimitTest = suite.ConformanceTest{
}
prefix := "http-10080"
+ if XDSNameSchemeV2() {
+ prefix = "http-80"
+ }
gtwName := "connection-limit-gateway"
promQL := fmt.Sprintf(`envoy_connection_limit_limited_connections{envoy_connection_limit_prefix="%s",gateway_envoyproxy_io_owning_gateway_name="%s"}`, prefix, gtwName)
diff --git a/test/e2e/tests/weighted_backend.go b/test/e2e/tests/weighted_backend.go
index 154c6f5fbf..51fc0d1cb6 100644
--- a/test/e2e/tests/weighted_backend.go
+++ b/test/e2e/tests/weighted_backend.go
@@ -39,7 +39,7 @@ var WeightedBackendTest = suite.ConformanceTest{
"infra-backend-v1": sendRequests * .5,
"infra-backend-v2": sendRequests * .5,
}
- runWeightedBackendTest(t, suite, "weight-equal-http-route", "/same-weight", "infra-backend", expected)
+ runWeightedBackendTest(t, suite, nil, "weight-equal-http-route", "/same-weight", "infra-backend", expected)
})
t.Run("BlueGreen", func(t *testing.T) {
// The received request is approximately 9:1
@@ -47,7 +47,7 @@ var WeightedBackendTest = suite.ConformanceTest{
"infra-backend-v1": sendRequests * .9,
"infra-backend-v2": sendRequests * .1,
}
- runWeightedBackendTest(t, suite, "weight-bluegreen-http-route", "/blue-green", "infra-backend", expected)
+ runWeightedBackendTest(t, suite, nil, "weight-bluegreen-http-route", "/blue-green", "infra-backend", expected)
})
t.Run("CompleteRollout", func(t *testing.T) {
// All the requests should be proxied to v1
@@ -55,16 +55,20 @@ var WeightedBackendTest = suite.ConformanceTest{
"infra-backend-v1": sendRequests * 1,
"infra-backend-v2": sendRequests * 0,
}
- runWeightedBackendTest(t, suite, "weight-complete-rollout-http-route", "/complete-rollout", "infra-backend", expected)
+ runWeightedBackendTest(t, suite, nil, "weight-complete-rollout-http-route", "/complete-rollout", "infra-backend", expected)
})
},
}
-func runWeightedBackendTest(t *testing.T, suite *suite.ConformanceTestSuite, routeName, path, backendName string, expectedOutput map[string]int) {
+func runWeightedBackendTest(t *testing.T, suite *suite.ConformanceTestSuite, gateway *types.NamespacedName, routeName, path, backendName string, expectedOutput map[string]int) {
weightEqualRoute := types.NamespacedName{Name: routeName, Namespace: ConformanceInfraNamespace}
- gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig,
- suite.ControllerName,
- kubernetes.NewGatewayRef(SameNamespaceGateway), weightEqualRoute)
+
+ gatewayRef := kubernetes.NewGatewayRef(SameNamespaceGateway)
+ if gateway != nil {
+ gatewayRef = kubernetes.NewGatewayRef(*gateway)
+ }
+
+ gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, gatewayRef, weightEqualRoute)
// Make sure all test resources are ready
kubernetes.NamespacesMustBeReady(t, suite.Client, suite.TimeoutConfig, []string{ConformanceInfraNamespace})
diff --git a/test/e2e/tests/zone_aware_routing.go b/test/e2e/tests/zone_aware_routing.go
index 5ac6edc0fa..1234470400 100644
--- a/test/e2e/tests/zone_aware_routing.go
+++ b/test/e2e/tests/zone_aware_routing.go
@@ -8,9 +8,16 @@
package tests
import (
+ "math"
"testing"
+ "k8s.io/apimachinery/pkg/types"
+ gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
+ gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
"sigs.k8s.io/gateway-api/conformance/utils/suite"
+
+ "github.com/envoyproxy/gateway/internal/gatewayapi"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
)
func init() {
@@ -19,17 +26,90 @@ func init() {
var ZoneAwareRoutingTest = suite.ConformanceTest{
ShortName: "ZoneAwareRouting",
- Description: "Resource with Zone Aware Routing enabled",
- Manifests: []string{"testdata/zone-aware-routing.yaml"},
+ Description: "Test Zone Aware Routing is working",
+ Manifests: []string{
+ "testdata/zone-aware-routing-backendref-enabled.yaml",
+ "testdata/zone-aware-routing-btp-force-local-zone.yaml",
+ "testdata/zone-aware-routing-btp-no-force-local-zone.yaml",
+ "testdata/zone-aware-routing-deployments.yaml",
+ "testdata/zone-aware-routing-gateways.yaml",
+ },
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
- t.Run("only local zone should get requests", func(t *testing.T) {
+ t.Run("topology aware routing - only local zone should get requests", func(t *testing.T) {
+ // Pods from the backend-local deployment have affinity
+ // for the Envoy Proxy pods so should receive all requests.
+ expected := map[string]int{
+ "zone-aware-backend-local": sendRequests,
+ "zone-aware-backend-nonlocal": 0,
+ }
+ runWeightedBackendTest(t, suite, nil, "topology-aware-routing", "/topology-aware-routing", "zone-aware-backend", expected)
+ })
+ t.Run("BackendTrafficPolicy - ForceLocalZone - only local zone should get requests", func(t *testing.T) {
+ BackendTrafficPolicyMustBeAccepted(t,
+ suite.Client,
+ types.NamespacedName{Name: "btp-force-local-zone", Namespace: "gateway-conformance-infra"},
+ suite.ControllerName,
+ gwapiv1a2.ParentReference{
+ Group: gatewayapi.GroupPtr(gwapiv1.GroupName),
+ Kind: gatewayapi.KindPtr(resource.KindGateway),
+ Namespace: gatewayapi.NamespacePtr("gateway-conformance-infra"),
+ Name: gwapiv1.ObjectName("same-namespace"),
+ },
+ )
+
// Pods from the backend-local deployment have affinity
// for the Envoy Proxy pods so should receive all requests.
expected := map[string]int{
"zone-aware-backend-local": sendRequests,
"zone-aware-backend-nonlocal": 0,
}
- runWeightedBackendTest(t, suite, "zone-aware-http-route", "/", "zone-aware-backend", expected)
+ runWeightedBackendTest(t, suite, nil, "btp-force-local-zone", "/btp-force-local-zone", "zone-aware-backend", expected)
+ })
+ t.Run("BackendTrafficPolicy - No ForceLocalZone - local zone should get around 75% of requests", func(t *testing.T) {
+ BackendTrafficPolicyMustBeAccepted(t,
+ suite.Client,
+ types.NamespacedName{Name: "btp-no-force-local-zone", Namespace: "gateway-conformance-infra"},
+ suite.ControllerName,
+ gwapiv1a2.ParentReference{
+ Group: gatewayapi.GroupPtr(gwapiv1.GroupName),
+ Kind: gatewayapi.KindPtr(resource.KindGateway),
+ Namespace: gatewayapi.NamespacePtr("gateway-conformance-infra"),
+ Name: gwapiv1.ObjectName("same-namespace"),
+ },
+ )
+
+ // Pods from the backend-local deployment have affinity for the Envoy Proxy pods.
+ // ForceLocal is not used, and overall we have 4 backend pods, 3 local and 1 non-local.
+ // Distribution of upstream is 75% local, 25% non-local. Distribution of envoy is 100% local.
+ // Expect local upstream to get around 75% of traffic.
+ expected := map[string]int{
+ "zone-aware-backend-local": int(math.Round(sendRequests * .75)),
+ "zone-aware-backend-nonlocal": int(math.Round(sendRequests * .25)),
+ }
+ runWeightedBackendTest(t, suite, nil, "btp-no-force-local-zone", "/btp-no-force-local-zone", "zone-aware-backend", expected)
+ })
+ t.Run("BackendTrafficPolicy - No ForceLocalZone - Hardcoded service name in EnvoyProxy - local zone should get around 75% of requests", func(t *testing.T) {
+ BackendTrafficPolicyMustBeAccepted(t,
+ suite.Client,
+ types.NamespacedName{Name: "btp-no-force-local-zone-hardcoded-svc-name", Namespace: "gateway-conformance-infra"},
+ suite.ControllerName,
+ gwapiv1a2.ParentReference{
+ Group: gatewayapi.GroupPtr(gwapiv1.GroupName),
+ Kind: gatewayapi.KindPtr(resource.KindGateway),
+ Namespace: gatewayapi.NamespacePtr("gateway-conformance-infra"),
+ Name: gwapiv1.ObjectName("zone-aware-routing-gtw"),
+ },
+ )
+
+ // Pods from the backend-local deployment have affinity for the Envoy Proxy pods.
+ // ForceLocal is not used, and overall we have 4 backend pods, 3 local and 1 non-local.
+ // Distribution of upstream is 75% local, 25% non-local. Distribution of envoy is 100% local.
+ // Expect local upstream to get around 75% of traffic.
+ expected := map[string]int{
+ "zone-aware-backend-local": int(math.Round(sendRequests * .75)),
+ "zone-aware-backend-nonlocal": int(math.Round(sendRequests * .25)),
+ }
+ runWeightedBackendTest(t, suite, &types.NamespacedName{Name: "zone-aware-routing-gtw", Namespace: "gateway-conformance-infra"}, "btp-no-force-local-zone-hardcoded-svc-name", "/btp-no-force-local-zone-hardcoded-svc-name", "zone-aware-backend", expected)
})
},
}
diff --git a/test/gobench/translate_test.go b/test/gobench/translate_test.go
new file mode 100644
index 0000000000..cc1abaac14
--- /dev/null
+++ b/test/gobench/translate_test.go
@@ -0,0 +1,359 @@
+// 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 fuzz
+
+import (
+ "fmt"
+ "strings"
+ "testing"
+
+ "github.com/envoyproxy/gateway/internal/cmd/egctl"
+ "github.com/envoyproxy/gateway/internal/gatewayapi/resource"
+)
+
+// Reused YAML snippets.
+const (
+ baseYAML = `apiVersion: gateway.networking.k8s.io/v1
+kind: GatewayClass
+metadata:
+ name: eg
+spec:
+ controllerName: gateway.envoyproxy.io/gatewayclass-controller
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+ name: eg
+ namespace: default
+spec:
+ gatewayClassName: eg
+ listeners:
+ - name: http
+ protocol: HTTP
+ port: 80
+ - name: https
+ protocol: HTTPS
+ port: 443
+ tls:
+ mode: Terminate
+ certificateRefs:
+ - name: tls-secret
+ - name: grpc
+ protocol: HTTP
+ port: 81
+ - name: udp
+ protocol: UDP
+ port: 82
+`
+ backendYAML = `---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: Backend
+metadata:
+ name: provided-backend
+ namespace: default
+spec:
+ endpoints:
+ - ip:
+ address: 0.0.0.0
+ port: 8000
+`
+ tlsSecretYAML = `---
+apiVersion: v1
+kind: Secret
+metadata:
+ name: tls-secret
+ namespace: default
+type: kubernetes.io/tls
+data:
+ tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURERENDQWZTZ0F3SUJBZ0lVRUZNaFA5ZUo5WEFCV3NRNVptNmJSazJjTE5Rd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZqRVVNQklHQTFVRUF3d0xabTl2TG1KaGNpNWpiMjB3SGhjTk1qUXdNakk1TURrekNEWXdXaGNOTXpRdwpNakkyTUJUME1ERXdXakFXTVJRd0VnWURWUVFEREF0bWIyOHVZbUZ5TG1OdmJUQ0NBU0l3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFKbEk2WXhFOVprQ1BzNnBDUXhickNtZWl4OVA1RGZ4OVJ1NUxENFQKSm1kVzdJS2R0UVYvd2ZMbXRzdTc2QithVGRDaldlMEJUZmVPT1JCYlIzY1BBRzZFbFFMaWNsUVVydW4zcStncwpKcEsrSTdjSStqNXc4STY4WEg1V1E3clZVdGJ3SHBxYncrY1ZuQnFJVU9MaUlhdGpJZjdLWDUxTTF1RjljZkVICkU0RG5jSDZyYnI1OS9SRlpCc2toeHM1T3p3Sklmb2hreXZGd2V1VHd4Sy9WcGpJKzdPYzQ4QUJDWHBOTzlEL3EKRWgrck9hdWpBTWNYZ0hRSVRrQ2lpVVRjVW82TFNIOXZMWlB0YXFmem9acTZuaE1xcFc2NUUxcEF3RjNqeVRUeAphNUk4SmNmU0Zqa2llWjIwTFVRTW43TThVNHhIamFvL2d2SDBDQWZkQjdSTFUyc0NBd0VBQWFOTE1GRXdIUVlEClZSME9CQllFRk9SQ0U4dS8xRERXN2loWnA3Y3g5dFNtUG02T01COEdBMVVkSXdRWU1CYUFGT1JDRTh1LzFERFcKN2loWnA3Y3g5dFNtUG02T01BOEdBMVVkRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRnQ1M3pqc3FUYUg1YThFMmNodm1XQWdDcnhSSzhiVkxNeGl3TkdqYm1FUFJ6K3c2TngrazBBOEtFY0lEc0tjClNYY2k1OHU0b1didFZKQmx6YS9adWpIUjZQMUJuT3BsK2FveTc4NGJiZDRQMzl3VExvWGZNZmJCQ20xdmV2aDkKQUpLbncyWnRxcjRta2JMY3hFcWxxM3NCTEZBUzlzUUxuS05DZTJjR0xkVHAyYm9HK3FjZ3lRZ0NJTTZmOEVNdgpXUGlmQ01NR3V6Sy9HUkY0YlBPL1lGNDhld0R1M1VlaWgwWFhkVUFPRTlDdFVhOE5JaGMxVVBhT3pQcnRZVnFyClpPR2t2L0t1K0I3OGg4U0VzTzlYclFjdXdiT25KeDZLdFIrYWV5a3ZBcFhDUTNmWkMvYllLQUFSK1A4QUpvUVoKYndJVW1YaTRnajVtK2JLUGhlK2lyK0U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
+ tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ1pTT21NUlBXWkFqN08KcVFrTVc2d3Bub3NmVCtRMzhmVWJ1U3crRXlablZ1eUNuYlVGZjhIeTVyYkx1K2dObWszUW8xbnRBVTMzamprcwpXMGQzRHdCdWhKVUM0bkpVRks3cDk2dm9MQ2FTdmlPM0NQbytjUENPdkZ4K1ZrTzYxVkxXOEI2YW04UG5GWndhCmlGRGk0aUdyWXlIK3lsK2RUTmJoZlhIeEJ4T0E1M0IrcTI2K2ZmMFJXUWJKSWNiT1RzOENTSDZJWk1yeGNIcmsKOE1TdjFhWXlQdXpuT1BBQVFsNlRUdlEvNmhJZnF6bXJvd0RIRjRCMENFNUFvb2xFM0ZLT2kwaC9ieTJUN1dxbgo4NkdhdXA0VEtxVnV1Uk5hUU1CZDQ4azA4V3VTUENYSDBoWTVJbm1kdEMxRURKK3pQRk9NUjQycVA0THg5QWdICjNRZTBTMU5yQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+`
+ grpcRouteYAML = `---
+apiVersion: gateway.networking.k8s.io/v1
+kind: GRPCRoute
+metadata:
+ name: backend
+ namespace: default
+spec:
+ parentRefs:
+ - name: eg
+ sectionName: grpc
+ hostnames:
+ - "www.grpc-example.com"
+ rules:
+ - matches:
+ - method:
+ service: com.example.Things
+ method: DoThing
+ headers:
+ - name: com.example.Header
+ value: foobar
+ backendRefs:
+ - name: provided-backend
+ port: 9000
+`
+ httpRouteYAML = `---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: backend
+ namespace: default
+spec:
+ parentRefs:
+ - name: eg
+ hostnames:
+ - "www.example.com"
+ rules:
+ - backendRefs:
+ - name: provided-backend
+ port: 8000
+`
+ udpRouteYAML = `---
+apiVersion: gateway.networking.k8s.io/v1alpha2
+kind: UDPRoute
+metadata:
+ name: backend
+ namespace: default
+spec:
+ parentRefs:
+ - name: eg
+ sectionName: udp
+ rules:
+ - backendRefs:
+ - name: provided-backend
+ port: 3000
+`
+ securityPolicyYAML = `---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: SecurityPolicy
+metadata:
+ name: security-policy
+ namespace: default
+spec:
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
+ cors:
+ allowOrigins:
+ - "https://www.example.com"
+ allowMethods:
+ - GET
+ - POST
+ allowHeaders:
+ - "Content-Type"
+`
+ backendTrafficPolicyYAML = `---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: BackendTrafficPolicy
+metadata:
+ name: backend-traffic-policy
+ namespace: default
+spec:
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend
+ circuitBreaker:
+ maxConnections: 100
+ maxPendingRequests: 50
+ loadBalancer:
+ type: RoundRobin
+`
+ clientTrafficPolicyYAML = `---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: ClientTrafficPolicy
+metadata:
+ name: client-traffic-policy
+ namespace: default
+spec:
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: Gateway
+ name: eg
+ timeout:
+ http:
+ requestReceivedTimeout: 30s
+`
+)
+
+// Helpers for benchmark policy generation.
+func genSecurityPolicies(n int) string {
+ var sb strings.Builder
+ for i := 0; i < n; i++ {
+ sb.WriteString(fmt.Sprintf(`---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: SecurityPolicy
+metadata:
+ name: security-policy-%d
+ namespace: default
+spec:
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend-%d
+ cors:
+ allowOrigins:
+ - "https://www.example-%d.com"
+ allowMethods:
+ - GET
+ - POST
+ allowHeaders:
+ - "Content-Type"
+`, i, i, i))
+ }
+ return sb.String()
+}
+
+func genBackendTrafficPolicies(n int) string {
+ var sb strings.Builder
+ for i := 0; i < n; i++ {
+ sb.WriteString(fmt.Sprintf(`---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: BackendTrafficPolicy
+metadata:
+ name: backend-traffic-policy-%d
+ namespace: default
+spec:
+ targetRefs:
+ - group: gateway.networking.k8s.io
+ kind: HTTPRoute
+ name: backend-%d
+ circuitBreaker:
+ maxConnections: %d
+ maxPendingRequests: %d
+ loadBalancer:
+ type: RoundRobin
+`, i, i, 100+i*10, 50+i*5))
+ }
+ return sb.String()
+}
+
+// Helpers for benchmark route generation.
+func genHTTPRoutes(n int) string {
+ var sb strings.Builder
+ for i := 0; i < n; i++ {
+ sb.WriteString(fmt.Sprintf(`---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+ name: backend-%d
+ namespace: default
+spec:
+ parentRefs:
+ - name: eg
+ hostnames:
+ - "www.example-%d.com"
+ rules:
+ - backendRefs:
+ - name: provided-backend
+ port: 8000
+`, i, i))
+ }
+ return sb.String()
+}
+
+func genGRPCRoutes(n int) string {
+ var sb strings.Builder
+ for i := 0; i < n; i++ {
+ sb.WriteString(fmt.Sprintf(`---
+apiVersion: gateway.networking.k8s.io/v1
+kind: GRPCRoute
+metadata:
+ name: backend-grpc-%d
+ namespace: default
+spec:
+ parentRefs:
+ - name: eg
+ sectionName: grpc
+ hostnames:
+ - "www.grpc-%d.example.com"
+ rules:
+ - matches:
+ - method:
+ service: com.example.Service%d
+ method: Call
+ backendRefs:
+ - name: provided-backend
+ port: 9000
+`, i, i, i))
+ }
+ return sb.String()
+}
+
+func genUDPRoutes(n int) string {
+ var sb strings.Builder
+ for i := 0; i < n; i++ {
+ sb.WriteString(fmt.Sprintf(`---
+apiVersion: gateway.networking.k8s.io/v1alpha2
+kind: UDPRoute
+metadata:
+ name: backend-udp-%d
+ namespace: default
+spec:
+ parentRefs:
+ - name: eg
+ sectionName: udp
+ rules:
+ - backendRefs:
+ - name: provided-backend
+ port: %d
+`, i, 3000+i))
+ }
+ return sb.String()
+}
+
+// Benchmark cases: small / medium / large.
+func BenchmarkGatewayAPItoXDS(b *testing.B) {
+ type benchCase struct {
+ name string
+ yaml string
+ }
+ medium := baseYAML + backendYAML + tlsSecretYAML + clientTrafficPolicyYAML +
+ genHTTPRoutes(100) +
+ genGRPCRoutes(50) +
+ genUDPRoutes(20) +
+ genSecurityPolicies(100) +
+ genBackendTrafficPolicies(100)
+ large := baseYAML + backendYAML + tlsSecretYAML + clientTrafficPolicyYAML +
+ genHTTPRoutes(1000) +
+ genGRPCRoutes(500) +
+ genUDPRoutes(100) +
+ genSecurityPolicies(1000) +
+ genBackendTrafficPolicies(1000)
+
+ cases := []benchCase{
+ {
+ name: "small",
+ yaml: baseYAML + httpRouteYAML + backendYAML + tlsSecretYAML + securityPolicyYAML + backendTrafficPolicyYAML + clientTrafficPolicyYAML,
+ },
+ {
+ name: "medium",
+ yaml: medium,
+ },
+ {
+ name: "large",
+ yaml: large,
+ },
+ }
+
+ for _, tc := range cases {
+ b.Run(tc.name, func(b *testing.B) {
+ rs, err := resource.LoadResourcesFromYAMLBytes([]byte(tc.yaml), true)
+ if err != nil {
+ b.Fatalf("load: %v", err)
+ }
+ b.ReportAllocs()
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ _, err = egctl.TranslateGatewayAPIToXds("default", "cluster.local", "all", rs)
+ if err != nil && strings.Contains(err.Error(), "failed to translate xds") {
+ b.Fatalf("%v", err)
+ }
+ }
+ })
+ }
+}
diff --git a/test/helm/gateway-crds-helm/all.out.yaml b/test/helm/gateway-crds-helm/all.out.yaml
index 3bc2a49e17..b0f287a1f7 100644
--- a/test/helm/gateway-crds-helm/all.out.yaml
+++ b/test/helm/gateway-crds-helm/all.out.yaml
@@ -17820,6 +17820,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -17878,6 +17879,7 @@ spec:
properties:
fixedDelay:
description: FixedDelay specifies the fixed delay duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
percentage:
default: 100
@@ -17961,8 +17963,7 @@ spec:
Defaults to 200 only
items:
description: HTTPStatus defines the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -17992,14 +17993,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between active health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -18073,7 +18073,7 @@ spec:
default: 1s
description: Timeout defines the time to wait for a health
check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -18124,7 +18124,7 @@ spec:
default: 30s
description: BaseEjectionTime defines the base duration for
which a host will be ejected on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -18149,7 +18149,7 @@ spec:
default: 3s
description: Interval defines the time between passive health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -18268,6 +18268,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -18351,6 +18352,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -18671,12 +18673,14 @@ spec:
unit:
description: |-
RateLimitUnit specifies the intervals for setting rate limits.
- Valid RateLimitUnit values are "Second", "Minute", "Hour", and "Day".
+ Valid RateLimitUnit values are "Second", "Minute", "Hour", "Day", "Month" and "Year".
enum:
- Second
- Minute
- Hour
- Day
+ - Month
+ - Year
type: string
required:
- requests
@@ -18920,12 +18924,14 @@ spec:
unit:
description: |-
RateLimitUnit specifies the intervals for setting rate limits.
- Valid RateLimitUnit values are "Second", "Minute", "Hour", and "Day".
+ Valid RateLimitUnit values are "Second", "Minute", "Hour", "Day", "Month" and "Year".
enum:
- Second
- Minute
- Hour
- Day
+ - Month
+ - Year
type: string
required:
- requests
@@ -19286,18 +19292,18 @@ spec:
baseInterval:
description: BaseInterval is the base interval between
retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -19312,8 +19318,7 @@ spec:
The retriable-status-codes trigger must also be configured for these status codes to trigger a retry.
items:
description: HTTPStatus defines the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -20242,7 +20247,7 @@ spec:
- name
- value
type: object
- maxItems: 16
+ maxItems: 64
type: array
x-kubernetes-list-map-keys:
- name
@@ -20268,7 +20273,7 @@ spec:
my-header2: bar
items:
type: string
- maxItems: 16
+ maxItems: 64
type: array
x-kubernetes-list-type: set
set:
@@ -20316,7 +20321,7 @@ spec:
- name
- value
type: object
- maxItems: 16
+ maxItems: 64
type: array
x-kubernetes-list-map-keys:
- name
@@ -21764,6 +21769,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -21856,8 +21862,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -21887,14 +21892,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between active
health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -21973,7 +21977,7 @@ spec:
default: 1s
description: Timeout defines the time to wait for
a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -22026,7 +22030,7 @@ spec:
description: BaseEjectionTime defines the base duration
for which a host will be ejected on consecutive
failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -22051,7 +22055,7 @@ spec:
default: 3s
description: Interval defines the time between passive
health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -22141,6 +22145,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -22227,6 +22232,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -22339,18 +22345,18 @@ spec:
baseInterval:
description: BaseInterval is the base interval
between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -22366,8 +22372,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -24538,7 +24543,7 @@ spec:
x-kubernetes-validations:
- message: Image must include a tag and allowed characters
only (e.g., 'repo:tag').
- rule: self.matches('^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$')
+ rule: self.matches('^[a-zA-Z0-9._-]+(:[0-9]+)?(/[a-zA-Z0-9._/-]+)?(:[a-zA-Z0-9._-]+)?(@sha256:[a-z0-9]+)?$')
imageRepository:
description: |-
ImageRepository specifies the container image repository to be used without specifying a tag.
@@ -24547,8 +24552,8 @@ spec:
type: string
x-kubernetes-validations:
- message: ImageRepository must contain only allowed
- characters and must not include a tag or any colons.
- rule: self.matches('^[a-zA-Z0-9._/-]+$')
+ characters and must not include a tag.
+ rule: self.matches('^[a-zA-Z0-9._-]+(:[0-9]+)?[a-zA-Z0-9._/-]+$')
resources:
description: |-
Resources required by this container.
@@ -28383,7 +28388,7 @@ spec:
x-kubernetes-validations:
- message: Image must include a tag and allowed characters
only (e.g., 'repo:tag').
- rule: self.matches('^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$')
+ rule: self.matches('^[a-zA-Z0-9._-]+(:[0-9]+)?(/[a-zA-Z0-9._/-]+)?(:[a-zA-Z0-9._-]+)?(@sha256:[a-z0-9]+)?$')
imageRepository:
description: |-
ImageRepository specifies the container image repository to be used without specifying a tag.
@@ -28392,8 +28397,8 @@ spec:
type: string
x-kubernetes-validations:
- message: ImageRepository must contain only allowed
- characters and must not include a tag or any colons.
- rule: self.matches('^[a-zA-Z0-9._/-]+$')
+ characters and must not include a tag.
+ rule: self.matches('^[a-zA-Z0-9._-]+(:[0-9]+)?[a-zA-Z0-9._/-]+$')
resources:
description: |-
Resources required by this container.
@@ -34440,11 +34445,13 @@ spec:
description: |-
DrainTimeout defines the graceful drain timeout. This should be less than the pod's terminationGracePeriodSeconds.
If unspecified, defaults to 60 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
minDrainDuration:
description: |-
MinDrainDuration defines the minimum drain duration allowing time for endpoint deprogramming to complete.
If unspecified, defaults to 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
telemetry:
@@ -34798,6 +34805,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -34898,8 +34906,7 @@ spec:
description: HTTPStatus
defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -34931,7 +34938,6 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
@@ -34939,7 +34945,7 @@ spec:
description: Interval defines
the time between active health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -35028,7 +35034,7 @@ spec:
description: Timeout defines the
time to wait for a health check
response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -35091,7 +35097,7 @@ spec:
defines the base duration for
which a host will be ejected
on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -35119,7 +35125,7 @@ spec:
description: Interval defines
the time between passive health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -35214,6 +35220,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -35308,6 +35315,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -35429,19 +35437,19 @@ spec:
description: BaseInterval
is the base interval between
retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout
per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -35457,8 +35465,7 @@ spec:
items:
description: HTTPStatus defines
the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -35909,6 +35916,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -36009,8 +36017,7 @@ spec:
description: HTTPStatus
defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -36042,7 +36049,6 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
@@ -36050,7 +36056,7 @@ spec:
description: Interval defines
the time between active health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -36139,7 +36145,7 @@ spec:
description: Timeout defines the
time to wait for a health check
response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -36202,7 +36208,7 @@ spec:
defines the base duration for
which a host will be ejected
on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -36230,7 +36236,7 @@ spec:
description: Interval defines
the time between passive health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -36325,6 +36331,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -36419,6 +36426,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -36540,19 +36548,19 @@ spec:
description: BaseInterval
is the base interval between
retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout
per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -36568,8 +36576,7 @@ spec:
items:
description: HTTPStatus defines
the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -37128,6 +37135,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -37224,8 +37232,7 @@ spec:
items:
description: HTTPStatus defines
the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -37256,14 +37263,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time
between active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -37347,7 +37353,7 @@ spec:
default: 1s
description: Timeout defines the time
to wait for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -37405,7 +37411,7 @@ spec:
description: BaseEjectionTime defines
the base duration for which a host
will be ejected on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -37432,7 +37438,7 @@ spec:
default: 3s
description: Interval defines the time
between passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -37524,6 +37530,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -37614,6 +37621,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -37730,19 +37738,19 @@ spec:
baseInterval:
description: BaseInterval is the
base interval between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout
per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -37758,8 +37766,7 @@ spec:
items:
description: HTTPStatus defines the
http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -38244,6 +38251,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -38339,8 +38347,7 @@ spec:
items:
description: HTTPStatus defines the
http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -38371,14 +38378,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -38462,7 +38468,7 @@ spec:
default: 1s
description: Timeout defines the time to wait
for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -38519,7 +38525,7 @@ spec:
description: BaseEjectionTime defines the
base duration for which a host will be ejected
on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -38546,7 +38552,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -38638,6 +38644,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -38727,6 +38734,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -38841,19 +38849,19 @@ spec:
baseInterval:
description: BaseInterval is the base
interval between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry
attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -38869,8 +38877,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -39898,6 +39905,7 @@ spec:
description: |-
MaxAge defines how long the results of a preflight request can be cached.
It specifies the value in the Access-Control-Max-Age CORS response header..
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
extAuth:
@@ -40204,6 +40212,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -40296,8 +40305,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -40327,14 +40335,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -40413,7 +40420,7 @@ spec:
default: 1s
description: Timeout defines the time to wait
for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -40468,7 +40475,7 @@ spec:
description: BaseEjectionTime defines the base
duration for which a host will be ejected on
consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -40494,7 +40501,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -40586,6 +40593,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -40673,6 +40681,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -40787,19 +40796,19 @@ spec:
baseInterval:
description: BaseInterval is the base interval
between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry
attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -40815,8 +40824,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -41211,6 +41219,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -41303,8 +41312,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -41334,14 +41342,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -41420,7 +41427,7 @@ spec:
default: 1s
description: Timeout defines the time to wait
for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -41475,7 +41482,7 @@ spec:
description: BaseEjectionTime defines the base
duration for which a host will be ejected on
consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -41501,7 +41508,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -41593,6 +41600,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -41680,6 +41688,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -41794,19 +41803,19 @@ spec:
baseInterval:
description: BaseInterval is the base interval
between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry
attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -41822,8 +41831,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -42410,6 +42418,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -42505,8 +42514,7 @@ spec:
items:
description: HTTPStatus defines the
http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -42537,14 +42545,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -42628,7 +42635,7 @@ spec:
default: 1s
description: Timeout defines the time to
wait for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -42686,7 +42693,7 @@ spec:
description: BaseEjectionTime defines the
base duration for which a host will be
ejected on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -42713,7 +42720,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -42805,6 +42812,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -42894,6 +42902,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -43009,19 +43018,19 @@ spec:
baseInterval:
description: BaseInterval is the base
interval between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per
retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -43037,8 +43046,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -43278,7 +43286,6 @@ spec:
By default, its unset.
properties:
sameSite:
- default: Strict
enum:
- Lax
- Strict
@@ -43320,6 +43327,7 @@ spec:
If not specified, defaults to 604800s (one week).
Note: this field is only applicable when the "refreshToken" field is set to true.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
defaultTokenTTL:
description: |-
@@ -43331,6 +43339,7 @@ spec:
If not specified, defaults to 0. In this case, the "expires_in" field in
the authorization response must be set by the authorization server, or the
OAuth flow will fail.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
denyRedirect:
description: |-
@@ -43673,6 +43682,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -43765,8 +43775,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -43796,14 +43805,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -43882,7 +43890,7 @@ spec:
default: 1s
description: Timeout defines the time to wait
for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -43937,7 +43945,7 @@ spec:
description: BaseEjectionTime defines the base
duration for which a host will be ejected on
consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -43963,7 +43971,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -44055,6 +44063,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -44142,6 +44151,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -44256,19 +44266,19 @@ spec:
baseInterval:
description: BaseInterval is the base interval
between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry
attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -44284,8 +44294,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
diff --git a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml
index 4ab5cb551c..494471658b 100644
--- a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml
+++ b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml
@@ -508,6 +508,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -566,6 +567,7 @@ spec:
properties:
fixedDelay:
description: FixedDelay specifies the fixed delay duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
percentage:
default: 100
@@ -649,8 +651,7 @@ spec:
Defaults to 200 only
items:
description: HTTPStatus defines the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -680,14 +681,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between active health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -761,7 +761,7 @@ spec:
default: 1s
description: Timeout defines the time to wait for a health
check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -812,7 +812,7 @@ spec:
default: 30s
description: BaseEjectionTime defines the base duration for
which a host will be ejected on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -837,7 +837,7 @@ spec:
default: 3s
description: Interval defines the time between passive health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -956,6 +956,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -1039,6 +1040,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -1359,12 +1361,14 @@ spec:
unit:
description: |-
RateLimitUnit specifies the intervals for setting rate limits.
- Valid RateLimitUnit values are "Second", "Minute", "Hour", and "Day".
+ Valid RateLimitUnit values are "Second", "Minute", "Hour", "Day", "Month" and "Year".
enum:
- Second
- Minute
- Hour
- Day
+ - Month
+ - Year
type: string
required:
- requests
@@ -1608,12 +1612,14 @@ spec:
unit:
description: |-
RateLimitUnit specifies the intervals for setting rate limits.
- Valid RateLimitUnit values are "Second", "Minute", "Hour", and "Day".
+ Valid RateLimitUnit values are "Second", "Minute", "Hour", "Day", "Month" and "Year".
enum:
- Second
- Minute
- Hour
- Day
+ - Month
+ - Year
type: string
required:
- requests
@@ -1974,18 +1980,18 @@ spec:
baseInterval:
description: BaseInterval is the base interval between
retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -2000,8 +2006,7 @@ spec:
The retriable-status-codes trigger must also be configured for these status codes to trigger a retry.
items:
description: HTTPStatus defines the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -2930,7 +2935,7 @@ spec:
- name
- value
type: object
- maxItems: 16
+ maxItems: 64
type: array
x-kubernetes-list-map-keys:
- name
@@ -2956,7 +2961,7 @@ spec:
my-header2: bar
items:
type: string
- maxItems: 16
+ maxItems: 64
type: array
x-kubernetes-list-type: set
set:
@@ -3004,7 +3009,7 @@ spec:
- name
- value
type: object
- maxItems: 16
+ maxItems: 64
type: array
x-kubernetes-list-map-keys:
- name
@@ -4452,6 +4457,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -4544,8 +4550,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -4575,14 +4580,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between active
health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -4661,7 +4665,7 @@ spec:
default: 1s
description: Timeout defines the time to wait for
a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -4714,7 +4718,7 @@ spec:
description: BaseEjectionTime defines the base duration
for which a host will be ejected on consecutive
failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -4739,7 +4743,7 @@ spec:
default: 3s
description: Interval defines the time between passive
health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -4829,6 +4833,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -4915,6 +4920,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -5027,18 +5033,18 @@ spec:
baseInterval:
description: BaseInterval is the base interval
between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -5054,8 +5060,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -7226,7 +7231,7 @@ spec:
x-kubernetes-validations:
- message: Image must include a tag and allowed characters
only (e.g., 'repo:tag').
- rule: self.matches('^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$')
+ rule: self.matches('^[a-zA-Z0-9._-]+(:[0-9]+)?(/[a-zA-Z0-9._/-]+)?(:[a-zA-Z0-9._-]+)?(@sha256:[a-z0-9]+)?$')
imageRepository:
description: |-
ImageRepository specifies the container image repository to be used without specifying a tag.
@@ -7235,8 +7240,8 @@ spec:
type: string
x-kubernetes-validations:
- message: ImageRepository must contain only allowed
- characters and must not include a tag or any colons.
- rule: self.matches('^[a-zA-Z0-9._/-]+$')
+ characters and must not include a tag.
+ rule: self.matches('^[a-zA-Z0-9._-]+(:[0-9]+)?[a-zA-Z0-9._/-]+$')
resources:
description: |-
Resources required by this container.
@@ -11071,7 +11076,7 @@ spec:
x-kubernetes-validations:
- message: Image must include a tag and allowed characters
only (e.g., 'repo:tag').
- rule: self.matches('^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$')
+ rule: self.matches('^[a-zA-Z0-9._-]+(:[0-9]+)?(/[a-zA-Z0-9._/-]+)?(:[a-zA-Z0-9._-]+)?(@sha256:[a-z0-9]+)?$')
imageRepository:
description: |-
ImageRepository specifies the container image repository to be used without specifying a tag.
@@ -11080,8 +11085,8 @@ spec:
type: string
x-kubernetes-validations:
- message: ImageRepository must contain only allowed
- characters and must not include a tag or any colons.
- rule: self.matches('^[a-zA-Z0-9._/-]+$')
+ characters and must not include a tag.
+ rule: self.matches('^[a-zA-Z0-9._-]+(:[0-9]+)?[a-zA-Z0-9._/-]+$')
resources:
description: |-
Resources required by this container.
@@ -17128,11 +17133,13 @@ spec:
description: |-
DrainTimeout defines the graceful drain timeout. This should be less than the pod's terminationGracePeriodSeconds.
If unspecified, defaults to 60 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
minDrainDuration:
description: |-
MinDrainDuration defines the minimum drain duration allowing time for endpoint deprogramming to complete.
If unspecified, defaults to 10 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
telemetry:
@@ -17486,6 +17493,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -17586,8 +17594,7 @@ spec:
description: HTTPStatus
defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -17619,7 +17626,6 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
@@ -17627,7 +17633,7 @@ spec:
description: Interval defines
the time between active health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -17716,7 +17722,7 @@ spec:
description: Timeout defines the
time to wait for a health check
response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -17779,7 +17785,7 @@ spec:
defines the base duration for
which a host will be ejected
on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -17807,7 +17813,7 @@ spec:
description: Interval defines
the time between passive health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -17902,6 +17908,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -17996,6 +18003,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -18117,19 +18125,19 @@ spec:
description: BaseInterval
is the base interval between
retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout
per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -18145,8 +18153,7 @@ spec:
items:
description: HTTPStatus defines
the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -18597,6 +18604,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -18697,8 +18705,7 @@ spec:
description: HTTPStatus
defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -18730,7 +18737,6 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
@@ -18738,7 +18744,7 @@ spec:
description: Interval defines
the time between active health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -18827,7 +18833,7 @@ spec:
description: Timeout defines the
time to wait for a health check
response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -18890,7 +18896,7 @@ spec:
defines the base duration for
which a host will be ejected
on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -18918,7 +18924,7 @@ spec:
description: Interval defines
the time between passive health
checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -19013,6 +19019,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -19107,6 +19114,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -19228,19 +19236,19 @@ spec:
description: BaseInterval
is the base interval between
retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout
per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -19256,8 +19264,7 @@ spec:
items:
description: HTTPStatus defines
the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -19816,6 +19823,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -19912,8 +19920,7 @@ spec:
items:
description: HTTPStatus defines
the http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -19944,14 +19951,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time
between active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -20035,7 +20041,7 @@ spec:
default: 1s
description: Timeout defines the time
to wait for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -20093,7 +20099,7 @@ spec:
description: BaseEjectionTime defines
the base duration for which a host
will be ejected on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -20120,7 +20126,7 @@ spec:
default: 3s
description: Interval defines the time
between passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -20212,6 +20218,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -20302,6 +20309,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -20418,19 +20426,19 @@ spec:
baseInterval:
description: BaseInterval is the
base interval between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout
per retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -20446,8 +20454,7 @@ spec:
items:
description: HTTPStatus defines the
http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -20932,6 +20939,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -21027,8 +21035,7 @@ spec:
items:
description: HTTPStatus defines the
http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -21059,14 +21066,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -21150,7 +21156,7 @@ spec:
default: 1s
description: Timeout defines the time to wait
for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -21207,7 +21213,7 @@ spec:
description: BaseEjectionTime defines the
base duration for which a host will be ejected
on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -21234,7 +21240,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -21326,6 +21332,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -21415,6 +21422,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -21529,19 +21537,19 @@ spec:
baseInterval:
description: BaseInterval is the base
interval between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry
attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -21557,8 +21565,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -22586,6 +22593,7 @@ spec:
description: |-
MaxAge defines how long the results of a preflight request can be cached.
It specifies the value in the Access-Control-Max-Age CORS response header..
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
extAuth:
@@ -22892,6 +22900,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -22984,8 +22993,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -23015,14 +23023,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -23101,7 +23108,7 @@ spec:
default: 1s
description: Timeout defines the time to wait
for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -23156,7 +23163,7 @@ spec:
description: BaseEjectionTime defines the base
duration for which a host will be ejected on
consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -23182,7 +23189,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -23274,6 +23281,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -23361,6 +23369,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -23475,19 +23484,19 @@ spec:
baseInterval:
description: BaseInterval is the base interval
between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry
attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -23503,8 +23512,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -23899,6 +23907,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -23991,8 +24000,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -24022,14 +24030,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -24108,7 +24115,7 @@ spec:
default: 1s
description: Timeout defines the time to wait
for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -24163,7 +24170,7 @@ spec:
description: BaseEjectionTime defines the base
duration for which a host will be ejected on
consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -24189,7 +24196,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -24281,6 +24288,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -24368,6 +24376,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -24482,19 +24491,19 @@ spec:
baseInterval:
description: BaseInterval is the base interval
between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry
attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -24510,8 +24519,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -25098,6 +25106,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -25193,8 +25202,7 @@ spec:
items:
description: HTTPStatus defines the
http status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -25225,14 +25233,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -25316,7 +25323,7 @@ spec:
default: 1s
description: Timeout defines the time to
wait for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -25374,7 +25381,7 @@ spec:
description: BaseEjectionTime defines the
base duration for which a host will be
ejected on consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -25401,7 +25408,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -25493,6 +25500,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -25582,6 +25590,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -25697,19 +25706,19 @@ spec:
baseInterval:
description: BaseInterval is the base
interval between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per
retry attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -25725,8 +25734,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -25966,7 +25974,6 @@ spec:
By default, its unset.
properties:
sameSite:
- default: Strict
enum:
- Lax
- Strict
@@ -26008,6 +26015,7 @@ spec:
If not specified, defaults to 604800s (one week).
Note: this field is only applicable when the "refreshToken" field is set to true.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
defaultTokenTTL:
description: |-
@@ -26019,6 +26027,7 @@ spec:
If not specified, defaults to 0. In this case, the "expires_in" field in
the authorization response must be set by the authorization server, or the
OAuth flow will fail.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
denyRedirect:
description: |-
@@ -26361,6 +26370,7 @@ spec:
description: |-
DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
lookupFamily:
description: |-
@@ -26453,8 +26463,7 @@ spec:
items:
description: HTTPStatus defines the http
status code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
@@ -26484,14 +26493,13 @@ spec:
description: |-
InitialJitter defines the maximum time Envoy will wait before the first health check.
Envoy will randomly select a value between 0 and the initial jitter value.
- format: duration
pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
interval:
default: 3s
description: Interval defines the time between
active health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
tcp:
description: |-
@@ -26570,7 +26578,7 @@ spec:
default: 1s
description: Timeout defines the time to wait
for a health check response.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type:
allOf:
@@ -26625,7 +26633,7 @@ spec:
description: BaseEjectionTime defines the base
duration for which a host will be ejected on
consecutive failures.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
consecutive5XxErrors:
default: 5
@@ -26651,7 +26659,7 @@ spec:
default: 3s
description: Interval defines the time between
passive health checks.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxEjectionPercent:
default: 10
@@ -26743,6 +26751,7 @@ spec:
description: |-
TTL of the generated cookie if the cookie is not present. This value sets the
Max-Age attribute value.
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- name
@@ -26830,6 +26839,7 @@ spec:
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
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
required:
- window
@@ -26944,19 +26954,19 @@ spec:
baseInterval:
description: BaseInterval is the base interval
between retries.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
maxInterval:
description: |-
MaxInterval is the maximum interval between retries. This parameter is optional, but must be greater than or equal to the base_interval if set.
The default is 10 times the base_interval
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
timeout:
description: Timeout is the timeout per retry
attempt.
- format: duration
+ pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$
type: string
type: object
retryOn:
@@ -26972,8 +26982,7 @@ spec:
items:
description: HTTPStatus defines the http status
code.
- exclusiveMaximum: true
- maximum: 600
+ maximum: 599
minimum: 100
type: integer
type: array
diff --git a/test/helm/gateway-helm/certgen-annotations.out.yaml b/test/helm/gateway-helm/certgen-annotations.out.yaml
index ee7cd1a071..e3fbaec4f9 100644
--- a/test/helm/gateway-helm/certgen-annotations.out.yaml
+++ b/test/helm/gateway-helm/certgen-annotations.out.yaml
@@ -38,7 +38,7 @@ data:
kubernetes:
rateLimitDeployment:
container:
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
patch:
type: StrategicMerge
value:
diff --git a/test/helm/gateway-helm/certgen-args.out.yaml b/test/helm/gateway-helm/certgen-args.out.yaml
index 6b35f8cfa7..308dc0b80d 100644
--- a/test/helm/gateway-helm/certgen-args.out.yaml
+++ b/test/helm/gateway-helm/certgen-args.out.yaml
@@ -38,7 +38,7 @@ data:
kubernetes:
rateLimitDeployment:
container:
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
patch:
type: StrategicMerge
value:
diff --git a/test/helm/gateway-helm/certgen-labels.out.yaml b/test/helm/gateway-helm/certgen-labels.out.yaml
index 69c0168c25..c214e14e0d 100644
--- a/test/helm/gateway-helm/certgen-labels.out.yaml
+++ b/test/helm/gateway-helm/certgen-labels.out.yaml
@@ -38,7 +38,7 @@ data:
kubernetes:
rateLimitDeployment:
container:
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
patch:
type: StrategicMerge
value:
diff --git a/test/helm/gateway-helm/certjen-custom-scheduling.out.yaml b/test/helm/gateway-helm/certjen-custom-scheduling.out.yaml
index 90ee8b7b23..2121c0f9e1 100644
--- a/test/helm/gateway-helm/certjen-custom-scheduling.out.yaml
+++ b/test/helm/gateway-helm/certjen-custom-scheduling.out.yaml
@@ -38,7 +38,7 @@ data:
kubernetes:
rateLimitDeployment:
container:
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
patch:
type: StrategicMerge
value:
diff --git a/test/helm/gateway-helm/control-plane-with-pdb.out.yaml b/test/helm/gateway-helm/control-plane-with-pdb.out.yaml
index cc0d712ae8..3864a0b09b 100644
--- a/test/helm/gateway-helm/control-plane-with-pdb.out.yaml
+++ b/test/helm/gateway-helm/control-plane-with-pdb.out.yaml
@@ -53,7 +53,7 @@ data:
kubernetes:
rateLimitDeployment:
container:
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
patch:
type: StrategicMerge
value:
diff --git a/test/helm/gateway-helm/default-config.out.yaml b/test/helm/gateway-helm/default-config.out.yaml
index ac352d6c9c..079f46ebdb 100644
--- a/test/helm/gateway-helm/default-config.out.yaml
+++ b/test/helm/gateway-helm/default-config.out.yaml
@@ -38,7 +38,7 @@ data:
kubernetes:
rateLimitDeployment:
container:
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
patch:
type: StrategicMerge
value:
diff --git a/test/helm/gateway-helm/deployment-annotations.out.yaml b/test/helm/gateway-helm/deployment-annotations.out.yaml
index 69f27e3802..92134053c6 100644
--- a/test/helm/gateway-helm/deployment-annotations.out.yaml
+++ b/test/helm/gateway-helm/deployment-annotations.out.yaml
@@ -38,7 +38,7 @@ data:
kubernetes:
rateLimitDeployment:
container:
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
patch:
type: StrategicMerge
value:
diff --git a/test/helm/gateway-helm/deployment-custom-topology.out.yaml b/test/helm/gateway-helm/deployment-custom-topology.out.yaml
index 520f03e92c..aad6382f77 100644
--- a/test/helm/gateway-helm/deployment-custom-topology.out.yaml
+++ b/test/helm/gateway-helm/deployment-custom-topology.out.yaml
@@ -38,7 +38,7 @@ data:
kubernetes:
rateLimitDeployment:
container:
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
patch:
type: StrategicMerge
value:
diff --git a/test/helm/gateway-helm/deployment-images-config.out.yaml b/test/helm/gateway-helm/deployment-images-config.out.yaml
index 53f21ea3cd..30207a3f29 100644
--- a/test/helm/gateway-helm/deployment-images-config.out.yaml
+++ b/test/helm/gateway-helm/deployment-images-config.out.yaml
@@ -38,7 +38,7 @@ data:
kubernetes:
rateLimitDeployment:
container:
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
patch:
type: StrategicMerge
value:
diff --git a/test/helm/gateway-helm/deployment-priorityclass.out.yaml b/test/helm/gateway-helm/deployment-priorityclass.out.yaml
index 3e81feb1e9..6cd127f267 100644
--- a/test/helm/gateway-helm/deployment-priorityclass.out.yaml
+++ b/test/helm/gateway-helm/deployment-priorityclass.out.yaml
@@ -38,7 +38,7 @@ data:
kubernetes:
rateLimitDeployment:
container:
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
patch:
type: StrategicMerge
value:
diff --git a/test/helm/gateway-helm/deployment-repo-no-registry.out.yaml b/test/helm/gateway-helm/deployment-repo-no-registry.out.yaml
index f040f1df0b..abf76f65ca 100644
--- a/test/helm/gateway-helm/deployment-repo-no-registry.out.yaml
+++ b/test/helm/gateway-helm/deployment-repo-no-registry.out.yaml
@@ -38,7 +38,7 @@ data:
kubernetes:
rateLimitDeployment:
container:
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
patch:
type: StrategicMerge
value:
diff --git a/test/helm/gateway-helm/deployment-securitycontext.out.yaml b/test/helm/gateway-helm/deployment-securitycontext.out.yaml
index c473f44d45..c568ac3d68 100644
--- a/test/helm/gateway-helm/deployment-securitycontext.out.yaml
+++ b/test/helm/gateway-helm/deployment-securitycontext.out.yaml
@@ -38,7 +38,7 @@ data:
kubernetes:
rateLimitDeployment:
container:
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
patch:
type: StrategicMerge
value:
diff --git a/test/helm/gateway-helm/envoy-gateway-gateway-namespace-config-watch.out.yaml b/test/helm/gateway-helm/envoy-gateway-gateway-namespace-config-watch.out.yaml
index 36e22808fd..34a42953f3 100644
--- a/test/helm/gateway-helm/envoy-gateway-gateway-namespace-config-watch.out.yaml
+++ b/test/helm/gateway-helm/envoy-gateway-gateway-namespace-config-watch.out.yaml
@@ -40,7 +40,7 @@ data:
type: GatewayNamespace
rateLimitDeployment:
container:
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
patch:
type: StrategicMerge
value:
diff --git a/test/helm/gateway-helm/envoy-gateway-gateway-namespace-config.out.yaml b/test/helm/gateway-helm/envoy-gateway-gateway-namespace-config.out.yaml
index 2a5a315dbc..5795e02e6f 100644
--- a/test/helm/gateway-helm/envoy-gateway-gateway-namespace-config.out.yaml
+++ b/test/helm/gateway-helm/envoy-gateway-gateway-namespace-config.out.yaml
@@ -40,7 +40,7 @@ data:
type: GatewayNamespace
rateLimitDeployment:
container:
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
patch:
type: StrategicMerge
value:
diff --git a/test/helm/gateway-helm/horizontal-pod-autoscaler.out.yaml b/test/helm/gateway-helm/horizontal-pod-autoscaler.out.yaml
index 0f4762e469..ac2d4b20b8 100644
--- a/test/helm/gateway-helm/horizontal-pod-autoscaler.out.yaml
+++ b/test/helm/gateway-helm/horizontal-pod-autoscaler.out.yaml
@@ -38,7 +38,7 @@ data:
kubernetes:
rateLimitDeployment:
container:
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
patch:
type: StrategicMerge
value:
diff --git a/test/helm/gateway-helm/service-customization.out.yaml b/test/helm/gateway-helm/service-customization.out.yaml
index 8ae6075f77..40e788b27b 100644
--- a/test/helm/gateway-helm/service-customization.out.yaml
+++ b/test/helm/gateway-helm/service-customization.out.yaml
@@ -38,7 +38,7 @@ data:
kubernetes:
rateLimitDeployment:
container:
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
patch:
type: StrategicMerge
value:
diff --git a/test/helm/gateway-helm/webhook-disabled.out.yaml b/test/helm/gateway-helm/webhook-disabled.out.yaml
index 7c11e2ced8..c92917716c 100644
--- a/test/helm/gateway-helm/webhook-disabled.out.yaml
+++ b/test/helm/gateway-helm/webhook-disabled.out.yaml
@@ -38,7 +38,7 @@ data:
kubernetes:
rateLimitDeployment:
container:
- image: docker.io/envoyproxy/ratelimit:master
+ image: docker.io/envoyproxy/ratelimit:e74a664a
patch:
type: StrategicMerge
value:
diff --git a/test/resilience/tests/extensionserver.go b/test/resilience/tests/extensionserver.go
index 6947a87ab0..65c4bffeb5 100644
--- a/test/resilience/tests/extensionserver.go
+++ b/test/resilience/tests/extensionserver.go
@@ -34,7 +34,7 @@ var ESResilience = suite.ResilienceTest{
Test: func(t *testing.T, suite *suite.ResilienceTestSuite) {
const (
namespace = "envoy-gateway-system"
- PrometheusXDSTranslatorErrors = `watchable_subscribe_total{runner="xds-translator", status="failure"}`
+ PrometheusXDSTranslatorErrors = `watchable_subscribe_total{runner="xds", status="failure"}`
PrometheusEnvoyConnectedToControlPlane = `envoy_control_plane_connected_state`
)
diff --git a/tools/docker/envoy-gateway/Dockerfile b/tools/docker/envoy-gateway/Dockerfile
index f9b2aa70b1..0911b964a1 100644
--- a/tools/docker/envoy-gateway/Dockerfile
+++ b/tools/docker/envoy-gateway/Dockerfile
@@ -4,7 +4,7 @@ RUN mkdir -p /var/lib/eg && chmod -R 0777 /var/lib/eg
# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
-FROM gcr.io/distroless/base-nossl:nonroot@sha256:fa7b50f111719aaf5f7435383b6d05f12277f3ce9514bc0a62759374a04d6bae
+FROM gcr.io/distroless/base-nossl:nonroot@sha256:a1922debbf4ff2cc245d7c0d1e2021cfcee35fe24afae7505aeec59f7e7802f6
ARG TARGETPLATFORM
COPY $TARGETPLATFORM/envoy-gateway /usr/local/bin/
COPY --from=source /var/lib /var/lib
diff --git a/tools/go.mod b/tools/go.mod
new file mode 100644
index 0000000000..af9397d90f
--- /dev/null
+++ b/tools/go.mod
@@ -0,0 +1,352 @@
+module tools
+
+go 1.24.7
+
+tool (
+ github.com/bufbuild/buf/cmd/buf
+ github.com/elastic/crd-ref-docs
+ github.com/golangci/golangci-lint/v2/cmd/golangci-lint
+ github.com/google/go-jsonnet/cmd/jsonnet
+ github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb
+ github.com/norwoodj/helm-docs/cmd/helm-docs
+ google.golang.org/grpc/cmd/protoc-gen-go-grpc
+ google.golang.org/protobuf/cmd/protoc-gen-go
+ sigs.k8s.io/controller-runtime/tools/setup-envtest
+ sigs.k8s.io/controller-tools/cmd/controller-gen
+ sigs.k8s.io/kind/cmd/kind
+)
+
+require (
+ 4d63.com/gocheckcompilerdirectives v1.3.0 // indirect
+ 4d63.com/gochecknoglobals v0.2.2 // indirect
+ al.essio.dev/pkg/shellescape v1.5.1 // indirect
+ buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.6-20250718181942-e35f9b667443.1 // indirect
+ buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250717185734-6c6e0d3c608e.1 // indirect
+ buf.build/gen/go/bufbuild/registry/connectrpc/go v1.18.1-20250721151928-2b7ae473b098.1 // indirect
+ buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.6-20250721151928-2b7ae473b098.1 // indirect
+ buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.36.6-20241007202033-cf42259fcbfc.1 // indirect
+ buf.build/go/app v0.1.0 // indirect
+ buf.build/go/bufplugin v0.9.0 // indirect
+ buf.build/go/interrupt v1.1.0 // indirect
+ buf.build/go/protovalidate v0.14.0 // indirect
+ buf.build/go/protoyaml v0.6.0 // indirect
+ buf.build/go/spdx v0.2.0 // indirect
+ buf.build/go/standard v0.1.0 // indirect
+ cel.dev/expr v0.24.0 // indirect
+ codeberg.org/chavacava/garif v0.2.0 // indirect
+ connectrpc.com/connect v1.18.1 // indirect
+ connectrpc.com/otelconnect v0.7.2 // indirect
+ dario.cat/mergo v1.0.1 // indirect
+ dev.gaijin.team/go/exhaustruct/v4 v4.0.0 // indirect
+ dev.gaijin.team/go/golib v0.6.0 // indirect
+ github.com/4meepo/tagalign v1.4.3 // indirect
+ github.com/Abirdcfly/dupword v0.1.6 // indirect
+ github.com/AlwxSin/noinlineerr v1.0.5 // indirect
+ github.com/Antonboom/errname v1.1.0 // indirect
+ github.com/Antonboom/nilnil v1.1.0 // indirect
+ github.com/Antonboom/testifylint v1.6.1 // indirect
+ github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
+ github.com/BurntSushi/toml v1.5.0 // indirect
+ github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
+ github.com/Masterminds/goutils v1.1.1 // indirect
+ github.com/Masterminds/semver v1.5.0 // indirect
+ github.com/Masterminds/semver/v3 v3.3.1 // indirect
+ github.com/Masterminds/sprig v2.22.0+incompatible // indirect
+ github.com/Masterminds/sprig/v3 v3.3.0 // indirect
+ github.com/Microsoft/go-winio v0.6.2 // indirect
+ github.com/OpenPeeDeeP/depguard/v2 v2.2.1 // indirect
+ github.com/alecthomas/chroma/v2 v2.20.0 // indirect
+ github.com/alecthomas/go-check-sumtype v0.3.1 // indirect
+ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
+ github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
+ github.com/alexkohler/nakedret/v2 v2.0.6 // indirect
+ github.com/alexkohler/prealloc v1.0.0 // indirect
+ github.com/alfatraining/structtag v1.0.0 // indirect
+ github.com/alingse/asasalint v0.0.11 // indirect
+ github.com/alingse/nilnesserr v0.2.0 // indirect
+ github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
+ github.com/ashanbrown/forbidigo/v2 v2.1.0 // indirect
+ github.com/ashanbrown/makezero/v2 v2.0.1 // indirect
+ github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
+ github.com/beorn7/perks v1.0.1 // indirect
+ github.com/bkielbasa/cyclop v1.2.3 // indirect
+ github.com/blizzy78/varnamelen v0.8.0 // indirect
+ github.com/bombsimon/wsl/v4 v4.7.0 // indirect
+ github.com/bombsimon/wsl/v5 v5.1.1 // indirect
+ github.com/breml/bidichk v0.3.3 // indirect
+ github.com/breml/errchkjson v0.4.1 // indirect
+ github.com/bufbuild/buf v1.56.0 // indirect
+ github.com/bufbuild/protocompile v0.14.1 // indirect
+ github.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1 // indirect
+ github.com/butuzov/ireturn v0.4.0 // indirect
+ github.com/butuzov/mirror v1.3.0 // indirect
+ github.com/catenacyber/perfsprint v0.9.1 // indirect
+ github.com/ccojocar/zxcvbn-go v1.0.4 // indirect
+ github.com/cespare/xxhash/v2 v2.3.0 // indirect
+ github.com/charithe/durationcheck v0.0.10 // indirect
+ github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
+ github.com/charmbracelet/lipgloss v1.1.0 // indirect
+ github.com/charmbracelet/x/ansi v0.8.0 // indirect
+ github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
+ github.com/charmbracelet/x/term v0.2.1 // indirect
+ github.com/ckaznocha/intrange v0.3.1 // indirect
+ github.com/containerd/errdefs v1.0.0 // indirect
+ github.com/containerd/errdefs/pkg v0.3.0 // indirect
+ github.com/containerd/stargz-snapshotter/estargz v0.17.0 // indirect
+ github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
+ github.com/curioswitch/go-reassign v0.3.0 // indirect
+ github.com/daixiang0/gci v0.13.7 // indirect
+ github.com/dave/dst v0.27.3 // indirect
+ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
+ github.com/denis-tingaikin/go-header v0.5.0 // indirect
+ github.com/distribution/reference v0.6.0 // indirect
+ github.com/dlclark/regexp2 v1.11.5 // indirect
+ github.com/docker/cli v28.3.3+incompatible // indirect
+ github.com/docker/distribution v2.8.3+incompatible // indirect
+ github.com/docker/docker v28.3.3+incompatible // indirect
+ github.com/docker/docker-credential-helpers v0.9.3 // indirect
+ github.com/docker/go-connections v0.5.0 // indirect
+ github.com/docker/go-units v0.5.0 // indirect
+ github.com/elastic/crd-ref-docs v0.2.0 // indirect
+ github.com/elliotchance/orderedmap/v2 v2.2.0 // indirect
+ github.com/ettle/strcase v0.2.0 // indirect
+ github.com/evanphx/json-patch/v5 v5.6.0 // indirect
+ github.com/fatih/color v1.18.0 // indirect
+ github.com/fatih/structtag v1.2.0 // indirect
+ github.com/felixge/httpsnoop v1.0.4 // indirect
+ github.com/firefart/nonamedreturns v1.0.6 // indirect
+ github.com/fsnotify/fsnotify v1.7.0 // indirect
+ github.com/fxamacker/cbor/v2 v2.9.0 // indirect
+ github.com/fzipp/gocyclo v0.6.0 // indirect
+ github.com/ghostiam/protogetter v0.3.15 // indirect
+ github.com/go-chi/chi/v5 v5.2.2 // indirect
+ github.com/go-critic/go-critic v0.13.0 // indirect
+ github.com/go-logr/logr v1.4.3 // indirect
+ github.com/go-logr/stdr v1.2.2 // indirect
+ github.com/go-logr/zapr v1.3.0 // indirect
+ github.com/go-openapi/jsonpointer v0.21.0 // indirect
+ github.com/go-openapi/jsonreference v0.20.2 // indirect
+ github.com/go-openapi/swag v0.23.0 // indirect
+ github.com/go-toolsmith/astcast v1.1.0 // indirect
+ github.com/go-toolsmith/astcopy v1.1.0 // indirect
+ github.com/go-toolsmith/astequal v1.2.0 // indirect
+ github.com/go-toolsmith/astfmt v1.1.0 // indirect
+ github.com/go-toolsmith/astp v1.1.0 // indirect
+ github.com/go-toolsmith/strparse v1.1.0 // indirect
+ github.com/go-toolsmith/typep v1.1.0 // indirect
+ github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
+ github.com/go-xmlfmt/xmlfmt v1.1.3 // indirect
+ github.com/gobuffalo/flect v1.0.3 // indirect
+ github.com/gobwas/glob v0.2.3 // indirect
+ github.com/goccy/go-yaml v1.18.0 // indirect
+ github.com/gofrs/flock v0.12.1 // indirect
+ github.com/gogo/protobuf v1.3.2 // indirect
+ github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32 // indirect
+ github.com/golangci/go-printf-func-name v0.1.0 // indirect
+ github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d // indirect
+ github.com/golangci/golangci-lint/v2 v2.4.0 // indirect
+ github.com/golangci/golines v0.0.0-20250217134842-442fd0091d95 // indirect
+ github.com/golangci/misspell v0.7.0 // indirect
+ github.com/golangci/plugin-module-register v0.1.2 // indirect
+ github.com/golangci/revgrep v0.8.0 // indirect
+ github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e // indirect
+ github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e // indirect
+ github.com/google/cel-go v0.26.0 // indirect
+ github.com/google/gnostic-models v0.7.0 // indirect
+ github.com/google/go-cmp v0.7.0 // indirect
+ github.com/google/go-containerregistry v0.20.6 // indirect
+ github.com/google/go-jsonnet v0.21.0 // indirect
+ github.com/google/uuid v1.6.0 // indirect
+ github.com/gordonklaus/ineffassign v0.1.0 // indirect
+ github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
+ github.com/gostaticanalysis/comment v1.5.0 // indirect
+ github.com/gostaticanalysis/forcetypeassert v0.2.0 // indirect
+ github.com/gostaticanalysis/nilerr v0.1.1 // indirect
+ github.com/hashicorp/go-immutable-radix/v2 v2.1.0 // indirect
+ github.com/hashicorp/go-version v1.7.0 // indirect
+ github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
+ github.com/hashicorp/hcl v1.0.0 // indirect
+ github.com/hexops/gotextdiff v1.0.3 // indirect
+ github.com/huandu/xstrings v1.5.0 // indirect
+ github.com/imdario/mergo v0.3.13 // indirect
+ github.com/inconshreveable/mousetrap v1.1.0 // indirect
+ github.com/jdx/go-netrc v1.0.0 // indirect
+ github.com/jgautheron/goconst v1.8.2 // indirect
+ github.com/jingyugao/rowserrcheck v1.1.1 // indirect
+ github.com/jjti/go-spancheck v0.6.5 // indirect
+ github.com/josharian/intern v1.0.0 // indirect
+ github.com/json-iterator/go v1.1.12 // indirect
+ github.com/jsonnet-bundler/jsonnet-bundler v0.6.0 // indirect
+ github.com/julz/importas v0.2.0 // indirect
+ github.com/karamaru-alpha/copyloopvar v1.2.1 // indirect
+ github.com/kisielk/errcheck v1.9.0 // indirect
+ github.com/kkHAIKE/contextcheck v1.1.6 // indirect
+ github.com/klauspost/compress v1.18.0 // indirect
+ github.com/klauspost/pgzip v1.2.6 // indirect
+ github.com/kulti/thelper v0.6.3 // indirect
+ github.com/kunwardeep/paralleltest v1.0.14 // indirect
+ github.com/lasiar/canonicalheader v1.1.2 // indirect
+ github.com/ldez/exptostd v0.4.4 // indirect
+ github.com/ldez/gomoddirectives v0.7.0 // indirect
+ github.com/ldez/grignotin v0.10.0 // indirect
+ github.com/ldez/tagliatelle v0.7.1 // indirect
+ github.com/ldez/usetesting v0.5.0 // indirect
+ github.com/leonklingele/grouper v1.1.2 // indirect
+ github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
+ github.com/macabu/inamedparam v0.2.0 // indirect
+ github.com/magiconair/properties v1.8.7 // indirect
+ github.com/mailru/easyjson v0.7.7 // indirect
+ github.com/manuelarte/embeddedstructfieldcheck v0.3.0 // indirect
+ github.com/manuelarte/funcorder v0.5.0 // indirect
+ github.com/maratori/testableexamples v1.0.0 // indirect
+ github.com/maratori/testpackage v1.1.1 // indirect
+ github.com/matoous/godox v1.1.0 // indirect
+ github.com/mattn/go-colorable v0.1.14 // indirect
+ github.com/mattn/go-isatty v0.0.20 // indirect
+ github.com/mattn/go-runewidth v0.0.16 // indirect
+ github.com/mgechev/revive v1.11.0 // indirect
+ github.com/mitchellh/copystructure v1.2.0 // indirect
+ github.com/mitchellh/go-homedir v1.1.0 // indirect
+ github.com/mitchellh/mapstructure v1.5.0 // indirect
+ github.com/mitchellh/reflectwalk v1.0.2 // indirect
+ github.com/moby/docker-image-spec v1.3.1 // indirect
+ github.com/moby/term v0.5.2 // indirect
+ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+ github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
+ github.com/moricho/tparallel v0.3.2 // indirect
+ github.com/morikuni/aec v1.0.0 // indirect
+ github.com/muesli/termenv v0.16.0 // indirect
+ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
+ github.com/nakabonne/nestif v0.3.1 // indirect
+ github.com/nishanths/exhaustive v0.12.0 // indirect
+ github.com/nishanths/predeclared v0.2.2 // indirect
+ github.com/norwoodj/helm-docs v1.14.2 // indirect
+ github.com/nunnatsa/ginkgolinter v0.20.0 // indirect
+ github.com/opencontainers/go-digest v1.0.0 // indirect
+ github.com/opencontainers/image-spec v1.1.1 // indirect
+ github.com/pelletier/go-toml v1.9.5 // indirect
+ github.com/pelletier/go-toml/v2 v2.2.4 // indirect
+ github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
+ github.com/pkg/errors v0.9.1 // indirect
+ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
+ github.com/polyfloyd/go-errorlint v1.8.0 // indirect
+ github.com/prometheus/client_golang v1.22.0 // indirect
+ github.com/prometheus/client_model v0.6.1 // indirect
+ github.com/prometheus/common v0.62.0 // indirect
+ github.com/prometheus/procfs v0.15.1 // indirect
+ github.com/quasilyte/go-ruleguard v0.4.4 // indirect
+ github.com/quasilyte/go-ruleguard/dsl v0.3.22 // indirect
+ github.com/quasilyte/gogrep v0.5.0 // indirect
+ github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect
+ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect
+ github.com/quic-go/qpack v0.5.1 // indirect
+ github.com/quic-go/quic-go v0.54.0 // indirect
+ github.com/raeperd/recvcheck v0.2.0 // indirect
+ github.com/rivo/uniseg v0.4.7 // indirect
+ github.com/rogpeppe/go-internal v1.14.1 // indirect
+ github.com/rs/cors v1.11.1 // indirect
+ github.com/russross/blackfriday/v2 v2.1.0 // indirect
+ github.com/ryancurrah/gomodguard v1.4.1 // indirect
+ github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect
+ github.com/sanposhiho/wastedassign/v2 v2.1.0 // indirect
+ github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
+ github.com/sashamelentyev/interfacebloat v1.1.0 // indirect
+ github.com/sashamelentyev/usestdlibvars v1.29.0 // indirect
+ github.com/securego/gosec/v2 v2.22.7 // indirect
+ github.com/segmentio/asm v1.2.0 // indirect
+ github.com/segmentio/encoding v0.5.3 // indirect
+ github.com/shopspring/decimal v1.4.0 // indirect
+ github.com/sirupsen/logrus v1.9.3 // indirect
+ github.com/sivchari/containedctx v1.0.3 // indirect
+ github.com/sonatard/noctx v0.4.0 // indirect
+ github.com/sourcegraph/go-diff v0.7.0 // indirect
+ github.com/spf13/afero v1.14.0 // indirect
+ github.com/spf13/cast v1.7.0 // indirect
+ github.com/spf13/cobra v1.9.1 // indirect
+ github.com/spf13/jwalterweatherman v1.1.0 // indirect
+ github.com/spf13/pflag v1.0.7 // indirect
+ github.com/spf13/viper v1.16.0 // indirect
+ github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
+ github.com/stbenjam/no-sprintf-host-port v0.2.0 // indirect
+ github.com/stoewer/go-strcase v1.3.1 // indirect
+ github.com/stretchr/objx v0.5.2 // indirect
+ github.com/stretchr/testify v1.10.0 // indirect
+ github.com/subosito/gotenv v1.4.2 // indirect
+ github.com/tdakkota/asciicheck v0.4.1 // indirect
+ github.com/tetafro/godot v1.5.1 // indirect
+ github.com/tetratelabs/wazero v1.9.0 // indirect
+ github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67 // indirect
+ github.com/timonwong/loggercheck v0.11.0 // indirect
+ github.com/tomarrell/wrapcheck/v2 v2.11.0 // indirect
+ github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect
+ github.com/ultraware/funlen v0.2.0 // indirect
+ github.com/ultraware/whitespace v0.2.0 // indirect
+ github.com/uudashr/gocognit v1.2.0 // indirect
+ github.com/uudashr/iface v1.4.1 // indirect
+ github.com/vbatts/tar-split v0.12.1 // indirect
+ github.com/x448/float16 v0.8.4 // indirect
+ github.com/xen0n/gosmopolitan v1.3.0 // indirect
+ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
+ github.com/yagipy/maintidx v1.0.0 // indirect
+ github.com/yeya24/promlinter v0.3.0 // indirect
+ github.com/ykadowak/zerologlint v0.1.5 // indirect
+ gitlab.com/bosi/decorder v0.4.2 // indirect
+ go-simpler.org/musttag v0.13.1 // indirect
+ go-simpler.org/sloglint v0.11.1 // indirect
+ go.augendre.info/arangolint v0.2.0 // indirect
+ go.augendre.info/fatcontext v0.8.0 // indirect
+ go.lsp.dev/jsonrpc2 v0.10.0 // indirect
+ go.lsp.dev/pkg v0.0.0-20210717090340-384b27a52fb2 // indirect
+ go.lsp.dev/protocol v0.12.0 // indirect
+ go.lsp.dev/uri v0.3.0 // indirect
+ go.opentelemetry.io/auto/sdk v1.1.0 // indirect
+ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect
+ go.opentelemetry.io/otel v1.37.0 // indirect
+ go.opentelemetry.io/otel/metric v1.37.0 // indirect
+ go.opentelemetry.io/otel/trace v1.37.0 // indirect
+ go.uber.org/automaxprocs v1.6.0 // indirect
+ go.uber.org/mock v0.5.2 // indirect
+ go.uber.org/multierr v1.11.0 // indirect
+ go.uber.org/zap v1.27.0 // indirect
+ go.yaml.in/yaml/v2 v2.4.2 // indirect
+ go.yaml.in/yaml/v3 v3.0.4 // indirect
+ golang.org/x/crypto v0.41.0 // indirect
+ golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 // indirect
+ golang.org/x/exp/typeparams v0.0.0-20250620022241-b7579e27df2b // indirect
+ golang.org/x/mod v0.27.0 // indirect
+ golang.org/x/net v0.43.0 // indirect
+ golang.org/x/sync v0.16.0 // indirect
+ golang.org/x/sys v0.35.0 // indirect
+ golang.org/x/term v0.34.0 // indirect
+ golang.org/x/text v0.28.0 // indirect
+ golang.org/x/tools v0.36.0 // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0 // indirect
+ google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 // indirect
+ google.golang.org/protobuf v1.36.7 // indirect
+ gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect
+ gopkg.in/inf.v0 v0.9.1 // indirect
+ gopkg.in/ini.v1 v1.67.0 // indirect
+ gopkg.in/yaml.v2 v2.4.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
+ helm.sh/helm/v3 v3.18.6 // indirect
+ honnef.co/go/tools v0.6.1 // indirect
+ k8s.io/api v0.33.3 // indirect
+ k8s.io/apiextensions-apiserver v0.33.3 // indirect
+ k8s.io/apimachinery v0.34.0-rc.1 // indirect
+ k8s.io/code-generator v0.33.3 // indirect
+ k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f // indirect
+ k8s.io/klog/v2 v2.130.1 // indirect
+ k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
+ k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect
+ mvdan.cc/gofumpt v0.8.0 // indirect
+ mvdan.cc/unparam v0.0.0-20250301125049-0df0534333a4 // indirect
+ pluginrpc.com/pluginrpc v0.5.0 // indirect
+ sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20250819114936-e4f9a2446c3d // indirect
+ sigs.k8s.io/controller-tools v0.18.0 // indirect
+ sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
+ sigs.k8s.io/kind v0.29.0 // indirect
+ sigs.k8s.io/randfill v1.0.0 // indirect
+ sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
+ sigs.k8s.io/yaml v1.6.0 // indirect
+)
diff --git a/tools/go.sum b/tools/go.sum
new file mode 100644
index 0000000000..8f8aafa994
--- /dev/null
+++ b/tools/go.sum
@@ -0,0 +1,495 @@
+4d63.com/gocheckcompilerdirectives v1.3.0/go.mod h1:ofsJ4zx2QAuIP/NO/NAh1ig6R1Fb18/GI7RVMwz7kAY=
+4d63.com/gochecknoglobals v0.2.2/go.mod h1:lLxwTQjL5eIesRbvnzIP3jZtG140FnTdz+AlMa+ogt0=
+al.essio.dev/pkg/shellescape v1.5.1/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890=
+buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.6-20250718181942-e35f9b667443.1/go.mod h1:TsmeaGU5CZAF7zRM05vIKgXh56GgwaoMS8X+a77RV5Q=
+buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250717185734-6c6e0d3c608e.1/go.mod h1:avRlCjnFzl98VPaeCtJ24RrV/wwHFzB8sWXhj26+n/U=
+buf.build/gen/go/bufbuild/registry/connectrpc/go v1.18.1-20250721151928-2b7ae473b098.1/go.mod h1:/MMEAJmz7PEmksjkSxhWXell82FXiG7BLUPBJRmKBsA=
+buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.6-20250721151928-2b7ae473b098.1/go.mod h1:RsJBKYlgzsbl5LAhIu0cNrPPzBNenMLTAAykRxFidtw=
+buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.36.6-20241007202033-cf42259fcbfc.1/go.mod h1:OUbhXurY+VHFGn9FBxcRy8UB7HXk9NvJ2qCgifOMypQ=
+buf.build/go/app v0.1.0/go.mod h1:0XVOYemubVbxNXVY0DnsVgWeGkcbbAvjDa1fmhBC+Wo=
+buf.build/go/bufplugin v0.9.0/go.mod h1:Z0CxA3sKQ6EPz/Os4kJJneeRO6CjPeidtP1ABh5jPPY=
+buf.build/go/interrupt v1.1.0/go.mod h1:ql56nXPG1oHlvZa6efNC7SKAQ/tUjS6z0mhJl0gyeRM=
+buf.build/go/protovalidate v0.14.0/go.mod h1:+F/oISho9MO7gJQNYC2VWLzcO1fTPmaTA08SDYJZncA=
+buf.build/go/protoyaml v0.6.0/go.mod h1:RgUOsBu/GYKLDSIRgQXniXbNgFlGEZnQpRAUdLAFV2Q=
+buf.build/go/spdx v0.2.0/go.mod h1:bXdwQFem9Si3nsbNy8aJKGPoaPi5DKwdeEp5/ArZ6w8=
+buf.build/go/standard v0.1.0/go.mod h1:PiqpHz/7ZFq+kqvYhc/SK3lxFIB9N/aiH2CFC2JHIQg=
+cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
+codeberg.org/chavacava/garif v0.2.0/go.mod h1:P2BPbVbT4QcvLZrORc2T29szK3xEOlnl0GiPTJmEqBQ=
+connectrpc.com/connect v1.18.1/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8=
+connectrpc.com/otelconnect v0.7.2/go.mod h1:JS7XUKfuJs2adhCnXhNHPHLz6oAaZniCJdSF00OZSew=
+dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
+dev.gaijin.team/go/exhaustruct/v4 v4.0.0/go.mod h1:aZ/k2o4Y05aMJtiux15x8iXaumE88YdiB0Ai4fXOzPI=
+dev.gaijin.team/go/golib v0.6.0/go.mod h1:uY1mShx8Z/aNHWDyAkZTkX+uCi5PdX7KsG1eDQa2AVE=
+github.com/4meepo/tagalign v1.4.3/go.mod h1:00WwRjiuSbrRJnSVeGWPLp2epS5Q/l4UEy0apLLS37c=
+github.com/Abirdcfly/dupword v0.1.6/go.mod h1:s+BFMuL/I4YSiFv29snqyjwzDp4b65W2Kvy+PKzZ6cw=
+github.com/AlwxSin/noinlineerr v1.0.5/go.mod h1:+QgkkoYrMH7RHvcdxdlI7vYYEdgeoFOVjU9sUhw/rQc=
+github.com/Antonboom/errname v1.1.0/go.mod h1:O1NMrzgUcVBGIfi3xlVuvX8Q/VP/73sseCaAppfjqZw=
+github.com/Antonboom/nilnil v1.1.0/go.mod h1:b7sAlogQjFa1wV8jUW3o4PMzDVFLbTux+xnQdvzdcIE=
+github.com/Antonboom/testifylint v1.6.1/go.mod h1:k+nEkathI2NFjKO6HvwmSrbzUcQ6FAnbZV+ZRrnXPLI=
+github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
+github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
+github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
+github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
+github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
+github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
+github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
+github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
+github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
+github.com/OpenPeeDeeP/depguard/v2 v2.2.1/go.mod h1:q4DKzC4UcVaAvcfd41CZh0PWpGgzrVxUYBlgKNGquUo=
+github.com/alecthomas/chroma/v2 v2.20.0/go.mod h1:e7tViK0xh/Nf4BYHl00ycY6rV7b8iXBksI9E359yNmA=
+github.com/alecthomas/go-check-sumtype v0.3.1/go.mod h1:A8TSiN3UPRw3laIgWEUOHHLPa6/r9MtoigdlP5h3K/E=
+github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
+github.com/alexkohler/nakedret/v2 v2.0.6/go.mod h1:l3RKju/IzOMQHmsEvXwkqMDzHHvurNQfAgE1eVmT40Q=
+github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE=
+github.com/alfatraining/structtag v1.0.0/go.mod h1:p3Xi5SwzTi+Ryj64DqjLWz7XurHxbGsq6y3ubePJPus=
+github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I=
+github.com/alingse/nilnesserr v0.2.0/go.mod h1:1xJPrXonEtX7wyTq8Dytns5P2hNzoWymVUIaKm4HNFg=
+github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw=
+github.com/ashanbrown/forbidigo/v2 v2.1.0/go.mod h1:0zZfdNAuZIL7rSComLGthgc/9/n2FqspBOH90xlCHdA=
+github.com/ashanbrown/makezero/v2 v2.0.1/go.mod h1:kKU4IMxmYW1M4fiEHMb2vc5SFoPzXvgbMR9gIp5pjSw=
+github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bkielbasa/cyclop v1.2.3/go.mod h1:kHTwA9Q0uZqOADdupvcFJQtp/ksSnytRMe8ztxG8Fuo=
+github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k=
+github.com/bombsimon/wsl/v4 v4.7.0/go.mod h1:uV/+6BkffuzSAVYD+yGyld1AChO7/EuLrCF/8xTiapg=
+github.com/bombsimon/wsl/v5 v5.1.1/go.mod h1:Gp8lD04z27wm3FANIUPZycXp+8huVsn0oxc+n4qfV9I=
+github.com/breml/bidichk v0.3.3/go.mod h1:ISbsut8OnjB367j5NseXEGGgO/th206dVa427kR8YTE=
+github.com/breml/errchkjson v0.4.1/go.mod h1:a23OvR6Qvcl7DG/Z4o0el6BRAjKnaReoPQFciAl9U3s=
+github.com/bufbuild/buf v1.56.0/go.mod h1:uDNMYshCJIXL99OQc71SDeFiDqOse9sSHXPpZlrqElw=
+github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
+github.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1/go.mod h1:c5D8gWRIZ2HLWO3gXYTtUfw/hbJyD8xikv2ooPxnklQ=
+github.com/butuzov/ireturn v0.4.0/go.mod h1:ghI0FrCmap8pDWZwfPisFD1vEc56VKH4NpQUxDHta70=
+github.com/butuzov/mirror v1.3.0/go.mod h1:AEij0Z8YMALaq4yQj9CPPVYOyJQyiexpQEQgihajRfI=
+github.com/catenacyber/perfsprint v0.9.1/go.mod h1:q//VWC2fWbcdSLEY1R3l8n0zQCDPdE4IjZwyY1HMunM=
+github.com/ccojocar/zxcvbn-go v1.0.4/go.mod h1:3GxGX+rHmueTUMvm5ium7irpyjmm7ikxYFOSJB21Das=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ=
+github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
+github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
+github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=
+github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
+github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
+github.com/ckaznocha/intrange v0.3.1/go.mod h1:QVepyz1AkUoFQkpEqksSYpNpUo3c5W7nWh/s6SHIJJk=
+github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
+github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
+github.com/containerd/stargz-snapshotter/estargz v0.17.0/go.mod h1:s06tWAiJcXQo9/8AReBCIo/QxcXFZ2n4qfsRnpl71SM=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
+github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/curioswitch/go-reassign v0.3.0/go.mod h1:nApPCCTtqLJN/s8HfItCcKV0jIPwluBOvZP+dsJGA88=
+github.com/daixiang0/gci v0.13.7/go.mod h1:812WVN6JLFY9S6Tv76twqmNqevN0pa3SX3nih0brVzQ=
+github.com/dave/dst v0.27.3/go.mod h1:jHh6EOibnHgcUW3WjKHisiooEkYwqpHLBSX1iOBhEyc=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/denis-tingaikin/go-header v0.5.0/go.mod h1:mMenU5bWrok6Wl2UsZjy+1okegmwQ3UgWl4V1D8gjlY=
+github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
+github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
+github.com/docker/cli v28.3.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
+github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
+github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
+github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
+github.com/elastic/crd-ref-docs v0.2.0/go.mod h1:0bklkJhTG7nC6AVsdDi0wt5bGoqvzdZSzMMQkilZ6XM=
+github.com/elliotchance/orderedmap/v2 v2.2.0/go.mod h1:85lZyVbpGaGvHvnKa7Qhx7zncAdBIBq6u56Hb1PRU5Q=
+github.com/ettle/strcase v0.2.0/go.mod h1:DajmHElDSaX76ITe3/VHVyMin4LWSJN5Z909Wp+ED1A=
+github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
+github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
+github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
+github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
+github.com/firefart/nonamedreturns v1.0.6/go.mod h1:R8NisJnSIpvPWheCq0mNRXJok6D8h7fagJTF8EMEwCo=
+github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
+github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
+github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
+github.com/ghostiam/protogetter v0.3.15/go.mod h1:WZ0nw9pfzsgxuRsPOFQomgDVSWtDLJRfQJEhsGbmQMA=
+github.com/go-chi/chi/v5 v5.2.2/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
+github.com/go-critic/go-critic v0.13.0/go.mod h1:M/YeuJ3vOCQDnP2SU+ZhjgRzwzcBW87JqLpMJLrZDLI=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
+github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
+github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
+github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
+github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
+github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
+github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU=
+github.com/go-toolsmith/astcopy v1.1.0/go.mod h1:hXM6gan18VA1T/daUEHCFcYiW8Ai1tIwIzHY6srfEAw=
+github.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4=
+github.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ=
+github.com/go-toolsmith/astequal v1.2.0/go.mod h1:c8NZ3+kSFtFY/8lPso4v8LuJjdJiUFVnSuU3s0qrrDY=
+github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4=
+github.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA=
+github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
+github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ=
+github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig=
+github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
+github.com/go-xmlfmt/xmlfmt v1.1.3/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
+github.com/gobuffalo/flect v1.0.3/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs=
+github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
+github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
+github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0=
+github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32/go.mod h1:NUw9Zr2Sy7+HxzdjIULge71wI6yEg1lWQr7Evcu8K0E=
+github.com/golangci/go-printf-func-name v0.1.0/go.mod h1:wqhWFH5mUdJQhweRnldEywnR5021wTdZSNgwYceV14s=
+github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d/go.mod h1:ivJ9QDg0XucIkmwhzCDsqcnxxlDStoTl89jDMIoNxKY=
+github.com/golangci/golangci-lint/v2 v2.4.0/go.mod h1:Oq7vuAf6L1iNL34uHDcsIF6Mnc0amOPdsT3/GlpHD+I=
+github.com/golangci/golines v0.0.0-20250217134842-442fd0091d95/go.mod h1:k9mmcyWKSTMcPPvQUCfRWWQ9VHJ1U9Dc0R7kaXAgtnQ=
+github.com/golangci/misspell v0.7.0/go.mod h1:WZyyI2P3hxPY2UVHs3cS8YcllAeyfquQcKfdeE9AFVg=
+github.com/golangci/plugin-module-register v0.1.2/go.mod h1:1+QGTsKBvAIvPvoY/os+G5eoqxWn70HYDm2uvUyGuVw=
+github.com/golangci/revgrep v0.8.0/go.mod h1:U4R/s9dlXZsg8uJmaR1GrloUr14D7qDl8gi2iPXJH8k=
+github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e/go.mod h1:Vrn4B5oR9qRwM+f54koyeH3yzphlecwERs0el27Fr/s=
+github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e/go.mod h1:h+wZwLjUTJnm/P2rwlbJdRPZXOzaT36/FwnPnY2inzc=
+github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM=
+github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
+github.com/google/go-containerregistry v0.20.6/go.mod h1:T0x8MuoAoKX/873bkeSfLD2FAkwCDf9/HZgsFJ02E2Y=
+github.com/google/go-jsonnet v0.21.0/go.mod h1:tCGAu8cpUpEZcdGMmdOu37nh8bGgqubhI5v2iSk3KJQ=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gordonklaus/ineffassign v0.1.0/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0=
+github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc=
+github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado=
+github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM=
+github.com/gostaticanalysis/comment v1.5.0/go.mod h1:V6eb3gpCv9GNVqb6amXzEUX3jXLVK/AdA+IrAMSqvEc=
+github.com/gostaticanalysis/forcetypeassert v0.2.0/go.mod h1:M5iPavzE9pPqWyeiVXSFghQjljW1+l/Uke3PXHS6ILY=
+github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A=
+github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M=
+github.com/hashicorp/go-immutable-radix/v2 v2.1.0/go.mod h1:hgdqLXA4f6NIjRVisM1TJ9aOJVNRqKZj+xDGF6m7PBw=
+github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
+github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
+github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
+github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/jdx/go-netrc v1.0.0/go.mod h1:Gh9eFQJnoTNIRHXl2j5bJXA1u84hQWJWgGh569zF3v8=
+github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
+github.com/jgautheron/goconst v1.8.2/go.mod h1:A0oxgBCHy55NQn6sYpO7UdnA9p+h7cPtoOZUmvNIako=
+github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c=
+github.com/jjti/go-spancheck v0.6.5/go.mod h1:aEogkeatBrbYsyW6y5TgDfihCulDYciL1B7rG2vSsrU=
+github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/jsonnet-bundler/jsonnet-bundler v0.6.0/go.mod h1:5esRxD59TyScj6qxT3o7GH0sryBKvVmx2zaEYDXtQkg=
+github.com/julz/importas v0.2.0/go.mod h1:pThlt589EnCYtMnmhmRYY/qn9lCf/frPOK+WMx3xiJY=
+github.com/karamaru-alpha/copyloopvar v1.2.1/go.mod h1:nFmMlFNlClC2BPvNaHMdkirmTJxVCY0lhxBtlfOypMM=
+github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+github.com/kisielk/errcheck v1.9.0/go.mod h1:kQxWMMVZgIkDq7U8xtG/n2juOjbLgZtedi0D+/VL/i8=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/kkHAIKE/contextcheck v1.1.6/go.mod h1:3dDbMRNBFaq8HFXWC1JyvDSPm43CmE6IuHam8Wr0rkg=
+github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
+github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I=
+github.com/kunwardeep/paralleltest v1.0.14/go.mod h1:di4moFqtfz3ToSKxhNjhOZL+696QtJGCFe132CbBLGk=
+github.com/lasiar/canonicalheader v1.1.2/go.mod h1:qJCeLFS0G/QlLQ506T+Fk/fWMa2VmBUiEI2cuMK4djI=
+github.com/ldez/exptostd v0.4.4/go.mod h1:QfdzPw6oHjFVdNV7ILoPu5sw3OZ3OG1JS0I5JN3J4Js=
+github.com/ldez/gomoddirectives v0.7.0/go.mod h1:wR4v8MN9J8kcwvrkzrx6sC9xe9Cp68gWYCsda5xvyGc=
+github.com/ldez/grignotin v0.10.0/go.mod h1:oR4iCKUP9fwoeO6vCQeD7M5SMxCT6xdVas4vg0h1LaI=
+github.com/ldez/tagliatelle v0.7.1/go.mod h1:3zjxUpsNB2aEZScWiZTHrAXOl1x25t3cRmzfK1mlo2I=
+github.com/ldez/usetesting v0.5.0/go.mod h1:Spnb4Qppf8JTuRgblLrEWb7IE6rDmUpGvxY3iRrzvDQ=
+github.com/leonklingele/grouper v1.1.2/go.mod h1:6D0M/HVkhs2yRKRFZUoGjeDy7EZTfFBE9gl4kjmIGkA=
+github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
+github.com/macabu/inamedparam v0.2.0/go.mod h1:+Pee9/YfGe5LJ62pYXqB89lJ+0k5bsR8Wgz/C0Zlq3U=
+github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
+github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/manuelarte/embeddedstructfieldcheck v0.3.0/go.mod h1:LSo/IQpPfx1dXMcX4ibZCYA7Yy6ayZHIaOGM70+1Wy8=
+github.com/manuelarte/funcorder v0.5.0/go.mod h1:Yt3CiUQthSBMBxjShjdXMexmzpP8YGvGLjrxJNkO2hA=
+github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE=
+github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc=
+github.com/matoous/godox v1.1.0/go.mod h1:jgE/3fUXiTurkdHOLT5WEkThTSuE7yxHv5iWPa80afs=
+github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
+github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/mgechev/revive v1.11.0/go.mod h1:tI0oLF/2uj+InHCBLrrqfTKfjtFTBCFFfG05auyzgdw=
+github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
+github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/moricho/tparallel v0.3.2/go.mod h1:OQ+K3b4Ln3l2TZveGCywybl68glfLEwFGqvnjok8b+U=
+github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
+github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
+github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE=
+github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs=
+github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=
+github.com/norwoodj/helm-docs v1.14.2/go.mod h1:qdo76rorOkPDme8nsV5e0JBAYrs56kzvZMYW83k1kgc=
+github.com/nunnatsa/ginkgolinter v0.20.0/go.mod h1:dCIuFlTPfQerXgGUju3VygfAFPdC5aE1mdacCDKDJcQ=
+github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
+github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
+github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw=
+github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
+github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
+github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
+github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
+github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
+github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
+github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/polyfloyd/go-errorlint v1.8.0/go.mod h1:G2W0Q5roxbLCt0ZQbdoxQxXktTjwNyDbEaj3n7jvl4s=
+github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
+github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
+github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
+github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
+github.com/quasilyte/go-ruleguard v0.4.4/go.mod h1:Vl05zJ538vcEEwu16V/Hdu7IYZWyKSwIy4c88Ro1kRE=
+github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
+github.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng=
+github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0=
+github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ=
+github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
+github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
+github.com/raeperd/recvcheck v0.2.0/go.mod h1:n04eYkwIR0JbgD73wT8wL4JjPC3wm0nFtzBnWNocnYU=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
+github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/ryancurrah/gomodguard v1.4.1/go.mod h1:qnMJwV1hX9m+YJseXEBhd2s90+1Xn6x9dLz11ualI1I=
+github.com/ryanrolds/sqlclosecheck v0.5.1/go.mod h1:2g3dUjoS6AL4huFdv6wn55WpLIDjY7ZgUR4J8HOO/XQ=
+github.com/sanposhiho/wastedassign/v2 v2.1.0/go.mod h1:+oSmSC+9bQ+VUAxA66nBb0Z7N8CK7mscKTDYC6aIek4=
+github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
+github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ=
+github.com/sashamelentyev/usestdlibvars v1.29.0/go.mod h1:8PpnjHMk5VdeWlVb4wCdrB8PNbLqZ3wBZTZWkrpZZL8=
+github.com/securego/gosec/v2 v2.22.7/go.mod h1:510TFNDMrIPytokyHQAVLvPeDr41Yihn2ak8P+XQfNE=
+github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
+github.com/segmentio/encoding v0.5.3/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0=
+github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
+github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
+github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
+github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/sivchari/containedctx v1.0.3/go.mod h1:c1RDvCbnJLtH4lLcYD/GqwiBSSf4F5Qk0xld2rBqzJ4=
+github.com/sonatard/noctx v0.4.0/go.mod h1:64XdbzFb18XL4LporKXp8poqZtPKbCrqQ402CV+kJas=
+github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs=
+github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo=
+github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
+github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg=
+github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I=
+github.com/stbenjam/no-sprintf-host-port v0.2.0/go.mod h1:eL0bQ9PasS0hsyTyfTjjG+E80QIyPnBVQbYZyv20Jfk=
+github.com/stoewer/go-strcase v1.3.1/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
+github.com/tdakkota/asciicheck v0.4.1/go.mod h1:0k7M3rCfRXb0Z6bwgvkEIMleKH3kXNz9UqJ9Xuqopr8=
+github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0=
+github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY=
+github.com/tetafro/godot v1.5.1/go.mod h1:cCdPtEndkmqqrhiCfkmxDodMQJ/f3L1BCNskCUZdTwk=
+github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
+github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67/go.mod h1:mkjARE7Yr8qU23YcGMSALbIxTQ9r9QBVahQOBRfU460=
+github.com/timonwong/loggercheck v0.11.0/go.mod h1:HEAWU8djynujaAVX7QI65Myb8qgfcZ1uKbdpg3ZzKl8=
+github.com/tomarrell/wrapcheck/v2 v2.11.0/go.mod h1:wFL9pDWDAbXhhPZZt+nG8Fu+h29TtnZ2MW6Lx4BRXIU=
+github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw=
+github.com/ultraware/funlen v0.2.0/go.mod h1:ZE0q4TsJ8T1SQcjmkhN/w+MceuatI6pBFSxxyteHIJA=
+github.com/ultraware/whitespace v0.2.0/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givTvyI8a586WjW8=
+github.com/uudashr/gocognit v1.2.0/go.mod h1:k/DdKPI6XBZO1q7HgoV2juESI2/Ofj9AcHPZhBBdrTU=
+github.com/uudashr/iface v1.4.1/go.mod h1:pbeBPlbuU2qkNDn0mmfrxP2X+wjPMIQAy+r1MBXSXtg=
+github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA=
+github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
+github.com/xen0n/gosmopolitan v1.3.0/go.mod h1:rckfr5T6o4lBtM1ga7mLGKZmLxswUoH1zxHgNXOsEt4=
+github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
+github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk=
+github.com/yeya24/promlinter v0.3.0/go.mod h1:cDfJQQYv9uYciW60QT0eeHlFodotkYZlL+YcPQN+mW4=
+github.com/ykadowak/zerologlint v0.1.5/go.mod h1:KaUskqF3e/v59oPmdq1U1DnKcuHokl2/K1U4pmIELKg=
+github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+gitlab.com/bosi/decorder v0.4.2/go.mod h1:muuhHoaJkA9QLcYHq4Mj8FJUwDZ+EirSHRiaTcTf6T8=
+go-simpler.org/musttag v0.13.1/go.mod h1:8r450ehpMLQgvpb6sg+hV5Ur47eH6olp/3yEanfG97k=
+go-simpler.org/sloglint v0.11.1/go.mod h1:2PowwiCOK8mjiF+0KGifVOT8ZsCNiFzvfyJeJOIt8MQ=
+go.augendre.info/arangolint v0.2.0/go.mod h1:Vx4KSJwu48tkE+8uxuf0cbBnAPgnt8O1KWiT7bljq7w=
+go.augendre.info/fatcontext v0.8.0/go.mod h1:oVJfMgwngMsHO+KB2MdgzcO+RvtNdiCEOlWvSFtax/s=
+go.lsp.dev/jsonrpc2 v0.10.0/go.mod h1:fmEzIdXPi/rf6d4uFcayi8HpFP1nBF99ERP1htC72Ac=
+go.lsp.dev/pkg v0.0.0-20210717090340-384b27a52fb2/go.mod h1:gtSHRuYfbCT0qnbLnovpie/WEmqyJ7T4n6VXiFMBtcw=
+go.lsp.dev/protocol v0.12.0/go.mod h1:Qb11/HgZQ72qQbeyPfJbu3hZBH23s1sr4st8czGeDMQ=
+go.lsp.dev/uri v0.3.0/go.mod h1:P5sbO1IQR+qySTWOCnhnK7phBx+W3zbLqSMDJNTw88I=
+go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY=
+go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
+go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
+go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
+go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
+go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o=
+go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
+go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
+go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
+go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+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.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
+golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
+golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
+golang.org/x/exp v0.0.0-20250718183923-645b1fa84792/go.mod h1:A+z0yzpGtvnG90cToK5n2tu8UJVP2XUATh+r+sfOOOc=
+golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
+golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
+golang.org/x/exp/typeparams v0.0.0-20250620022241-b7579e27df2b/go.mod h1:LKZHyeOpPuZcMgxeHjJp4p5yvxrCX1xDvH10zYHhjjQ=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.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.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+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-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
+golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
+golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
+golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
+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-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
+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-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.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.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
+golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
+golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3/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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
+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-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
+golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
+golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=
+golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=
+golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
+golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
+golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
+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-20250728155136-f173205681a0/go.mod h1:8ytArBbtOy2xfht+y2fqKd5DRDJRUQhqbyEnQ4bDChs=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
+google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA=
+google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
+gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+helm.sh/helm/v3 v3.18.6/go.mod h1:L/dXDR2r539oPlFP1PJqKAC1CUgqHJDLkxKpDGrWnyg=
+honnef.co/go/tools v0.6.1/go.mod h1:3puzxxljPCe8RGJX7BIy1plGbxEOZni5mR2aXe3/uk4=
+k8s.io/api v0.33.3/go.mod h1:01Y/iLUjNBM3TAvypct7DIj0M0NIZc+PzAHCIo0CYGE=
+k8s.io/apiextensions-apiserver v0.33.3/go.mod h1:oROuctgo27mUsyp9+Obahos6CWcMISSAPzQ77CAQGz8=
+k8s.io/apimachinery v0.34.0-rc.1/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
+k8s.io/code-generator v0.33.3/go.mod h1:6Y02+HQJYgNphv9z3wJB5w+sjYDIEBQW7sh62PkufvA=
+k8s.io/gengo/v2 v2.0.0-20250604051438-85fd79dbfd9f/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU=
+k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
+k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts=
+k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+mvdan.cc/gofumpt v0.8.0/go.mod h1:vEYnSzyGPmjvFkqJWtXkh79UwPWP9/HMxQdGEXZHjpg=
+mvdan.cc/unparam v0.0.0-20250301125049-0df0534333a4/go.mod h1:rthT7OuvRbaGcd5ginj6dA2oLE7YNlta9qhBNNdCaLE=
+pluginrpc.com/pluginrpc v0.5.0/go.mod h1:UNWZ941hcVAoOZUn8YZsMmOZBzbUjQa3XMns8RQLp9o=
+sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20250819114936-e4f9a2446c3d/go.mod h1:f9/k6JI1T3ROlGzlrAEnIFMXypFWgx5p1zYgFAEIfYE=
+sigs.k8s.io/controller-tools v0.18.0/go.mod h1:gLKoiGBriyNh+x1rWtUQnakUYEujErjXs9pf+x/8n1U=
+sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
+sigs.k8s.io/kind v0.29.0/go.mod h1:ldWQisw2NYyM6k64o/tkZng/1qQW7OlzcN5a8geJX3o=
+sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
+sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
+sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
diff --git a/tools/make/kube.mk b/tools/make/kube.mk
index 2cd3aacd5a..b80919f706 100644
--- a/tools/make/kube.mk
+++ b/tools/make/kube.mk
@@ -318,7 +318,10 @@ run-experimental-conformance: prepare-ip-family ## Run Experimental Gateway API
@$(LOG_TARGET)
kubectl wait --timeout=$(WAIT_TIMEOUT) -n envoy-gateway-system deployment/envoy-gateway --for=condition=Available
kubectl apply -f test/config/gatewayclass.yaml
- go test -v -tags experimental ./test/conformance -run TestExperimentalConformance --gateway-class=envoy-gateway --debug=true --organization=envoyproxy --project=envoy-gateway --url=https://github.com/envoyproxy/gateway --version=latest --report-output="$(CONFORMANCE_REPORT_PATH)" --contact=https://github.com/envoyproxy/gateway/blob/main/GOVERNANCE.md
+ go test -v -tags experimental ./test/conformance -run TestExperimentalConformance --gateway-class=envoy-gateway --debug=true \
+ --organization=envoyproxy --project=envoy-gateway --url=https://github.com/envoyproxy/gateway --version=latest \
+ --report-output="$(CONFORMANCE_REPORT_PATH)" --contact=https://github.com/envoyproxy/gateway/blob/main/GOVERNANCE.md \
+ --mode="$(KUBE_DEPLOY_PROFILE)" --version=$(TAG)
.PHONY: delete-cluster
delete-cluster: ## Delete kind cluster.