diff --git a/api/v1alpha1/accesslogging_types.go b/api/v1alpha1/accesslogging_types.go index 24272564488..78b78a485d6 100644 --- a/api/v1alpha1/accesslogging_types.go +++ b/api/v1alpha1/accesslogging_types.go @@ -123,15 +123,13 @@ const ( // - `x-accesslog-attr` - JSON encoded key/value pairs when a JSON format is used. // // +kubebuilder:validation:XValidation:rule="self.type == 'HTTP' || !has(self.http)",message="The http field may only be set when type is HTTP." +// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)" +// +kubebuilder:validation:XValidation:message="must have at least one backend in backendRefs",rule="has(self.backendRefs) && self.backendRefs.size() > 0" +// +kubebuilder:validation:XValidation:message="BackendRefs only supports Service kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service') : true" +// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\")) : true" type ALSEnvoyProxyAccessLog struct { - // BackendRefs references a Kubernetes object that represents the gRPC service to which - // the access logs will be sent. Currently only Service is supported. - // - // +kubebuilder:validation:MinItems=1 - // +kubebuilder:validation:MaxItems=1 - // +kubebuilder:validation:XValidation:message="BackendRefs only supports Service kind.",rule="self.all(f, f.kind == 'Service')" - // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')" - BackendRefs []BackendRef `json:"backendRefs"` + BackendCluster `json:",inline"` + // LogName defines the friendly name of the access log to be returned in // StreamAccessLogsMessage.Identifier. This allows the access log server // to differentiate between different access logs coming from the same Envoy. @@ -167,7 +165,11 @@ type FileEnvoyProxyAccessLog struct { // OpenTelemetryEnvoyProxyAccessLog defines the OpenTelemetry access log sink. // // +kubebuilder:validation:XValidation:message="host or backendRefs needs to be set",rule="has(self.host) || self.backendRefs.size() > 0" +// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)" +// +kubebuilder:validation:XValidation:message="BackendRefs only supports Service kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service') : true" +// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\")) : true" type OpenTelemetryEnvoyProxyAccessLog struct { + BackendCluster `json:",inline"` // Host define the extension service hostname. // Deprecated: Use BackendRefs instead. // @@ -180,15 +182,6 @@ type OpenTelemetryEnvoyProxyAccessLog struct { // +kubebuilder:validation:Minimum=0 // +kubebuilder:default=4317 Port int32 `json:"port,omitempty"` - // BackendRefs references a Kubernetes object that represents the - // backend server to which the access log will be sent. - // Only Service kind is supported for now. - // - // +optional - // +kubebuilder:validation:MaxItems=1 - // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')" - // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')" - BackendRefs []BackendRef `json:"backendRefs,omitempty"` // Resources is a set of labels that describe the source of a log entry, including envoy node info. // It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). // +optional diff --git a/api/v1alpha1/backendtrafficpolicy_types.go b/api/v1alpha1/backendtrafficpolicy_types.go index 80e4561507e..3f014b28285 100644 --- a/api/v1alpha1/backendtrafficpolicy_types.go +++ b/api/v1alpha1/backendtrafficpolicy_types.go @@ -46,12 +46,61 @@ type BackendTrafficPolicy struct { // BackendTrafficPolicySpec defines the desired state of BackendTrafficPolicy. type BackendTrafficPolicySpec struct { PolicyTargetReferences `json:",inline"` + ClusterSettings `json:",inline"` // RateLimit allows the user to limit the number of incoming requests // to a predefined value based on attributes within the traffic flow. // +optional RateLimit *RateLimitSpec `json:"rateLimit,omitempty"` + // FaultInjection defines the fault injection policy to be applied. This configuration can be used to + // inject delays and abort requests to mimic failure scenarios such as service failures and overloads + // +optional + FaultInjection *FaultInjection `json:"faultInjection,omitempty"` + + // Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions. + // If not set, retry will be disabled. + // +optional + Retry *Retry `json:"retry,omitempty"` + + // UseClientProtocol configures Envoy to prefer sending requests to backends using + // the same HTTP protocol that the incoming request used. Defaults to false, which means + // that Envoy will use the protocol indicated by the attached BackendRef. + // + // +optional + UseClientProtocol *bool `json:"useClientProtocol,omitempty"` + + // The compression config for the http streams. + // + // +optional + // +notImplementedHide + Compression []*Compression `json:"compression,omitempty"` +} + +// +kubebuilder:object:root=true + +// BackendTrafficPolicyList contains a list of BackendTrafficPolicy resources. +type BackendTrafficPolicyList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []BackendTrafficPolicy `json:"items"` +} + +// BackendTrafficPolicyConnection allows users to configure connection-level settings of backend +type BackendTrafficPolicyConnection struct { + // BufferLimit Soft limit on size of the cluster’s connections read and write buffers. + // If unspecified, an implementation defined default is applied (32768 bytes). + // For example, 20Mi, 1Gi, 256Ki etc. + // Note: that when the suffix is not provided, the value is interpreted as bytes. + // + // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="BufferLimit must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"" + // +optional + BufferLimit *resource.Quantity `json:"bufferLimit,omitempty"` +} + +// ClusterSettings provides the various knobs that can be set to control how traffic to a given +// backend will be configured. +type ClusterSettings struct { // LoadBalancer policy to apply when routing traffic from the gateway to // the backend endpoints // +optional @@ -72,44 +121,22 @@ type BackendTrafficPolicySpec struct { // +optional HealthCheck *HealthCheck `json:"healthCheck,omitempty"` - // FaultInjection defines the fault injection policy to be applied. This configuration can be used to - // inject delays and abort requests to mimic failure scenarios such as service failures and overloads - // +optional - FaultInjection *FaultInjection `json:"faultInjection,omitempty"` - // Circuit Breaker settings for the upstream connections and requests. // If not set, circuit breakers will be enabled with the default thresholds // // +optional CircuitBreaker *CircuitBreaker `json:"circuitBreaker,omitempty"` - // Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions. - // If not set, retry will be disabled. - // +optional - Retry *Retry `json:"retry,omitempty"` - - // UseClientProtocol configures Envoy to prefer sending requests to backends using - // the same HTTP protocol that the incoming request used. Defaults to false, which means - // that Envoy will use the protocol indicated by the attached BackendRef. - // - // +optional - UseClientProtocol *bool `json:"useClientProtocol,omitempty"` - // Timeout settings for the backend connections. // // +optional Timeout *Timeout `json:"timeout,omitempty"` - // The compression config for the http streams. - // - // +optional - // +notImplementedHide - Compression []*Compression `json:"compression,omitempty"` - // Connection includes backend connection settings. // // +optional Connection *BackendConnection `json:"connection,omitempty"` + // DNS includes dns resolution settings. // // +optional @@ -121,27 +148,6 @@ type BackendTrafficPolicySpec struct { HTTP2 *HTTP2Settings `json:"http2,omitempty"` } -// +kubebuilder:object:root=true - -// BackendTrafficPolicyList contains a list of BackendTrafficPolicy resources. -type BackendTrafficPolicyList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - Items []BackendTrafficPolicy `json:"items"` -} - -// BackendTrafficPolicyConnection allows users to configure connection-level settings of backend -type BackendTrafficPolicyConnection struct { - // BufferLimit Soft limit on size of the cluster’s connections read and write buffers. - // If unspecified, an implementation defined default is applied (32768 bytes). - // For example, 20Mi, 1Gi, 256Ki etc. - // Note: that when the suffix is not provided, the value is interpreted as bytes. - // - // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="BufferLimit must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"" - // +optional - BufferLimit *resource.Quantity `json:"bufferLimit,omitempty"` -} - func init() { SchemeBuilder.Register(&BackendTrafficPolicy{}, &BackendTrafficPolicyList{}) } diff --git a/api/v1alpha1/connection_types.go b/api/v1alpha1/connection_types.go index ff24c8edd4d..6f27794748b 100644 --- a/api/v1alpha1/connection_types.go +++ b/api/v1alpha1/connection_types.go @@ -22,7 +22,8 @@ type ClientConnection struct { // Note that when the suffix is not provided, the value is interpreted as bytes. // Default: 32768 bytes. // - // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="bufferLimit must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"" + // +kubebuilder:validation:XIntOrString + // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" // +optional BufferLimit *resource.Quantity `json:"bufferLimit,omitempty"` // SocketBufferLimit provides configuration for the maximum buffer size in bytes for each incoming socket. @@ -30,7 +31,8 @@ type ClientConnection struct { // For example, 20Mi, 1Gi, 256Ki etc. // Note that when the suffix is not provided, the value is interpreted as bytes. // - // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="socketBufferLimit must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"" + // +kubebuilder:validation:XIntOrString + // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" // +optional // +notImplementedHide SocketBufferLimit *resource.Quantity `json:"socketBufferLimit,omitempty"` @@ -44,7 +46,8 @@ type BackendConnection struct { // For example, 20Mi, 1Gi, 256Ki etc. // Note: that when the suffix is not provided, the value is interpreted as bytes. // - // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="BufferLimit must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"" + // +kubebuilder:validation:XIntOrString + // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" // +optional BufferLimit *resource.Quantity `json:"bufferLimit,omitempty"` // SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket @@ -53,7 +56,8 @@ type BackendConnection struct { // For example, 20Mi, 1Gi, 256Ki etc. // Note that when the suffix is not provided, the value is interpreted as bytes. // - // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="socketBufferLimit must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"" + // +kubebuilder:validation:XIntOrString + // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" // +optional // +notImplementedHide SocketBufferLimit *resource.Quantity `json:"socketBufferLimit,omitempty"` diff --git a/api/v1alpha1/envoyproxy_metric_types.go b/api/v1alpha1/envoyproxy_metric_types.go index 8791ddbd490..0e571ef23c9 100644 --- a/api/v1alpha1/envoyproxy_metric_types.go +++ b/api/v1alpha1/envoyproxy_metric_types.go @@ -15,6 +15,7 @@ type ProxyMetrics struct { // Prometheus defines the configuration for Admin endpoint `/stats/prometheus`. Prometheus *ProxyPrometheusProvider `json:"prometheus,omitempty"` // Sinks defines the metric sinks where metrics are sent to. + // +kubebuilder:validation:MaxItems=16 Sinks []ProxyMetricSink `json:"sinks,omitempty"` // Matches defines configuration for selecting specific metrics instead of generating all metrics stats // that are enabled by default. This helps reduce CPU and memory overhead in Envoy, but eliminating some stats @@ -54,7 +55,11 @@ type ProxyMetricSink struct { // ProxyOpenTelemetrySink defines the configuration for OpenTelemetry sink. // // +kubebuilder:validation:XValidation:message="host or backendRefs needs to be set",rule="has(self.host) || self.backendRefs.size() > 0" +// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)" +// +kubebuilder:validation:XValidation:message="only supports Service kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service') : true" +// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\")) : true" type ProxyOpenTelemetrySink struct { + BackendCluster `json:",inline"` // Host define the service hostname. // Deprecated: Use BackendRefs instead. // @@ -68,15 +73,6 @@ type ProxyOpenTelemetrySink struct { // +kubebuilder:validation:Maximum=65535 // +kubebuilder:default=4317 Port int32 `json:"port,omitempty"` - // BackendRefs references a Kubernetes object that represents the - // backend server to which the metric will be sent. - // Only Service kind is supported for now. - // - // +optional - // +kubebuilder:validation:MaxItems=1 - // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')" - // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')" - BackendRefs []BackendRef `json:"backendRefs,omitempty"` // TODO: add support for customizing OpenTelemetry sink in https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/stat_sinks/open_telemetry/v3/open_telemetry.proto#envoy-v3-api-msg-extensions-stat-sinks-open-telemetry-v3-sinkconfig } diff --git a/api/v1alpha1/envoyproxy_types.go b/api/v1alpha1/envoyproxy_types.go index 910c6d1503a..e2ada31c3fc 100644 --- a/api/v1alpha1/envoyproxy_types.go +++ b/api/v1alpha1/envoyproxy_types.go @@ -112,6 +112,8 @@ type EnvoyProxySpec struct { // // - envoy.filters.http.jwt_authn // + // - envoy.filters.http.stateful_session + // // - envoy.filters.http.ext_proc // // - envoy.filters.http.wasm @@ -172,7 +174,7 @@ type FilterPosition struct { } // EnvoyFilter defines the type of Envoy HTTP filter. -// +kubebuilder:validation:Enum=envoy.filters.http.health_check;envoy.filters.http.fault;envoy.filters.http.cors;envoy.filters.http.ext_authz;envoy.filters.http.basic_auth;envoy.filters.http.oauth2;envoy.filters.http.jwt_authn;envoy.filters.http.ext_proc;envoy.filters.http.wasm;envoy.filters.http.rbac;envoy.filters.http.local_ratelimit;envoy.filters.http.ratelimit +// +kubebuilder:validation:Enum=envoy.filters.http.health_check;envoy.filters.http.fault;envoy.filters.http.cors;envoy.filters.http.ext_authz;envoy.filters.http.basic_auth;envoy.filters.http.oauth2;envoy.filters.http.jwt_authn;envoy.filters.http.stateful_session;envoy.filters.http.ext_proc;envoy.filters.http.wasm;envoy.filters.http.rbac;envoy.filters.http.local_ratelimit;envoy.filters.http.ratelimit type EnvoyFilter string const ( @@ -197,6 +199,9 @@ const ( // EnvoyFilterJWTAuthn defines the Envoy HTTP JWT authentication filter. EnvoyFilterJWTAuthn EnvoyFilter = "envoy.filters.http.jwt_authn" + // EnvoyFilterSessionPersistence defines the Envoy HTTP session persistence filter. + EnvoyFilterSessionPersistence EnvoyFilter = "envoy.filters.http.stateful_session" + // EnvoyFilterExtProc defines the Envoy HTTP external process filter. EnvoyFilterExtProc EnvoyFilter = "envoy.filters.http.ext_proc" diff --git a/api/v1alpha1/ext_auth_types.go b/api/v1alpha1/ext_auth_types.go index 13de5f9f6ac..2ecb8674aad 100644 --- a/api/v1alpha1/ext_auth_types.go +++ b/api/v1alpha1/ext_auth_types.go @@ -5,18 +5,10 @@ package v1alpha1 -import ( - gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" -) - // ExtAuth defines the configuration for External Authorization. // // +kubebuilder:validation:XValidation:rule="(has(self.grpc) || has(self.http))",message="one of grpc or http must be specified" // +kubebuilder:validation:XValidation:rule="(has(self.grpc) && !has(self.http)) || (!has(self.grpc) && has(self.http))",message="only one of grpc or http can be specified" -// +kubebuilder:validation:XValidation:rule="has(self.grpc) ? (!has(self.grpc.backendRef) || !has(self.grpc.backendRef.group) || self.grpc.backendRef.group == \"\") : true", message="group is invalid, only the core API group (specified by omitting the group field or setting it to an empty string) is supported" -// +kubebuilder:validation:XValidation:rule="has(self.grpc) ? (!has(self.grpc.backendRef) || !has(self.grpc.backendRef.kind) || self.grpc.backendRef.kind == 'Service') : true", message="kind is invalid, only Service (specified by omitting the kind field or setting it to 'Service') is supported" -// +kubebuilder:validation:XValidation:rule="has(self.http) ? (!has(self.http.backendRef) || !has(self.http.backendRef.group) || self.http.backendRef.group == \"\") : true", message="group is invalid, only the core API group (specified by omitting the group field or setting it to an empty string) is supported" -// +kubebuilder:validation:XValidation:rule="has(self.http) ? (!has(self.http.backendRef) || !has(self.http.backendRef.kind) || self.http.backendRef.kind == 'Service') : true", message="kind is invalid, only Service (specified by omitting the kind field or setting it to 'Service') is supported" type ExtAuth struct { // GRPC defines the gRPC External Authorization service. // Either GRPCService or HTTPService must be specified, @@ -56,45 +48,25 @@ type ExtAuth struct { // The authorization request message is defined in // https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto // +kubebuilder:validation:XValidation:message="backendRef or backendRefs needs to be set",rule="has(self.backendRef) || self.backendRefs.size() > 0" +// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)" +// +kubebuilder:validation:XValidation:message="Exactly one backendRef can be specified in backendRefs.",rule="has(self.backendRefs) && self.backendRefs.size()==1" +// +kubebuilder:validation:XValidation:message="BackendRefs only supports Service and Backend kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service' || f.kind == 'Backend') : true" +// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core and gateway.envoyproxy.io group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\" || f.group == 'gateway.envoyproxy.io')) : true" type GRPCExtAuthService struct { - // BackendRef references a Kubernetes object that represents the - // backend server to which the authorization request will be sent. - // Only Service kind is supported for now. - // - // Deprecated: Use BackendRefs instead. - BackendRef *gwapiv1.BackendObjectReference `json:"backendRef,omitempty"` - - // BackendRefs references a Kubernetes object that represents the - // backend server to which the authorization request will be sent. // Only Service kind is supported for now. - // - // +optional - // +kubebuilder:validation:MaxItems=1 - // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')" - // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')" - BackendRefs []BackendRef `json:"backendRefs,omitempty"` + BackendCluster `json:",inline"` } // HTTPExtAuthService defines the HTTP External Authorization service // // +kubebuilder:validation:XValidation:message="backendRef or backendRefs needs to be set",rule="has(self.backendRef) || self.backendRefs.size() > 0" +// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)" +// +kubebuilder:validation:XValidation:message="Exactly one backendRef can be specified in backendRefs.",rule="has(self.backendRefs) && self.backendRefs.size()==1" +// +kubebuilder:validation:XValidation:message="BackendRefs only supports Service and Backend kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service' || f.kind == 'Backend') : true" +// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core and gateway.envoyproxy.io group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\" || f.group == 'gateway.envoyproxy.io')) : true" type HTTPExtAuthService struct { - // BackendRef references a Kubernetes object that represents the - // backend server to which the authorization request will be sent. // Only Service kind is supported for now. - // - // Deprecated: Use BackendRefs instead. - BackendRef *gwapiv1.BackendObjectReference `json:"backendRef,omitempty"` - - // BackendRefs references a Kubernetes object that represents the - // backend server to which the authorization request will be sent. - // Only Service kind is supported for now. - // - // +optional - // +kubebuilder:validation:MaxItems=1 - // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')" - // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')" - BackendRefs []BackendRef `json:"backendRefs,omitempty"` + BackendCluster `json:",inline"` // Path is the path of the HTTP External Authorization service. // If path is specified, the authorization request will be sent to that path, diff --git a/api/v1alpha1/ext_proc_types.go b/api/v1alpha1/ext_proc_types.go index 27be5e6318d..9f19d92b48f 100644 --- a/api/v1alpha1/ext_proc_types.go +++ b/api/v1alpha1/ext_proc_types.go @@ -46,14 +46,12 @@ type ExtProcProcessingMode struct { } // ExtProc defines the configuration for External Processing filter. +// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)" +// +kubebuilder:validation:XValidation:message="Exactly one backendRef can be specified in backendRefs.",rule="has(self.backendRefs) && self.backendRefs.size()==1" +// +kubebuilder:validation:XValidation:message="BackendRefs only supports Service and Backend kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service' || f.kind == 'Backend') : true" +// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core and gateway.envoyproxy.io group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\" || f.group == 'gateway.envoyproxy.io')) : true" type ExtProc struct { - // BackendRefs defines the configuration of the external processing service - // - // +kubebuilder:validation:MinItems=1 - // +kubebuilder:validation:MaxItems=1 - // +kubebuilder:validation:XValidation:message="BackendRefs only supports Service and Backend kind.",rule="self.all(f, f.kind == 'Service' || f.kind == 'Backend')" - // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core and gateway.envoyproxy.io group.",rule="self.all(f, f.group == '' || f.group == 'gateway.envoyproxy.io')" - BackendRefs []BackendRef `json:"backendRefs"` + BackendCluster `json:",inline"` // MessageTimeout is the timeout for a response to be returned from the external processor // Default: 200ms diff --git a/api/v1alpha1/shared_types.go b/api/v1alpha1/shared_types.go index c151fcd8b17..89aef19c37b 100644 --- a/api/v1alpha1/shared_types.go +++ b/api/v1alpha1/shared_types.go @@ -475,6 +475,30 @@ type BackendRef struct { gwapiv1.BackendObjectReference `json:",inline"` } +// BackendCluster contains all the configuration required for configuring access +// to a backend. This can include multiple endpoints, and settings that apply for +// managing the connection to all these endpoints. +type BackendCluster struct { + // BackendRef references a Kubernetes object that represents the + // backend server to which the authorization request will be sent. + // + // Deprecated: Use BackendRefs instead. + BackendRef *gwapiv1.BackendObjectReference `json:"backendRef,omitempty"` + + // BackendRefs references a Kubernetes object that represents the + // backend server to which the authorization request will be sent. + // + // +kubebuilder:validation:MaxItems=16 + // +optional + BackendRefs []BackendRef `json:"backendRefs,omitempty"` + + // BackendSettings holds configuration for managing the connection + // to the backend. + // + // +optional + BackendSettings *ClusterSettings `json:"backendSettings,omitempty"` +} + // CIDR defines a CIDR Address range. // A CIDR can be an IPv4 address range such as "192.168.1.0/24" or an IPv6 address range such as "2001:0db8:11a3:09d7::/64". // +kubebuilder:validation:Pattern=`((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/([0-9]+))|((([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/([0-9]+))` @@ -492,14 +516,16 @@ type HTTP2Settings struct { // InitialStreamWindowSize sets the initial window size for HTTP/2 streams. // If not set, the default value is 64 KiB(64*1024). // - // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="initialStreamWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"" + // +kubebuilder:validation:XIntOrString + // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" // +optional InitialStreamWindowSize *resource.Quantity `json:"initialStreamWindowSize,omitempty"` // InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. // If not set, the default value is 1 MiB. // - // +kubebuilder:validation:XValidation:rule="type(self) == string ? self.matches(r\"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\") : type(self) == int",message="initialConnectionWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"" + // +kubebuilder:validation:XIntOrString + // +kubebuilder:validation:Pattern="^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" // +optional InitialConnectionWindowSize *resource.Quantity `json:"initialConnectionWindowSize,omitempty"` diff --git a/api/v1alpha1/tracing_types.go b/api/v1alpha1/tracing_types.go index b7be478de15..55fd63ef4e9 100644 --- a/api/v1alpha1/tracing_types.go +++ b/api/v1alpha1/tracing_types.go @@ -31,7 +31,11 @@ const ( // TracingProvider defines the tracing provider configuration. // // +kubebuilder:validation:XValidation:message="host or backendRefs needs to be set",rule="has(self.host) || self.backendRefs.size() > 0" +// +kubebuilder:validation:XValidation:message="BackendRefs must be used, backendRef is not supported.",rule="!has(self.backendRef)" +// +kubebuilder:validation:XValidation:message="only supports Service kind.",rule="has(self.backendRefs) ? self.backendRefs.all(f, f.kind == 'Service') : true" +// +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="has(self.backendRefs) ? (self.backendRefs.all(f, f.group == \"\")) : true" type TracingProvider struct { + BackendCluster `json:",inline"` // Type defines the tracing provider type. // +kubebuilder:validation:Enum=OpenTelemetry;Zipkin // +kubebuilder:default=OpenTelemetry @@ -48,15 +52,6 @@ type TracingProvider struct { // +kubebuilder:validation:Minimum=0 // +kubebuilder:default=4317 Port int32 `json:"port,omitempty"` - // BackendRefs references a Kubernetes object that represents the - // backend server to which the trace will be sent. - // Only Service kind is supported for now. - // - // +optional - // +kubebuilder:validation:MaxItems=1 - // +kubebuilder:validation:XValidation:message="only support Service kind.",rule="self.all(f, f.kind == 'Service')" - // +kubebuilder:validation:XValidation:message="BackendRefs only supports Core group.",rule="self.all(f, f.group == '')" - BackendRefs []BackendRef `json:"backendRefs,omitempty"` // Zipkin defines the Zipkin tracing provider configuration // +optional Zipkin *ZipkinTracingProvider `json:"zipkin,omitempty"` diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index b5bac63fc50..ad72365802a 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -23,13 +23,7 @@ import ( // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ALSEnvoyProxyAccessLog) DeepCopyInto(out *ALSEnvoyProxyAccessLog) { *out = *in - if in.BackendRefs != nil { - in, out := &in.BackendRefs, &out.BackendRefs - *out = make([]BackendRef, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } + in.BackendCluster.DeepCopyInto(&out.BackendCluster) if in.LogName != nil { in, out := &in.LogName, &out.LogName *out = new(string) @@ -252,6 +246,38 @@ func (in *Backend) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BackendCluster) DeepCopyInto(out *BackendCluster) { + *out = *in + if in.BackendRef != nil { + in, out := &in.BackendRef, &out.BackendRef + *out = new(apisv1.BackendObjectReference) + (*in).DeepCopyInto(*out) + } + if in.BackendRefs != nil { + in, out := &in.BackendRefs, &out.BackendRefs + *out = make([]BackendRef, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.BackendSettings != nil { + in, out := &in.BackendSettings, &out.BackendSettings + *out = new(ClusterSettings) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendCluster. +func (in *BackendCluster) DeepCopy() *BackendCluster { + if in == nil { + return nil + } + out := new(BackendCluster) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BackendConnection) DeepCopyInto(out *BackendConnection) { *out = *in @@ -508,41 +534,17 @@ func (in *BackendTrafficPolicyList) DeepCopyObject() runtime.Object { func (in *BackendTrafficPolicySpec) DeepCopyInto(out *BackendTrafficPolicySpec) { *out = *in in.PolicyTargetReferences.DeepCopyInto(&out.PolicyTargetReferences) + in.ClusterSettings.DeepCopyInto(&out.ClusterSettings) if in.RateLimit != nil { in, out := &in.RateLimit, &out.RateLimit *out = new(RateLimitSpec) (*in).DeepCopyInto(*out) } - if in.LoadBalancer != nil { - in, out := &in.LoadBalancer, &out.LoadBalancer - *out = new(LoadBalancer) - (*in).DeepCopyInto(*out) - } - if in.ProxyProtocol != nil { - in, out := &in.ProxyProtocol, &out.ProxyProtocol - *out = new(ProxyProtocol) - **out = **in - } - if in.TCPKeepalive != nil { - in, out := &in.TCPKeepalive, &out.TCPKeepalive - *out = new(TCPKeepalive) - (*in).DeepCopyInto(*out) - } - if in.HealthCheck != nil { - in, out := &in.HealthCheck, &out.HealthCheck - *out = new(HealthCheck) - (*in).DeepCopyInto(*out) - } if in.FaultInjection != nil { in, out := &in.FaultInjection, &out.FaultInjection *out = new(FaultInjection) (*in).DeepCopyInto(*out) } - if in.CircuitBreaker != nil { - in, out := &in.CircuitBreaker, &out.CircuitBreaker - *out = new(CircuitBreaker) - (*in).DeepCopyInto(*out) - } if in.Retry != nil { in, out := &in.Retry, &out.Retry *out = new(Retry) @@ -553,11 +555,6 @@ func (in *BackendTrafficPolicySpec) DeepCopyInto(out *BackendTrafficPolicySpec) *out = new(bool) **out = **in } - if in.Timeout != nil { - in, out := &in.Timeout, &out.Timeout - *out = new(Timeout) - (*in).DeepCopyInto(*out) - } if in.Compression != nil { in, out := &in.Compression, &out.Compression *out = make([]*Compression, len(*in)) @@ -569,21 +566,6 @@ func (in *BackendTrafficPolicySpec) DeepCopyInto(out *BackendTrafficPolicySpec) } } } - if in.Connection != nil { - in, out := &in.Connection, &out.Connection - *out = new(BackendConnection) - (*in).DeepCopyInto(*out) - } - if in.DNS != nil { - in, out := &in.DNS, &out.DNS - *out = new(DNS) - (*in).DeepCopyInto(*out) - } - if in.HTTP2 != nil { - in, out := &in.HTTP2, &out.HTTP2 - *out = new(HTTP2Settings) - (*in).DeepCopyInto(*out) - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendTrafficPolicySpec. @@ -970,6 +952,66 @@ func (in *ClientValidationContext) DeepCopy() *ClientValidationContext { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterSettings) DeepCopyInto(out *ClusterSettings) { + *out = *in + if in.LoadBalancer != nil { + in, out := &in.LoadBalancer, &out.LoadBalancer + *out = new(LoadBalancer) + (*in).DeepCopyInto(*out) + } + if in.ProxyProtocol != nil { + in, out := &in.ProxyProtocol, &out.ProxyProtocol + *out = new(ProxyProtocol) + **out = **in + } + if in.TCPKeepalive != nil { + in, out := &in.TCPKeepalive, &out.TCPKeepalive + *out = new(TCPKeepalive) + (*in).DeepCopyInto(*out) + } + if in.HealthCheck != nil { + in, out := &in.HealthCheck, &out.HealthCheck + *out = new(HealthCheck) + (*in).DeepCopyInto(*out) + } + if in.CircuitBreaker != nil { + in, out := &in.CircuitBreaker, &out.CircuitBreaker + *out = new(CircuitBreaker) + (*in).DeepCopyInto(*out) + } + if in.Timeout != nil { + in, out := &in.Timeout, &out.Timeout + *out = new(Timeout) + (*in).DeepCopyInto(*out) + } + if in.Connection != nil { + in, out := &in.Connection, &out.Connection + *out = new(BackendConnection) + (*in).DeepCopyInto(*out) + } + if in.DNS != nil { + in, out := &in.DNS, &out.DNS + *out = new(DNS) + (*in).DeepCopyInto(*out) + } + if in.HTTP2 != nil { + in, out := &in.HTTP2, &out.HTTP2 + *out = new(HTTP2Settings) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSettings. +func (in *ClusterSettings) DeepCopy() *ClusterSettings { + if in == nil { + return nil + } + out := new(ClusterSettings) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Compression) DeepCopyInto(out *Compression) { *out = *in @@ -2000,13 +2042,7 @@ func (in *ExtAuth) DeepCopy() *ExtAuth { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ExtProc) DeepCopyInto(out *ExtProc) { *out = *in - if in.BackendRefs != nil { - in, out := &in.BackendRefs, &out.BackendRefs - *out = make([]BackendRef, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } + in.BackendCluster.DeepCopyInto(&out.BackendCluster) if in.MessageTimeout != nil { in, out := &in.MessageTimeout, &out.MessageTimeout *out = new(apisv1.Duration) @@ -2304,18 +2340,7 @@ func (in *FilterPosition) DeepCopy() *FilterPosition { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GRPCExtAuthService) DeepCopyInto(out *GRPCExtAuthService) { *out = *in - if in.BackendRef != nil { - in, out := &in.BackendRef, &out.BackendRef - *out = new(apisv1.BackendObjectReference) - (*in).DeepCopyInto(*out) - } - if in.BackendRefs != nil { - in, out := &in.BackendRefs, &out.BackendRefs - *out = make([]BackendRef, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } + in.BackendCluster.DeepCopyInto(&out.BackendCluster) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCExtAuthService. @@ -2553,18 +2578,7 @@ func (in *HTTPClientTimeout) DeepCopy() *HTTPClientTimeout { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTPExtAuthService) DeepCopyInto(out *HTTPExtAuthService) { *out = *in - if in.BackendRef != nil { - in, out := &in.BackendRef, &out.BackendRef - *out = new(apisv1.BackendObjectReference) - (*in).DeepCopyInto(*out) - } - if in.BackendRefs != nil { - in, out := &in.BackendRefs, &out.BackendRefs - *out = make([]BackendRef, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } + in.BackendCluster.DeepCopyInto(&out.BackendCluster) if in.Path != nil { in, out := &in.Path, &out.Path *out = new(string) @@ -3532,18 +3546,12 @@ func (in *OIDCProvider) DeepCopy() *OIDCProvider { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OpenTelemetryEnvoyProxyAccessLog) DeepCopyInto(out *OpenTelemetryEnvoyProxyAccessLog) { *out = *in + in.BackendCluster.DeepCopyInto(&out.BackendCluster) if in.Host != nil { in, out := &in.Host, &out.Host *out = new(string) **out = **in } - if in.BackendRefs != nil { - in, out := &in.BackendRefs, &out.BackendRefs - *out = make([]BackendRef, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } if in.Resources != nil { in, out := &in.Resources, &out.Resources *out = make(map[string]string, len(*in)) @@ -3947,18 +3955,12 @@ func (in *ProxyMetrics) DeepCopy() *ProxyMetrics { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ProxyOpenTelemetrySink) DeepCopyInto(out *ProxyOpenTelemetrySink) { *out = *in + in.BackendCluster.DeepCopyInto(&out.BackendCluster) if in.Host != nil { in, out := &in.Host, &out.Host *out = new(string) **out = **in } - if in.BackendRefs != nil { - in, out := &in.BackendRefs, &out.BackendRefs - *out = make([]BackendRef, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyOpenTelemetrySink. @@ -4840,18 +4842,12 @@ func (in *Timeout) DeepCopy() *Timeout { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TracingProvider) DeepCopyInto(out *TracingProvider) { *out = *in + in.BackendCluster.DeepCopyInto(&out.BackendCluster) if in.Host != nil { in, out := &in.Host, &out.Host *out = new(string) **out = **in } - if in.BackendRefs != nil { - in, out := &in.BackendRefs, &out.BackendRefs - *out = make([]BackendRef, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } if in.Zipkin != nil { in, out := &in.Zipkin, &out.Zipkin *out = new(ZipkinTracingProvider) diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml index d94bd0fa0d3..daf4175fc3b 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -123,6 +123,9 @@ spec: description: Connection includes backend connection settings. properties: bufferLimit: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ anyOf: - type: integer - type: string @@ -132,13 +135,11 @@ spec: If unspecified, an implementation defined default is applied (32768 bytes). For example, 20Mi, 1Gi, 256Ki etc. Note: that when the suffix is not provided, the value is interpreted as bytes. - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - x-kubernetes-validations: - - message: BufferLimit must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" - rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$") - : type(self) == int' socketBufferLimit: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ anyOf: - type: integer - type: string @@ -148,12 +149,7 @@ spec: SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space. For example, 20Mi, 1Gi, 256Ki etc. Note that when the suffix is not provided, the value is interpreted as bytes. - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - x-kubernetes-validations: - - message: socketBufferLimit must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" - rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$") - : type(self) == int' type: object dns: description: DNS includes dns resolution settings. @@ -457,31 +453,27 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: initialConnectionWindowSize: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ anyOf: - type: integer - type: string description: |- InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. If not set, the default value is 1 MiB. - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - x-kubernetes-validations: - - message: initialConnectionWindowSize must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" - rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$") - : type(self) == int' initialStreamWindowSize: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ anyOf: - type: integer - type: string description: |- InitialStreamWindowSize sets the initial window size for HTTP/2 streams. If not set, the default value is 64 KiB(64*1024). - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - x-kubernetes-validations: - - message: initialStreamWindowSize must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" - rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$") - : type(self) == int' maxConcurrentStreams: description: |- MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml index 43443bf28cc..0dd5ac6a980 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml @@ -98,6 +98,9 @@ spec: description: Connection includes client connection settings. properties: bufferLimit: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ anyOf: - type: integer - type: string @@ -107,12 +110,7 @@ spec: For example, 20Mi, 1Gi, 256Ki etc. Note that when the suffix is not provided, the value is interpreted as bytes. Default: 32768 bytes. - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - x-kubernetes-validations: - - message: bufferLimit must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" - rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$") - : type(self) == int' connectionLimit: description: ConnectionLimit defines limits related to connections properties: @@ -133,6 +131,9 @@ spec: type: integer type: object socketBufferLimit: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ anyOf: - type: integer - type: string @@ -141,12 +142,7 @@ spec: SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space. For example, 20Mi, 1Gi, 256Ki etc. Note that when the suffix is not provided, the value is interpreted as bytes. - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - x-kubernetes-validations: - - message: socketBufferLimit must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" - rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$") - : type(self) == int' type: object enableProxyProtocol: description: |- @@ -283,31 +279,27 @@ spec: description: HTTP2 provides HTTP/2 configuration on the listener. properties: initialConnectionWindowSize: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ anyOf: - type: integer - type: string description: |- InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. If not set, the default value is 1 MiB. - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - x-kubernetes-validations: - - message: initialConnectionWindowSize must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" - rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$") - : type(self) == int' initialStreamWindowSize: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ anyOf: - type: integer - type: string description: |- InitialStreamWindowSize sets the initial window size for HTTP/2 streams. If not set, the default value is 64 KiB(64*1024). - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true - x-kubernetes-validations: - - message: initialStreamWindowSize must be of the format "^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$" - rule: 'type(self) == string ? self.matches(r"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$") - : type(self) == int' maxConcurrentStreams: description: |- MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml index 61827ee1205..8712a6b13a2 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml @@ -54,9 +54,91 @@ spec: description: ExtProc defines the configuration for External Processing filter. properties: + backendRef: + description: |- + BackendRef references a Kubernetes object that represents the + backend server to which the authorization request will be sent. + + + Deprecated: Use BackendRefs instead. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind == ''Service'') + ? has(self.port) : true' backendRefs: - description: BackendRefs defines the configuration of the external - processing service + description: |- + BackendRefs references a Kubernetes object that represents the + backend server to which the authorization request will be sent. items: description: BackendRef defines how an ObjectReference that is specific to BackendRef. @@ -134,15 +216,588 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - maxItems: 1 - minItems: 1 + maxItems: 16 type: array - x-kubernetes-validations: - - message: BackendRefs only supports Service and Backend kind. - rule: self.all(f, f.kind == 'Service' || f.kind == 'Backend') - - message: BackendRefs only supports Core and gateway.envoyproxy.io - group. - rule: self.all(f, f.group == '' || f.group == 'gateway.envoyproxy.io') + backendSettings: + description: |- + BackendSettings holds configuration for managing the connection + to the backend. + properties: + circuitBreaker: + description: |- + Circuit Breaker settings for the upstream connections and requests. + If not set, circuit breakers will be enabled with the default thresholds + properties: + maxConnections: + default: 1024 + description: The maximum number of connections that + Envoy will establish to the referenced backend defined + within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxParallelRequests: + default: 1024 + description: The maximum number of parallel requests + that Envoy will make to the referenced backend defined + within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxParallelRetries: + default: 1024 + description: The maximum number of parallel retries + that Envoy will make to the referenced backend defined + within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxPendingRequests: + default: 1024 + description: The maximum number of pending requests + that Envoy will queue to the referenced backend defined + within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxRequestsPerConnection: + description: |- + The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule. + Default: unlimited. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + type: object + connection: + description: Connection includes backend connection settings. + properties: + bufferLimit: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + BufferLimit Soft limit on size of the cluster’s connections read and write buffers. + BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space. + If unspecified, an implementation defined default is applied (32768 bytes). + For example, 20Mi, 1Gi, 256Ki etc. + Note: that when the suffix is not provided, the value is interpreted as bytes. + x-kubernetes-int-or-string: true + socketBufferLimit: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket + to backend. + SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space. + For example, 20Mi, 1Gi, 256Ki etc. + Note that when the suffix is not provided, the value is interpreted as bytes. + x-kubernetes-int-or-string: true + type: object + dns: + description: DNS includes dns resolution settings. + properties: + dnsRefreshRate: + description: |- + DNSRefreshRate specifies the rate at which DNS records should be refreshed. + Defaults to 30 seconds. + type: string + respectDnsTtl: + description: |- + RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected. + If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL. + Defaults to true. + type: boolean + type: object + healthCheck: + description: HealthCheck allows gateway to perform active + health checking on backends. + properties: + active: + description: Active health check configuration + properties: + healthyThreshold: + default: 1 + description: HealthyThreshold defines the number + of healthy health checks required before a backend + host is marked healthy. + format: int32 + minimum: 1 + type: integer + http: + description: |- + HTTP defines the configuration of http health checker. + It's required while the health checker type is HTTP. + properties: + expectedResponse: + description: ExpectedResponse defines a list + of HTTP expected responses to match. + properties: + binary: + description: Binary payload base64 encoded. + format: byte + type: string + text: + description: Text payload in plain text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines the type of the + payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type is Text, text field + needs to be set. + rule: 'self.type == ''Text'' ? has(self.text) + : !has(self.text)' + - message: If payload type is Binary, binary + field needs to be set. + rule: 'self.type == ''Binary'' ? has(self.binary) + : !has(self.binary)' + expectedStatuses: + description: |- + ExpectedStatuses defines a list of HTTP response statuses considered healthy. + Defaults to 200 only + items: + description: HTTPStatus defines the http status + code. + exclusiveMaximum: true + maximum: 600 + minimum: 100 + type: integer + type: array + method: + description: |- + Method defines the HTTP method used for health checking. + Defaults to GET + type: string + path: + description: Path defines the HTTP path that + will be requested during health checking. + maxLength: 1024 + minLength: 1 + type: string + required: + - path + type: object + interval: + default: 3s + description: Interval defines the time between active + health checks. + format: duration + type: string + tcp: + description: |- + TCP defines the configuration of tcp health checker. + It's required while the health checker type is TCP. + properties: + receive: + description: Receive defines the expected response + payload. + properties: + binary: + description: Binary payload base64 encoded. + format: byte + type: string + text: + description: Text payload in plain text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines the type of the + payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type is Text, text field + needs to be set. + rule: 'self.type == ''Text'' ? has(self.text) + : !has(self.text)' + - message: If payload type is Binary, binary + field needs to be set. + rule: 'self.type == ''Binary'' ? has(self.binary) + : !has(self.binary)' + send: + description: Send defines the request payload. + properties: + binary: + description: Binary payload base64 encoded. + format: byte + type: string + text: + description: Text payload in plain text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines the type of the + payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type is Text, text field + needs to be set. + rule: 'self.type == ''Text'' ? has(self.text) + : !has(self.text)' + - message: If payload type is Binary, binary + field needs to be set. + rule: 'self.type == ''Binary'' ? has(self.binary) + : !has(self.binary)' + type: object + timeout: + default: 1s + description: Timeout defines the time to wait for + a health check response. + format: duration + type: string + type: + allOf: + - enum: + - HTTP + - TCP + - enum: + - HTTP + - TCP + description: Type defines the type of health checker. + type: string + unhealthyThreshold: + default: 3 + description: UnhealthyThreshold defines the number + of unhealthy health checks required before a backend + host is marked unhealthy. + format: int32 + minimum: 1 + type: integer + required: + - type + type: object + x-kubernetes-validations: + - message: If Health Checker type is HTTP, http field + needs to be set. + rule: 'self.type == ''HTTP'' ? has(self.http) : !has(self.http)' + - message: If Health Checker type is TCP, tcp field + needs to be set. + rule: 'self.type == ''TCP'' ? has(self.tcp) : !has(self.tcp)' + passive: + description: Passive passive check configuration + properties: + baseEjectionTime: + default: 30s + description: BaseEjectionTime defines the base duration + for which a host will be ejected on consecutive + failures. + format: duration + type: string + consecutive5XxErrors: + default: 5 + description: Consecutive5xxErrors sets the number + of consecutive 5xx errors triggering ejection. + format: int32 + type: integer + consecutiveGatewayErrors: + default: 0 + description: ConsecutiveGatewayErrors sets the number + of consecutive gateway errors triggering ejection. + format: int32 + type: integer + consecutiveLocalOriginFailures: + default: 5 + description: |- + ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection. + Parameter takes effect only when split_external_local_origin_errors is set to true. + format: int32 + type: integer + interval: + default: 3s + description: Interval defines the time between passive + health checks. + format: duration + type: string + maxEjectionPercent: + default: 10 + description: MaxEjectionPercent sets the maximum + percentage of hosts in a cluster that can be ejected. + format: int32 + type: integer + splitExternalLocalOriginErrors: + default: false + description: SplitExternalLocalOriginErrors enables + splitting of errors between external and local + origin. + type: boolean + type: object + type: object + http2: + description: HTTP2 provides HTTP/2 configuration for backend + connections. + properties: + initialConnectionWindowSize: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. + If not set, the default value is 1 MiB. + x-kubernetes-int-or-string: true + initialStreamWindowSize: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + InitialStreamWindowSize sets the initial window size for HTTP/2 streams. + If not set, the default value is 64 KiB(64*1024). + x-kubernetes-int-or-string: true + maxConcurrentStreams: + description: |- + MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. + If not set, the default value is 100. + format: int32 + maximum: 2147483647 + minimum: 1 + type: integer + onInvalidMessage: + description: |- + OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error + It's recommended for L2 Envoy deployments to set this value to TerminateStream. + https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two + Default: TerminateConnection + type: string + type: object + loadBalancer: + description: |- + LoadBalancer policy to apply when routing traffic from the gateway to + the backend endpoints + properties: + consistentHash: + description: |- + ConsistentHash defines the configuration when the load balancer type is + set to ConsistentHash + properties: + cookie: + description: Cookie configures the cookie hash policy + when the consistent hash type is set to Cookie. + properties: + attributes: + additionalProperties: + type: string + description: Additional Attributes to set for + the generated cookie. + type: object + name: + description: |- + Name of the cookie to hash. + If this cookie does not exist in the request, Envoy will generate a cookie and set + the TTL on the response back to the client based on Layer 4 + attributes of the backend endpoint, to ensure that these future requests + go to the same backend endpoint. Make sure to set the TTL field for this case. + type: string + ttl: + description: |- + TTL of the generated cookie if the cookie is not present. This value sets the + Max-Age attribute value. + type: string + required: + - name + type: object + header: + description: Header configures the header hash policy + when the consistent hash type is set to Header. + properties: + name: + description: Name of the header to hash. + type: string + required: + - name + type: object + tableSize: + default: 65537 + description: The table size for consistent hashing, + must be prime number limited to 5000011. + format: int64 + maximum: 5000011 + minimum: 2 + type: integer + type: + description: |- + ConsistentHashType defines the type of input to hash on. Valid Type values are + "SourceIP", + "Header", + "Cookie". + enum: + - SourceIP + - Header + - Cookie + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If consistent hash type is header, the header + field must be set. + rule: 'self.type == ''Header'' ? has(self.header) + : !has(self.header)' + - message: If consistent hash type is cookie, the cookie + field must be set. + rule: 'self.type == ''Cookie'' ? has(self.cookie) + : !has(self.cookie)' + slowStart: + description: |- + SlowStart defines the configuration related to the slow start load balancer policy. + If set, during slow start window, traffic sent to the newly added hosts will gradually increase. + Currently this is only supported for RoundRobin and LeastRequest load balancers + properties: + window: + description: |- + Window defines the duration of the warm up period for newly added host. + During slow start window, traffic sent to the newly added hosts will gradually increase. + Currently only supports linear growth of traffic. For additional details, + see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig + type: string + required: + - window + type: object + type: + description: |- + Type decides the type of Load Balancer policy. + Valid LoadBalancerType values are + "ConsistentHash", + "LeastRequest", + "Random", + "RoundRobin". + enum: + - ConsistentHash + - LeastRequest + - Random + - RoundRobin + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If LoadBalancer type is consistentHash, consistentHash + field needs to be set. + rule: 'self.type == ''ConsistentHash'' ? has(self.consistentHash) + : !has(self.consistentHash)' + - message: Currently SlowStart is only supported for RoundRobin + and LeastRequest load balancers. + rule: 'self.type in [''Random'', ''ConsistentHash''] ? + !has(self.slowStart) : true ' + proxyProtocol: + description: ProxyProtocol enables the Proxy Protocol when + communicating with the backend. + properties: + version: + description: |- + Version of ProxyProtol + Valid ProxyProtocolVersion values are + "V1" + "V2" + enum: + - V1 + - V2 + type: string + required: + - version + type: object + tcpKeepalive: + description: |- + TcpKeepalive settings associated with the upstream client connection. + Disabled by default. + properties: + idleTime: + description: |- + The duration a connection needs to be idle before keep-alive + probes start being sent. + The duration format is + Defaults to `7200s`. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: |- + The duration between keep-alive probes. + Defaults to `75s`. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + probes: + description: |- + The total number of unacknowledged probes to send before deciding + the connection is dead. + Defaults to 9. + format: int32 + type: integer + type: object + timeout: + description: Timeout settings for the backend connections. + properties: + http: + description: Timeout settings for HTTP. + properties: + connectionIdleTimeout: + description: |- + The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection. + Default: 1 hour. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + maxConnectionDuration: + description: |- + The maximum duration of an HTTP connection. + Default: unlimited. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + tcp: + description: Timeout settings for TCP. + properties: + connectTimeout: + description: |- + The timeout for network connection establishment, including TCP and TLS handshakes. + Default: 10 seconds. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + type: object + type: object failOpen: description: |- FailOpen defines if requests or responses that cannot be processed due to connectivity to the @@ -187,9 +842,19 @@ spec: type: string type: object type: object - required: - - backendRefs type: object + x-kubernetes-validations: + - message: BackendRefs must be used, backendRef is not supported. + rule: '!has(self.backendRef)' + - message: Exactly one backendRef can be specified in backendRefs. + rule: has(self.backendRefs) && self.backendRefs.size()==1 + - message: BackendRefs only supports Service and Backend kind. + rule: 'has(self.backendRefs) ? self.backendRefs.all(f, f.kind + == ''Service'' || f.kind == ''Backend'') : true' + - message: BackendRefs only supports Core and gateway.envoyproxy.io + group. + rule: 'has(self.backendRefs) ? (self.backendRefs.all(f, f.group + == "" || f.group == ''gateway.envoyproxy.io'')) : true' maxItems: 16 type: array targetRef: diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml index 74438fea24c..874dc98d4a7 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml @@ -251,6 +251,9 @@ spec: - envoy.filters.http.jwt_authn + - envoy.filters.http.stateful_session + + - envoy.filters.http.ext_proc @@ -286,6 +289,7 @@ spec: - envoy.filters.http.basic_auth - envoy.filters.http.oauth2 - envoy.filters.http.jwt_authn + - envoy.filters.http.stateful_session - envoy.filters.http.ext_proc - envoy.filters.http.wasm - envoy.filters.http.rbac @@ -304,6 +308,7 @@ spec: - envoy.filters.http.basic_auth - envoy.filters.http.oauth2 - envoy.filters.http.jwt_authn + - envoy.filters.http.stateful_session - envoy.filters.http.ext_proc - envoy.filters.http.wasm - envoy.filters.http.rbac @@ -320,6 +325,7 @@ spec: - envoy.filters.http.basic_auth - envoy.filters.http.oauth2 - envoy.filters.http.jwt_authn + - envoy.filters.http.stateful_session - envoy.filters.http.ext_proc - envoy.filters.http.wasm - envoy.filters.http.rbac @@ -10303,10 +10309,91 @@ spec: description: ALS defines the gRPC Access Log Service (ALS) sink. properties: + backendRef: + description: |- + BackendRef references a Kubernetes object that represents the + backend server to which the authorization request will be sent. + + + Deprecated: Use BackendRefs instead. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind + == ''Service'') ? has(self.port) : true' backendRefs: description: |- - BackendRefs references a Kubernetes object that represents the gRPC service to which - the access logs will be sent. Currently only Service is supported. + BackendRefs references a Kubernetes object that represents the + backend server to which the authorization request will be sent. items: description: BackendRef defines how an ObjectReference that is specific to BackendRef. @@ -10385,16 +10472,642 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - maxItems: 1 - minItems: 1 + maxItems: 16 type: array - x-kubernetes-validations: - - message: BackendRefs only supports Service - kind. - rule: self.all(f, f.kind == 'Service') - - message: BackendRefs only supports Core - group. - rule: self.all(f, f.group == '') + backendSettings: + description: |- + BackendSettings holds configuration for managing the connection + to the backend. + properties: + circuitBreaker: + description: |- + Circuit Breaker settings for the upstream connections and requests. + If not set, circuit breakers will be enabled with the default thresholds + properties: + maxConnections: + default: 1024 + description: The maximum number of + connections that Envoy will establish + to the referenced backend defined + within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxParallelRequests: + default: 1024 + description: The maximum number of + parallel requests that Envoy will + make to the referenced backend defined + within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxParallelRetries: + default: 1024 + description: The maximum number of + parallel retries that Envoy will + make to the referenced backend defined + within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxPendingRequests: + default: 1024 + description: The maximum number of + pending requests that Envoy will + queue to the referenced backend + defined within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxRequestsPerConnection: + description: |- + The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule. + Default: unlimited. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + type: object + connection: + description: Connection includes backend + connection settings. + properties: + bufferLimit: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + BufferLimit Soft limit on size of the cluster’s connections read and write buffers. + BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space. + If unspecified, an implementation defined default is applied (32768 bytes). + For example, 20Mi, 1Gi, 256Ki etc. + Note: that when the suffix is not provided, the value is interpreted as bytes. + x-kubernetes-int-or-string: true + socketBufferLimit: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket + to backend. + SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space. + For example, 20Mi, 1Gi, 256Ki etc. + Note that when the suffix is not provided, the value is interpreted as bytes. + x-kubernetes-int-or-string: true + type: object + dns: + description: DNS includes dns resolution + settings. + properties: + dnsRefreshRate: + description: |- + DNSRefreshRate specifies the rate at which DNS records should be refreshed. + Defaults to 30 seconds. + type: string + respectDnsTtl: + description: |- + RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected. + If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL. + Defaults to true. + type: boolean + type: object + healthCheck: + description: HealthCheck allows gateway + to perform active health checking on + backends. + properties: + active: + description: Active health check configuration + properties: + healthyThreshold: + default: 1 + description: HealthyThreshold + defines the number of healthy + health checks required before + a backend host is marked healthy. + format: int32 + minimum: 1 + type: integer + http: + description: |- + HTTP defines the configuration of http health checker. + It's required while the health checker type is HTTP. + properties: + expectedResponse: + description: ExpectedResponse + defines a list of HTTP expected + responses to match. + properties: + binary: + description: Binary payload + base64 encoded. + format: byte + type: string + text: + description: Text payload + in plain text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines + the type of the payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type + is Text, text field needs + to be set. + rule: 'self.type == ''Text'' + ? has(self.text) : !has(self.text)' + - message: If payload type + is Binary, binary field + needs to be set. + rule: 'self.type == ''Binary'' + ? has(self.binary) : !has(self.binary)' + expectedStatuses: + description: |- + ExpectedStatuses defines a list of HTTP response statuses considered healthy. + Defaults to 200 only + items: + description: HTTPStatus + defines the http status + code. + exclusiveMaximum: true + maximum: 600 + minimum: 100 + type: integer + type: array + method: + description: |- + Method defines the HTTP method used for health checking. + Defaults to GET + type: string + path: + description: Path defines + the HTTP path that will + be requested during health + checking. + maxLength: 1024 + minLength: 1 + type: string + required: + - path + type: object + interval: + default: 3s + description: Interval defines + the time between active health + checks. + format: duration + type: string + tcp: + description: |- + TCP defines the configuration of tcp health checker. + It's required while the health checker type is TCP. + properties: + receive: + description: Receive defines + the expected response payload. + properties: + binary: + description: Binary payload + base64 encoded. + format: byte + type: string + text: + description: Text payload + in plain text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines + the type of the payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type + is Text, text field needs + to be set. + rule: 'self.type == ''Text'' + ? has(self.text) : !has(self.text)' + - message: If payload type + is Binary, binary field + needs to be set. + rule: 'self.type == ''Binary'' + ? has(self.binary) : !has(self.binary)' + send: + description: Send defines + the request payload. + properties: + binary: + description: Binary payload + base64 encoded. + format: byte + type: string + text: + description: Text payload + in plain text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines + the type of the payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type + is Text, text field needs + to be set. + rule: 'self.type == ''Text'' + ? has(self.text) : !has(self.text)' + - message: If payload type + is Binary, binary field + needs to be set. + rule: 'self.type == ''Binary'' + ? has(self.binary) : !has(self.binary)' + type: object + timeout: + default: 1s + description: Timeout defines the + time to wait for a health check + response. + format: duration + type: string + type: + allOf: + - enum: + - HTTP + - TCP + - enum: + - HTTP + - TCP + description: Type defines the + type of health checker. + type: string + unhealthyThreshold: + default: 3 + description: UnhealthyThreshold + defines the number of unhealthy + health checks required before + a backend host is marked unhealthy. + format: int32 + minimum: 1 + type: integer + required: + - type + type: object + x-kubernetes-validations: + - message: If Health Checker type + is HTTP, http field needs to be + set. + rule: 'self.type == ''HTTP'' ? has(self.http) + : !has(self.http)' + - message: If Health Checker type + is TCP, tcp field needs to be + set. + rule: 'self.type == ''TCP'' ? has(self.tcp) + : !has(self.tcp)' + passive: + description: Passive passive check + configuration + properties: + baseEjectionTime: + default: 30s + description: BaseEjectionTime + defines the base duration for + which a host will be ejected + on consecutive failures. + format: duration + type: string + consecutive5XxErrors: + default: 5 + description: Consecutive5xxErrors + sets the number of consecutive + 5xx errors triggering ejection. + format: int32 + type: integer + consecutiveGatewayErrors: + default: 0 + description: ConsecutiveGatewayErrors + sets the number of consecutive + gateway errors triggering ejection. + format: int32 + type: integer + consecutiveLocalOriginFailures: + default: 5 + description: |- + ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection. + Parameter takes effect only when split_external_local_origin_errors is set to true. + format: int32 + type: integer + interval: + default: 3s + description: Interval defines + the time between passive health + checks. + format: duration + type: string + maxEjectionPercent: + default: 10 + description: MaxEjectionPercent + sets the maximum percentage + of hosts in a cluster that can + be ejected. + format: int32 + type: integer + splitExternalLocalOriginErrors: + default: false + description: SplitExternalLocalOriginErrors + enables splitting of errors + between external and local origin. + type: boolean + type: object + type: object + http2: + description: HTTP2 provides HTTP/2 configuration + for backend connections. + properties: + initialConnectionWindowSize: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. + If not set, the default value is 1 MiB. + x-kubernetes-int-or-string: true + initialStreamWindowSize: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + InitialStreamWindowSize sets the initial window size for HTTP/2 streams. + If not set, the default value is 64 KiB(64*1024). + x-kubernetes-int-or-string: true + maxConcurrentStreams: + description: |- + MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. + If not set, the default value is 100. + format: int32 + maximum: 2147483647 + minimum: 1 + type: integer + onInvalidMessage: + description: |- + OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error + It's recommended for L2 Envoy deployments to set this value to TerminateStream. + https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two + Default: TerminateConnection + type: string + type: object + loadBalancer: + description: |- + LoadBalancer policy to apply when routing traffic from the gateway to + the backend endpoints + properties: + consistentHash: + description: |- + ConsistentHash defines the configuration when the load balancer type is + set to ConsistentHash + properties: + cookie: + description: Cookie configures + the cookie hash policy when + the consistent hash type is + set to Cookie. + properties: + attributes: + additionalProperties: + type: string + description: Additional Attributes + to set for the generated + cookie. + type: object + name: + description: |- + Name of the cookie to hash. + If this cookie does not exist in the request, Envoy will generate a cookie and set + the TTL on the response back to the client based on Layer 4 + attributes of the backend endpoint, to ensure that these future requests + go to the same backend endpoint. Make sure to set the TTL field for this case. + type: string + ttl: + description: |- + TTL of the generated cookie if the cookie is not present. This value sets the + Max-Age attribute value. + type: string + required: + - name + type: object + header: + description: Header configures + the header hash policy when + the consistent hash type is + set to Header. + properties: + name: + description: Name of the header + to hash. + type: string + required: + - name + type: object + tableSize: + default: 65537 + description: The table size for + consistent hashing, must be + prime number limited to 5000011. + format: int64 + maximum: 5000011 + minimum: 2 + type: integer + type: + description: |- + ConsistentHashType defines the type of input to hash on. Valid Type values are + "SourceIP", + "Header", + "Cookie". + enum: + - SourceIP + - Header + - Cookie + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If consistent hash type + is header, the header field must + be set. + rule: 'self.type == ''Header'' ? + has(self.header) : !has(self.header)' + - message: If consistent hash type + is cookie, the cookie field must + be set. + rule: 'self.type == ''Cookie'' ? + has(self.cookie) : !has(self.cookie)' + slowStart: + description: |- + SlowStart defines the configuration related to the slow start load balancer policy. + If set, during slow start window, traffic sent to the newly added hosts will gradually increase. + Currently this is only supported for RoundRobin and LeastRequest load balancers + properties: + window: + description: |- + Window defines the duration of the warm up period for newly added host. + During slow start window, traffic sent to the newly added hosts will gradually increase. + Currently only supports linear growth of traffic. For additional details, + see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig + type: string + required: + - window + type: object + type: + description: |- + Type decides the type of Load Balancer policy. + Valid LoadBalancerType values are + "ConsistentHash", + "LeastRequest", + "Random", + "RoundRobin". + enum: + - ConsistentHash + - LeastRequest + - Random + - RoundRobin + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If LoadBalancer type is consistentHash, + consistentHash field needs to be set. + rule: 'self.type == ''ConsistentHash'' + ? has(self.consistentHash) : !has(self.consistentHash)' + - message: Currently SlowStart is only + supported for RoundRobin and LeastRequest + load balancers. + rule: 'self.type in [''Random'', ''ConsistentHash''] + ? !has(self.slowStart) : true ' + proxyProtocol: + description: ProxyProtocol enables the + Proxy Protocol when communicating with + the backend. + properties: + version: + description: |- + Version of ProxyProtol + Valid ProxyProtocolVersion values are + "V1" + "V2" + enum: + - V1 + - V2 + type: string + required: + - version + type: object + tcpKeepalive: + description: |- + TcpKeepalive settings associated with the upstream client connection. + Disabled by default. + properties: + idleTime: + description: |- + The duration a connection needs to be idle before keep-alive + probes start being sent. + The duration format is + Defaults to `7200s`. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: |- + The duration between keep-alive probes. + Defaults to `75s`. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + probes: + description: |- + The total number of unacknowledged probes to send before deciding + the connection is dead. + Defaults to 9. + format: int32 + type: integer + type: object + timeout: + description: Timeout settings for the + backend connections. + properties: + http: + description: Timeout settings for + HTTP. + properties: + connectionIdleTimeout: + description: |- + The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection. + Default: 1 hour. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + maxConnectionDuration: + description: |- + The maximum duration of an HTTP connection. + Default: unlimited. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + tcp: + description: Timeout settings for + TCP. + properties: + connectTimeout: + description: |- + The timeout for network connection establishment, including TCP and TLS handshakes. + Default: 10 seconds. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + type: object + type: object http: description: HTTP defines additional configuration specific to HTTP access logs. @@ -10436,13 +11149,24 @@ spec: - TCP type: string required: - - backendRefs - type type: object x-kubernetes-validations: - message: The http field may only be set when type is HTTP. rule: self.type == 'HTTP' || !has(self.http) + - message: BackendRefs must be used, backendRef + is not supported. + rule: '!has(self.backendRef)' + - message: must have at least one backend in backendRefs + rule: has(self.backendRefs) && self.backendRefs.size() + > 0 + - message: BackendRefs only supports Service kind. + rule: 'has(self.backendRefs) ? self.backendRefs.all(f, + f.kind == ''Service'') : true' + - message: BackendRefs only supports Core group. + rule: 'has(self.backendRefs) ? (self.backendRefs.all(f, + f.group == "")) : true' file: description: File defines the file accesslog sink. properties: @@ -10456,11 +11180,91 @@ spec: description: OpenTelemetry defines the OpenTelemetry accesslog sink. properties: + backendRef: + description: |- + BackendRef references a Kubernetes object that represents the + backend server to which the authorization request will be sent. + + + Deprecated: Use BackendRefs instead. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind + == ''Service'') ? has(self.port) : true' backendRefs: description: |- BackendRefs references a Kubernetes object that represents the - backend server to which the access log will be sent. - Only Service kind is supported for now. + backend server to which the authorization request will be sent. items: description: BackendRef defines how an ObjectReference that is specific to BackendRef. @@ -10539,43 +11343,680 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - maxItems: 1 + maxItems: 16 type: array - x-kubernetes-validations: - - message: only support Service kind. - rule: self.all(f, f.kind == 'Service') - - message: BackendRefs only supports Core - group. - rule: self.all(f, f.group == '') - host: - description: |- - Host define the extension service hostname. - Deprecated: Use BackendRefs instead. - type: string - port: - default: 4317 - description: |- - Port defines the port the extension service is exposed on. - Deprecated: Use BackendRefs instead. - format: int32 - minimum: 0 - type: integer - resources: - additionalProperties: - type: string + backendSettings: description: |- - Resources is a set of labels that describe the source of a log entry, including envoy node info. - It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). - type: object - type: object - x-kubernetes-validations: - - message: host or backendRefs needs to be set - rule: has(self.host) || self.backendRefs.size() - > 0 - type: - description: Type defines the type of accesslog - sink. - enum: + BackendSettings holds configuration for managing the connection + to the backend. + properties: + circuitBreaker: + description: |- + Circuit Breaker settings for the upstream connections and requests. + If not set, circuit breakers will be enabled with the default thresholds + properties: + maxConnections: + default: 1024 + description: The maximum number of + connections that Envoy will establish + to the referenced backend defined + within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxParallelRequests: + default: 1024 + description: The maximum number of + parallel requests that Envoy will + make to the referenced backend defined + within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxParallelRetries: + default: 1024 + description: The maximum number of + parallel retries that Envoy will + make to the referenced backend defined + within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxPendingRequests: + default: 1024 + description: The maximum number of + pending requests that Envoy will + queue to the referenced backend + defined within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxRequestsPerConnection: + description: |- + The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule. + Default: unlimited. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + type: object + connection: + description: Connection includes backend + connection settings. + properties: + bufferLimit: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + BufferLimit Soft limit on size of the cluster’s connections read and write buffers. + BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space. + If unspecified, an implementation defined default is applied (32768 bytes). + For example, 20Mi, 1Gi, 256Ki etc. + Note: that when the suffix is not provided, the value is interpreted as bytes. + x-kubernetes-int-or-string: true + socketBufferLimit: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket + to backend. + SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space. + For example, 20Mi, 1Gi, 256Ki etc. + Note that when the suffix is not provided, the value is interpreted as bytes. + x-kubernetes-int-or-string: true + type: object + dns: + description: DNS includes dns resolution + settings. + properties: + dnsRefreshRate: + description: |- + DNSRefreshRate specifies the rate at which DNS records should be refreshed. + Defaults to 30 seconds. + type: string + respectDnsTtl: + description: |- + RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected. + If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL. + Defaults to true. + type: boolean + type: object + healthCheck: + description: HealthCheck allows gateway + to perform active health checking on + backends. + properties: + active: + description: Active health check configuration + properties: + healthyThreshold: + default: 1 + description: HealthyThreshold + defines the number of healthy + health checks required before + a backend host is marked healthy. + format: int32 + minimum: 1 + type: integer + http: + description: |- + HTTP defines the configuration of http health checker. + It's required while the health checker type is HTTP. + properties: + expectedResponse: + description: ExpectedResponse + defines a list of HTTP expected + responses to match. + properties: + binary: + description: Binary payload + base64 encoded. + format: byte + type: string + text: + description: Text payload + in plain text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines + the type of the payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type + is Text, text field needs + to be set. + rule: 'self.type == ''Text'' + ? has(self.text) : !has(self.text)' + - message: If payload type + is Binary, binary field + needs to be set. + rule: 'self.type == ''Binary'' + ? has(self.binary) : !has(self.binary)' + expectedStatuses: + description: |- + ExpectedStatuses defines a list of HTTP response statuses considered healthy. + Defaults to 200 only + items: + description: HTTPStatus + defines the http status + code. + exclusiveMaximum: true + maximum: 600 + minimum: 100 + type: integer + type: array + method: + description: |- + Method defines the HTTP method used for health checking. + Defaults to GET + type: string + path: + description: Path defines + the HTTP path that will + be requested during health + checking. + maxLength: 1024 + minLength: 1 + type: string + required: + - path + type: object + interval: + default: 3s + description: Interval defines + the time between active health + checks. + format: duration + type: string + tcp: + description: |- + TCP defines the configuration of tcp health checker. + It's required while the health checker type is TCP. + properties: + receive: + description: Receive defines + the expected response payload. + properties: + binary: + description: Binary payload + base64 encoded. + format: byte + type: string + text: + description: Text payload + in plain text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines + the type of the payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type + is Text, text field needs + to be set. + rule: 'self.type == ''Text'' + ? has(self.text) : !has(self.text)' + - message: If payload type + is Binary, binary field + needs to be set. + rule: 'self.type == ''Binary'' + ? has(self.binary) : !has(self.binary)' + send: + description: Send defines + the request payload. + properties: + binary: + description: Binary payload + base64 encoded. + format: byte + type: string + text: + description: Text payload + in plain text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines + the type of the payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type + is Text, text field needs + to be set. + rule: 'self.type == ''Text'' + ? has(self.text) : !has(self.text)' + - message: If payload type + is Binary, binary field + needs to be set. + rule: 'self.type == ''Binary'' + ? has(self.binary) : !has(self.binary)' + type: object + timeout: + default: 1s + description: Timeout defines the + time to wait for a health check + response. + format: duration + type: string + type: + allOf: + - enum: + - HTTP + - TCP + - enum: + - HTTP + - TCP + description: Type defines the + type of health checker. + type: string + unhealthyThreshold: + default: 3 + description: UnhealthyThreshold + defines the number of unhealthy + health checks required before + a backend host is marked unhealthy. + format: int32 + minimum: 1 + type: integer + required: + - type + type: object + x-kubernetes-validations: + - message: If Health Checker type + is HTTP, http field needs to be + set. + rule: 'self.type == ''HTTP'' ? has(self.http) + : !has(self.http)' + - message: If Health Checker type + is TCP, tcp field needs to be + set. + rule: 'self.type == ''TCP'' ? has(self.tcp) + : !has(self.tcp)' + passive: + description: Passive passive check + configuration + properties: + baseEjectionTime: + default: 30s + description: BaseEjectionTime + defines the base duration for + which a host will be ejected + on consecutive failures. + format: duration + type: string + consecutive5XxErrors: + default: 5 + description: Consecutive5xxErrors + sets the number of consecutive + 5xx errors triggering ejection. + format: int32 + type: integer + consecutiveGatewayErrors: + default: 0 + description: ConsecutiveGatewayErrors + sets the number of consecutive + gateway errors triggering ejection. + format: int32 + type: integer + consecutiveLocalOriginFailures: + default: 5 + description: |- + ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection. + Parameter takes effect only when split_external_local_origin_errors is set to true. + format: int32 + type: integer + interval: + default: 3s + description: Interval defines + the time between passive health + checks. + format: duration + type: string + maxEjectionPercent: + default: 10 + description: MaxEjectionPercent + sets the maximum percentage + of hosts in a cluster that can + be ejected. + format: int32 + type: integer + splitExternalLocalOriginErrors: + default: false + description: SplitExternalLocalOriginErrors + enables splitting of errors + between external and local origin. + type: boolean + type: object + type: object + http2: + description: HTTP2 provides HTTP/2 configuration + for backend connections. + properties: + initialConnectionWindowSize: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. + If not set, the default value is 1 MiB. + x-kubernetes-int-or-string: true + initialStreamWindowSize: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + InitialStreamWindowSize sets the initial window size for HTTP/2 streams. + If not set, the default value is 64 KiB(64*1024). + x-kubernetes-int-or-string: true + maxConcurrentStreams: + description: |- + MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. + If not set, the default value is 100. + format: int32 + maximum: 2147483647 + minimum: 1 + type: integer + onInvalidMessage: + description: |- + OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error + It's recommended for L2 Envoy deployments to set this value to TerminateStream. + https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two + Default: TerminateConnection + type: string + type: object + loadBalancer: + description: |- + LoadBalancer policy to apply when routing traffic from the gateway to + the backend endpoints + properties: + consistentHash: + description: |- + ConsistentHash defines the configuration when the load balancer type is + set to ConsistentHash + properties: + cookie: + description: Cookie configures + the cookie hash policy when + the consistent hash type is + set to Cookie. + properties: + attributes: + additionalProperties: + type: string + description: Additional Attributes + to set for the generated + cookie. + type: object + name: + description: |- + Name of the cookie to hash. + If this cookie does not exist in the request, Envoy will generate a cookie and set + the TTL on the response back to the client based on Layer 4 + attributes of the backend endpoint, to ensure that these future requests + go to the same backend endpoint. Make sure to set the TTL field for this case. + type: string + ttl: + description: |- + TTL of the generated cookie if the cookie is not present. This value sets the + Max-Age attribute value. + type: string + required: + - name + type: object + header: + description: Header configures + the header hash policy when + the consistent hash type is + set to Header. + properties: + name: + description: Name of the header + to hash. + type: string + required: + - name + type: object + tableSize: + default: 65537 + description: The table size for + consistent hashing, must be + prime number limited to 5000011. + format: int64 + maximum: 5000011 + minimum: 2 + type: integer + type: + description: |- + ConsistentHashType defines the type of input to hash on. Valid Type values are + "SourceIP", + "Header", + "Cookie". + enum: + - SourceIP + - Header + - Cookie + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If consistent hash type + is header, the header field must + be set. + rule: 'self.type == ''Header'' ? + has(self.header) : !has(self.header)' + - message: If consistent hash type + is cookie, the cookie field must + be set. + rule: 'self.type == ''Cookie'' ? + has(self.cookie) : !has(self.cookie)' + slowStart: + description: |- + SlowStart defines the configuration related to the slow start load balancer policy. + If set, during slow start window, traffic sent to the newly added hosts will gradually increase. + Currently this is only supported for RoundRobin and LeastRequest load balancers + properties: + window: + description: |- + Window defines the duration of the warm up period for newly added host. + During slow start window, traffic sent to the newly added hosts will gradually increase. + Currently only supports linear growth of traffic. For additional details, + see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig + type: string + required: + - window + type: object + type: + description: |- + Type decides the type of Load Balancer policy. + Valid LoadBalancerType values are + "ConsistentHash", + "LeastRequest", + "Random", + "RoundRobin". + enum: + - ConsistentHash + - LeastRequest + - Random + - RoundRobin + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If LoadBalancer type is consistentHash, + consistentHash field needs to be set. + rule: 'self.type == ''ConsistentHash'' + ? has(self.consistentHash) : !has(self.consistentHash)' + - message: Currently SlowStart is only + supported for RoundRobin and LeastRequest + load balancers. + rule: 'self.type in [''Random'', ''ConsistentHash''] + ? !has(self.slowStart) : true ' + proxyProtocol: + description: ProxyProtocol enables the + Proxy Protocol when communicating with + the backend. + properties: + version: + description: |- + Version of ProxyProtol + Valid ProxyProtocolVersion values are + "V1" + "V2" + enum: + - V1 + - V2 + type: string + required: + - version + type: object + tcpKeepalive: + description: |- + TcpKeepalive settings associated with the upstream client connection. + Disabled by default. + properties: + idleTime: + description: |- + The duration a connection needs to be idle before keep-alive + probes start being sent. + The duration format is + Defaults to `7200s`. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: |- + The duration between keep-alive probes. + Defaults to `75s`. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + probes: + description: |- + The total number of unacknowledged probes to send before deciding + the connection is dead. + Defaults to 9. + format: int32 + type: integer + type: object + timeout: + description: Timeout settings for the + backend connections. + properties: + http: + description: Timeout settings for + HTTP. + properties: + connectionIdleTimeout: + description: |- + The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection. + Default: 1 hour. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + maxConnectionDuration: + description: |- + The maximum duration of an HTTP connection. + Default: unlimited. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + tcp: + description: Timeout settings for + TCP. + properties: + connectTimeout: + description: |- + The timeout for network connection establishment, including TCP and TLS handshakes. + Default: 10 seconds. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + type: object + type: object + host: + description: |- + Host define the extension service hostname. + Deprecated: Use BackendRefs instead. + type: string + port: + default: 4317 + description: |- + Port defines the port the extension service is exposed on. + Deprecated: Use BackendRefs instead. + format: int32 + minimum: 0 + type: integer + resources: + additionalProperties: + type: string + description: |- + Resources is a set of labels that describe the source of a log entry, including envoy node info. + It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). + type: object + type: object + x-kubernetes-validations: + - message: host or backendRefs needs to be set + rule: has(self.host) || self.backendRefs.size() + > 0 + - message: BackendRefs must be used, backendRef + is not supported. + rule: '!has(self.backendRef)' + - message: BackendRefs only supports Service kind. + rule: 'has(self.backendRefs) ? self.backendRefs.all(f, + f.kind == ''Service'') : true' + - message: BackendRefs only supports Core group. + rule: 'has(self.backendRefs) ? (self.backendRefs.all(f, + f.group == "")) : true' + type: + description: Type defines the type of accesslog + sink. + enum: - ALS - File - OpenTelemetry @@ -10688,11 +12129,91 @@ spec: OpenTelemetry defines the configuration for OpenTelemetry sink. It's required if the sink type is OpenTelemetry. properties: + backendRef: + description: |- + BackendRef references a Kubernetes object that represents the + backend server to which the authorization request will be sent. + + + Deprecated: Use BackendRefs instead. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind == + ''Service'') ? has(self.port) : true' backendRefs: description: |- BackendRefs references a Kubernetes object that represents the - backend server to which the metric will be sent. - Only Service kind is supported for now. + backend server to which the authorization request will be sent. items: description: BackendRef defines how an ObjectReference that is specific to BackendRef. @@ -10770,48 +12291,657 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - maxItems: 1 + maxItems: 16 type: array - x-kubernetes-validations: - - message: only support Service kind. - rule: self.all(f, f.kind == 'Service') - - message: BackendRefs only supports Core group. - rule: self.all(f, f.group == '') - host: - description: |- - Host define the service hostname. - Deprecated: Use BackendRefs instead. - type: string - port: - default: 4317 + backendSettings: description: |- - Port defines the port the service is exposed on. - Deprecated: Use BackendRefs instead. - format: int32 - maximum: 65535 - minimum: 0 - type: integer - type: object - x-kubernetes-validations: - - message: host or backendRefs needs to be set - rule: has(self.host) || self.backendRefs.size() > - 0 - type: - default: OpenTelemetry - description: |- - Type defines the metric sink type. - EG currently only supports OpenTelemetry. - enum: - - OpenTelemetry - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: If MetricSink type is OpenTelemetry, openTelemetry - field needs to be set. - rule: 'self.type == ''OpenTelemetry'' ? has(self.openTelemetry) - : !has(self.openTelemetry)' + BackendSettings holds configuration for managing the connection + to the backend. + properties: + circuitBreaker: + description: |- + Circuit Breaker settings for the upstream connections and requests. + If not set, circuit breakers will be enabled with the default thresholds + properties: + maxConnections: + default: 1024 + description: The maximum number of connections + that Envoy will establish to the referenced + backend defined within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxParallelRequests: + default: 1024 + description: The maximum number of parallel + requests that Envoy will make to the referenced + backend defined within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxParallelRetries: + default: 1024 + description: The maximum number of parallel + retries that Envoy will make to the referenced + backend defined within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxPendingRequests: + default: 1024 + description: The maximum number of pending + requests that Envoy will queue to the + referenced backend defined within a xRoute + rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxRequestsPerConnection: + description: |- + The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule. + Default: unlimited. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + type: object + connection: + description: Connection includes backend connection + settings. + properties: + bufferLimit: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + BufferLimit Soft limit on size of the cluster’s connections read and write buffers. + BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space. + If unspecified, an implementation defined default is applied (32768 bytes). + For example, 20Mi, 1Gi, 256Ki etc. + Note: that when the suffix is not provided, the value is interpreted as bytes. + x-kubernetes-int-or-string: true + socketBufferLimit: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket + to backend. + SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space. + For example, 20Mi, 1Gi, 256Ki etc. + Note that when the suffix is not provided, the value is interpreted as bytes. + x-kubernetes-int-or-string: true + type: object + dns: + description: DNS includes dns resolution settings. + properties: + dnsRefreshRate: + description: |- + DNSRefreshRate specifies the rate at which DNS records should be refreshed. + Defaults to 30 seconds. + type: string + respectDnsTtl: + description: |- + RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected. + If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL. + Defaults to true. + type: boolean + type: object + healthCheck: + description: HealthCheck allows gateway to perform + active health checking on backends. + properties: + active: + description: Active health check configuration + properties: + healthyThreshold: + default: 1 + description: HealthyThreshold defines + the number of healthy health checks + required before a backend host is + marked healthy. + format: int32 + minimum: 1 + type: integer + http: + description: |- + HTTP defines the configuration of http health checker. + It's required while the health checker type is HTTP. + properties: + expectedResponse: + description: ExpectedResponse defines + a list of HTTP expected responses + to match. + properties: + binary: + description: Binary payload + base64 encoded. + format: byte + type: string + text: + description: Text payload in + plain text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines the + type of the payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type is Text, + text field needs to be set. + rule: 'self.type == ''Text'' ? + has(self.text) : !has(self.text)' + - message: If payload type is Binary, + binary field needs to be set. + rule: 'self.type == ''Binary'' + ? has(self.binary) : !has(self.binary)' + expectedStatuses: + description: |- + ExpectedStatuses defines a list of HTTP response statuses considered healthy. + Defaults to 200 only + items: + description: HTTPStatus defines + the http status code. + exclusiveMaximum: true + maximum: 600 + minimum: 100 + type: integer + type: array + method: + description: |- + Method defines the HTTP method used for health checking. + Defaults to GET + type: string + path: + description: Path defines the HTTP + path that will be requested during + health checking. + maxLength: 1024 + minLength: 1 + type: string + required: + - path + type: object + interval: + default: 3s + description: Interval defines the time + between active health checks. + format: duration + type: string + tcp: + description: |- + TCP defines the configuration of tcp health checker. + It's required while the health checker type is TCP. + properties: + receive: + description: Receive defines the + expected response payload. + properties: + binary: + description: Binary payload + base64 encoded. + format: byte + type: string + text: + description: Text payload in + plain text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines the + type of the payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type is Text, + text field needs to be set. + rule: 'self.type == ''Text'' ? + has(self.text) : !has(self.text)' + - message: If payload type is Binary, + binary field needs to be set. + rule: 'self.type == ''Binary'' + ? has(self.binary) : !has(self.binary)' + send: + description: Send defines the request + payload. + properties: + binary: + description: Binary payload + base64 encoded. + format: byte + type: string + text: + description: Text payload in + plain text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines the + type of the payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type is Text, + text field needs to be set. + rule: 'self.type == ''Text'' ? + has(self.text) : !has(self.text)' + - message: If payload type is Binary, + binary field needs to be set. + rule: 'self.type == ''Binary'' + ? has(self.binary) : !has(self.binary)' + type: object + timeout: + default: 1s + description: Timeout defines the time + to wait for a health check response. + format: duration + type: string + type: + allOf: + - enum: + - HTTP + - TCP + - enum: + - HTTP + - TCP + description: Type defines the type of + health checker. + type: string + unhealthyThreshold: + default: 3 + description: UnhealthyThreshold defines + the number of unhealthy health checks + required before a backend host is + marked unhealthy. + format: int32 + minimum: 1 + type: integer + required: + - type + type: object + x-kubernetes-validations: + - message: If Health Checker type is HTTP, + http field needs to be set. + rule: 'self.type == ''HTTP'' ? has(self.http) + : !has(self.http)' + - message: If Health Checker type is TCP, + tcp field needs to be set. + rule: 'self.type == ''TCP'' ? has(self.tcp) + : !has(self.tcp)' + passive: + description: Passive passive check configuration + properties: + baseEjectionTime: + default: 30s + description: BaseEjectionTime defines + the base duration for which a host + will be ejected on consecutive failures. + format: duration + type: string + consecutive5XxErrors: + default: 5 + description: Consecutive5xxErrors sets + the number of consecutive 5xx errors + triggering ejection. + format: int32 + type: integer + consecutiveGatewayErrors: + default: 0 + description: ConsecutiveGatewayErrors + sets the number of consecutive gateway + errors triggering ejection. + format: int32 + type: integer + consecutiveLocalOriginFailures: + default: 5 + description: |- + ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection. + Parameter takes effect only when split_external_local_origin_errors is set to true. + format: int32 + type: integer + interval: + default: 3s + description: Interval defines the time + between passive health checks. + format: duration + type: string + maxEjectionPercent: + default: 10 + description: MaxEjectionPercent sets + the maximum percentage of hosts in + a cluster that can be ejected. + format: int32 + type: integer + splitExternalLocalOriginErrors: + default: false + description: SplitExternalLocalOriginErrors + enables splitting of errors between + external and local origin. + type: boolean + type: object + type: object + http2: + description: HTTP2 provides HTTP/2 configuration + for backend connections. + properties: + initialConnectionWindowSize: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. + If not set, the default value is 1 MiB. + x-kubernetes-int-or-string: true + initialStreamWindowSize: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + InitialStreamWindowSize sets the initial window size for HTTP/2 streams. + If not set, the default value is 64 KiB(64*1024). + x-kubernetes-int-or-string: true + maxConcurrentStreams: + description: |- + MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. + If not set, the default value is 100. + format: int32 + maximum: 2147483647 + minimum: 1 + type: integer + onInvalidMessage: + description: |- + OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error + It's recommended for L2 Envoy deployments to set this value to TerminateStream. + https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two + Default: TerminateConnection + type: string + type: object + loadBalancer: + description: |- + LoadBalancer policy to apply when routing traffic from the gateway to + the backend endpoints + properties: + consistentHash: + description: |- + ConsistentHash defines the configuration when the load balancer type is + set to ConsistentHash + properties: + cookie: + description: Cookie configures the cookie + hash policy when the consistent hash + type is set to Cookie. + properties: + attributes: + additionalProperties: + type: string + description: Additional Attributes + to set for the generated cookie. + type: object + name: + description: |- + Name of the cookie to hash. + If this cookie does not exist in the request, Envoy will generate a cookie and set + the TTL on the response back to the client based on Layer 4 + attributes of the backend endpoint, to ensure that these future requests + go to the same backend endpoint. Make sure to set the TTL field for this case. + type: string + ttl: + description: |- + TTL of the generated cookie if the cookie is not present. This value sets the + Max-Age attribute value. + type: string + required: + - name + type: object + header: + description: Header configures the header + hash policy when the consistent hash + type is set to Header. + properties: + name: + description: Name of the header + to hash. + type: string + required: + - name + type: object + tableSize: + default: 65537 + description: The table size for consistent + hashing, must be prime number limited + to 5000011. + format: int64 + maximum: 5000011 + minimum: 2 + type: integer + type: + description: |- + ConsistentHashType defines the type of input to hash on. Valid Type values are + "SourceIP", + "Header", + "Cookie". + enum: + - SourceIP + - Header + - Cookie + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If consistent hash type is header, + the header field must be set. + rule: 'self.type == ''Header'' ? has(self.header) + : !has(self.header)' + - message: If consistent hash type is cookie, + the cookie field must be set. + rule: 'self.type == ''Cookie'' ? has(self.cookie) + : !has(self.cookie)' + slowStart: + description: |- + SlowStart defines the configuration related to the slow start load balancer policy. + If set, during slow start window, traffic sent to the newly added hosts will gradually increase. + Currently this is only supported for RoundRobin and LeastRequest load balancers + properties: + window: + description: |- + Window defines the duration of the warm up period for newly added host. + During slow start window, traffic sent to the newly added hosts will gradually increase. + Currently only supports linear growth of traffic. For additional details, + see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig + type: string + required: + - window + type: object + type: + description: |- + Type decides the type of Load Balancer policy. + Valid LoadBalancerType values are + "ConsistentHash", + "LeastRequest", + "Random", + "RoundRobin". + enum: + - ConsistentHash + - LeastRequest + - Random + - RoundRobin + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If LoadBalancer type is consistentHash, + consistentHash field needs to be set. + rule: 'self.type == ''ConsistentHash'' ? has(self.consistentHash) + : !has(self.consistentHash)' + - message: Currently SlowStart is only supported + for RoundRobin and LeastRequest load balancers. + rule: 'self.type in [''Random'', ''ConsistentHash''] + ? !has(self.slowStart) : true ' + proxyProtocol: + description: ProxyProtocol enables the Proxy + Protocol when communicating with the backend. + properties: + version: + description: |- + Version of ProxyProtol + Valid ProxyProtocolVersion values are + "V1" + "V2" + enum: + - V1 + - V2 + type: string + required: + - version + type: object + tcpKeepalive: + description: |- + TcpKeepalive settings associated with the upstream client connection. + Disabled by default. + properties: + idleTime: + description: |- + The duration a connection needs to be idle before keep-alive + probes start being sent. + The duration format is + Defaults to `7200s`. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: |- + The duration between keep-alive probes. + Defaults to `75s`. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + probes: + description: |- + The total number of unacknowledged probes to send before deciding + the connection is dead. + Defaults to 9. + format: int32 + type: integer + type: object + timeout: + description: Timeout settings for the backend + connections. + properties: + http: + description: Timeout settings for HTTP. + properties: + connectionIdleTimeout: + description: |- + The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection. + Default: 1 hour. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + maxConnectionDuration: + description: |- + The maximum duration of an HTTP connection. + Default: unlimited. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + tcp: + description: Timeout settings for TCP. + properties: + connectTimeout: + description: |- + The timeout for network connection establishment, including TCP and TLS handshakes. + Default: 10 seconds. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + type: object + type: object + host: + description: |- + Host define the service hostname. + Deprecated: Use BackendRefs instead. + type: string + port: + default: 4317 + description: |- + Port defines the port the service is exposed on. + Deprecated: Use BackendRefs instead. + format: int32 + maximum: 65535 + minimum: 0 + type: integer + type: object + x-kubernetes-validations: + - message: host or backendRefs needs to be set + rule: has(self.host) || self.backendRefs.size() > + 0 + - message: BackendRefs must be used, backendRef is not + supported. + rule: '!has(self.backendRef)' + - message: only supports Service kind. + rule: 'has(self.backendRefs) ? self.backendRefs.all(f, + f.kind == ''Service'') : true' + - message: BackendRefs only supports Core group. + rule: 'has(self.backendRefs) ? (self.backendRefs.all(f, + f.group == "")) : true' + type: + default: OpenTelemetry + description: |- + Type defines the metric sink type. + EG currently only supports OpenTelemetry. + enum: + - OpenTelemetry + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If MetricSink type is OpenTelemetry, openTelemetry + field needs to be set. + rule: 'self.type == ''OpenTelemetry'' ? has(self.openTelemetry) + : !has(self.openTelemetry)' + maxItems: 16 type: array type: object tracing: @@ -10884,11 +13014,91 @@ spec: provider: description: Provider defines the tracing provider. properties: + backendRef: + description: |- + BackendRef references a Kubernetes object that represents the + backend server to which the authorization request will be sent. + + + Deprecated: Use BackendRefs instead. + properties: + group: + default: "" + description: |- + Group is the group of the referent. For example, "gateway.networking.k8s.io". + When unspecified or empty string, core API group is inferred. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + default: Service + description: |- + Kind is the Kubernetes resource kind of the referent. For example + "Service". + + + Defaults to "Service" when not specified. + + + ExternalName services can refer to CNAME DNS records that may live + outside of the cluster and as such are difficult to reason about in + terms of conformance. They also may not be safe to forward to (see + CVE-2021-25740 for more information). Implementations SHOULD NOT + support ExternalName Services. + + + Support: Core (Services with a type other than ExternalName) + + + Support: Implementation-specific (Services with type ExternalName) + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: Name is the name of the referent. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the backend. When unspecified, the local + namespace is inferred. + + + Note that when a namespace different than the local namespace is specified, + a ReferenceGrant object is required in the referent namespace to allow that + namespace's owner to accept the reference. See the ReferenceGrant + documentation for details. + + + Support: Core + maxLength: 63 + minLength: 1 + pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ + type: string + port: + description: |- + Port specifies the destination port number to use for this resource. + Port is required when the referent is a Kubernetes Service. In this + case, the port number is the service port number, not the target port. + For other resources, destination port might be derived from the referent + resource or this field. + format: int32 + maximum: 65535 + minimum: 1 + type: integer + required: + - name + type: object + x-kubernetes-validations: + - message: Must have port for Service reference + rule: '(size(self.group) == 0 && self.kind == ''Service'') + ? has(self.port) : true' backendRefs: description: |- BackendRefs references a Kubernetes object that represents the - backend server to which the trace will be sent. - Only Service kind is supported for now. + backend server to which the authorization request will be sent. items: description: BackendRef defines how an ObjectReference that is specific to BackendRef. @@ -10966,13 +13176,607 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - maxItems: 1 + maxItems: 16 type: array - x-kubernetes-validations: - - message: only support Service kind. - rule: self.all(f, f.kind == 'Service') - - message: BackendRefs only supports Core group. - rule: self.all(f, f.group == '') + backendSettings: + description: |- + BackendSettings holds configuration for managing the connection + to the backend. + properties: + circuitBreaker: + description: |- + Circuit Breaker settings for the upstream connections and requests. + If not set, circuit breakers will be enabled with the default thresholds + properties: + maxConnections: + default: 1024 + description: The maximum number of connections + that Envoy will establish to the referenced + backend defined within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxParallelRequests: + default: 1024 + description: The maximum number of parallel requests + that Envoy will make to the referenced backend + defined within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxParallelRetries: + default: 1024 + description: The maximum number of parallel retries + that Envoy will make to the referenced backend + defined within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxPendingRequests: + default: 1024 + description: The maximum number of pending requests + that Envoy will queue to the referenced backend + defined within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxRequestsPerConnection: + description: |- + The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule. + Default: unlimited. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + type: object + connection: + description: Connection includes backend connection + settings. + properties: + bufferLimit: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + BufferLimit Soft limit on size of the cluster’s connections read and write buffers. + BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space. + If unspecified, an implementation defined default is applied (32768 bytes). + For example, 20Mi, 1Gi, 256Ki etc. + Note: that when the suffix is not provided, the value is interpreted as bytes. + x-kubernetes-int-or-string: true + socketBufferLimit: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket + to backend. + SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space. + For example, 20Mi, 1Gi, 256Ki etc. + Note that when the suffix is not provided, the value is interpreted as bytes. + x-kubernetes-int-or-string: true + type: object + dns: + description: DNS includes dns resolution settings. + properties: + dnsRefreshRate: + description: |- + DNSRefreshRate specifies the rate at which DNS records should be refreshed. + Defaults to 30 seconds. + type: string + respectDnsTtl: + description: |- + RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected. + If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL. + Defaults to true. + type: boolean + type: object + healthCheck: + description: HealthCheck allows gateway to perform + active health checking on backends. + properties: + active: + description: Active health check configuration + properties: + healthyThreshold: + default: 1 + description: HealthyThreshold defines the + number of healthy health checks required + before a backend host is marked healthy. + format: int32 + minimum: 1 + type: integer + http: + description: |- + HTTP defines the configuration of http health checker. + It's required while the health checker type is HTTP. + properties: + expectedResponse: + description: ExpectedResponse defines + a list of HTTP expected responses to + match. + properties: + binary: + description: Binary payload base64 + encoded. + format: byte + type: string + text: + description: Text payload in plain + text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines the type + of the payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type is Text, text + field needs to be set. + rule: 'self.type == ''Text'' ? has(self.text) + : !has(self.text)' + - message: If payload type is Binary, + binary field needs to be set. + rule: 'self.type == ''Binary'' ? has(self.binary) + : !has(self.binary)' + expectedStatuses: + description: |- + ExpectedStatuses defines a list of HTTP response statuses considered healthy. + Defaults to 200 only + items: + description: HTTPStatus defines the + http status code. + exclusiveMaximum: true + maximum: 600 + minimum: 100 + type: integer + type: array + method: + description: |- + Method defines the HTTP method used for health checking. + Defaults to GET + type: string + path: + description: Path defines the HTTP path + that will be requested during health + checking. + maxLength: 1024 + minLength: 1 + type: string + required: + - path + type: object + interval: + default: 3s + description: Interval defines the time between + active health checks. + format: duration + type: string + tcp: + description: |- + TCP defines the configuration of tcp health checker. + It's required while the health checker type is TCP. + properties: + receive: + description: Receive defines the expected + response payload. + properties: + binary: + description: Binary payload base64 + encoded. + format: byte + type: string + text: + description: Text payload in plain + text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines the type + of the payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type is Text, text + field needs to be set. + rule: 'self.type == ''Text'' ? has(self.text) + : !has(self.text)' + - message: If payload type is Binary, + binary field needs to be set. + rule: 'self.type == ''Binary'' ? has(self.binary) + : !has(self.binary)' + send: + description: Send defines the request + payload. + properties: + binary: + description: Binary payload base64 + encoded. + format: byte + type: string + text: + description: Text payload in plain + text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines the type + of the payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type is Text, text + field needs to be set. + rule: 'self.type == ''Text'' ? has(self.text) + : !has(self.text)' + - message: If payload type is Binary, + binary field needs to be set. + rule: 'self.type == ''Binary'' ? has(self.binary) + : !has(self.binary)' + type: object + timeout: + default: 1s + description: Timeout defines the time to wait + for a health check response. + format: duration + type: string + type: + allOf: + - enum: + - HTTP + - TCP + - enum: + - HTTP + - TCP + description: Type defines the type of health + checker. + type: string + unhealthyThreshold: + default: 3 + description: UnhealthyThreshold defines the + number of unhealthy health checks required + before a backend host is marked unhealthy. + format: int32 + minimum: 1 + type: integer + required: + - type + type: object + x-kubernetes-validations: + - message: If Health Checker type is HTTP, http + field needs to be set. + rule: 'self.type == ''HTTP'' ? has(self.http) + : !has(self.http)' + - message: If Health Checker type is TCP, tcp + field needs to be set. + rule: 'self.type == ''TCP'' ? has(self.tcp) + : !has(self.tcp)' + passive: + description: Passive passive check configuration + properties: + baseEjectionTime: + default: 30s + description: BaseEjectionTime defines the + base duration for which a host will be ejected + on consecutive failures. + format: duration + type: string + consecutive5XxErrors: + default: 5 + description: Consecutive5xxErrors sets the + number of consecutive 5xx errors triggering + ejection. + format: int32 + type: integer + consecutiveGatewayErrors: + default: 0 + description: ConsecutiveGatewayErrors sets + the number of consecutive gateway errors + triggering ejection. + format: int32 + type: integer + consecutiveLocalOriginFailures: + default: 5 + description: |- + ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection. + Parameter takes effect only when split_external_local_origin_errors is set to true. + format: int32 + type: integer + interval: + default: 3s + description: Interval defines the time between + passive health checks. + format: duration + type: string + maxEjectionPercent: + default: 10 + description: MaxEjectionPercent sets the maximum + percentage of hosts in a cluster that can + be ejected. + format: int32 + type: integer + splitExternalLocalOriginErrors: + default: false + description: SplitExternalLocalOriginErrors + enables splitting of errors between external + and local origin. + type: boolean + type: object + type: object + http2: + description: HTTP2 provides HTTP/2 configuration for + backend connections. + properties: + initialConnectionWindowSize: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. + If not set, the default value is 1 MiB. + x-kubernetes-int-or-string: true + initialStreamWindowSize: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + InitialStreamWindowSize sets the initial window size for HTTP/2 streams. + If not set, the default value is 64 KiB(64*1024). + x-kubernetes-int-or-string: true + maxConcurrentStreams: + description: |- + MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. + If not set, the default value is 100. + format: int32 + maximum: 2147483647 + minimum: 1 + type: integer + onInvalidMessage: + description: |- + OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error + It's recommended for L2 Envoy deployments to set this value to TerminateStream. + https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two + Default: TerminateConnection + type: string + type: object + loadBalancer: + description: |- + LoadBalancer policy to apply when routing traffic from the gateway to + the backend endpoints + properties: + consistentHash: + description: |- + ConsistentHash defines the configuration when the load balancer type is + set to ConsistentHash + properties: + cookie: + description: Cookie configures the cookie + hash policy when the consistent hash type + is set to Cookie. + properties: + attributes: + additionalProperties: + type: string + description: Additional Attributes to + set for the generated cookie. + type: object + name: + description: |- + Name of the cookie to hash. + If this cookie does not exist in the request, Envoy will generate a cookie and set + the TTL on the response back to the client based on Layer 4 + attributes of the backend endpoint, to ensure that these future requests + go to the same backend endpoint. Make sure to set the TTL field for this case. + type: string + ttl: + description: |- + TTL of the generated cookie if the cookie is not present. This value sets the + Max-Age attribute value. + type: string + required: + - name + type: object + header: + description: Header configures the header + hash policy when the consistent hash type + is set to Header. + properties: + name: + description: Name of the header to hash. + type: string + required: + - name + type: object + tableSize: + default: 65537 + description: The table size for consistent + hashing, must be prime number limited to + 5000011. + format: int64 + maximum: 5000011 + minimum: 2 + type: integer + type: + description: |- + ConsistentHashType defines the type of input to hash on. Valid Type values are + "SourceIP", + "Header", + "Cookie". + enum: + - SourceIP + - Header + - Cookie + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If consistent hash type is header, + the header field must be set. + rule: 'self.type == ''Header'' ? has(self.header) + : !has(self.header)' + - message: If consistent hash type is cookie, + the cookie field must be set. + rule: 'self.type == ''Cookie'' ? has(self.cookie) + : !has(self.cookie)' + slowStart: + description: |- + SlowStart defines the configuration related to the slow start load balancer policy. + If set, during slow start window, traffic sent to the newly added hosts will gradually increase. + Currently this is only supported for RoundRobin and LeastRequest load balancers + properties: + window: + description: |- + Window defines the duration of the warm up period for newly added host. + During slow start window, traffic sent to the newly added hosts will gradually increase. + Currently only supports linear growth of traffic. For additional details, + see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig + type: string + required: + - window + type: object + type: + description: |- + Type decides the type of Load Balancer policy. + Valid LoadBalancerType values are + "ConsistentHash", + "LeastRequest", + "Random", + "RoundRobin". + enum: + - ConsistentHash + - LeastRequest + - Random + - RoundRobin + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If LoadBalancer type is consistentHash, + consistentHash field needs to be set. + rule: 'self.type == ''ConsistentHash'' ? has(self.consistentHash) + : !has(self.consistentHash)' + - message: Currently SlowStart is only supported for + RoundRobin and LeastRequest load balancers. + rule: 'self.type in [''Random'', ''ConsistentHash''] + ? !has(self.slowStart) : true ' + proxyProtocol: + description: ProxyProtocol enables the Proxy Protocol + when communicating with the backend. + properties: + version: + description: |- + Version of ProxyProtol + Valid ProxyProtocolVersion values are + "V1" + "V2" + enum: + - V1 + - V2 + type: string + required: + - version + type: object + tcpKeepalive: + description: |- + TcpKeepalive settings associated with the upstream client connection. + Disabled by default. + properties: + idleTime: + description: |- + The duration a connection needs to be idle before keep-alive + probes start being sent. + The duration format is + Defaults to `7200s`. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: |- + The duration between keep-alive probes. + Defaults to `75s`. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + probes: + description: |- + The total number of unacknowledged probes to send before deciding + the connection is dead. + Defaults to 9. + format: int32 + type: integer + type: object + timeout: + description: Timeout settings for the backend connections. + properties: + http: + description: Timeout settings for HTTP. + properties: + connectionIdleTimeout: + description: |- + The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection. + Default: 1 hour. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + maxConnectionDuration: + description: |- + The maximum duration of an HTTP connection. + Default: unlimited. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + tcp: + description: Timeout settings for TCP. + properties: + connectTimeout: + description: |- + The timeout for network connection establishment, including TCP and TLS handshakes. + Default: 10 seconds. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + type: object + type: object host: description: |- Host define the provider service hostname. @@ -11015,6 +13819,14 @@ spec: x-kubernetes-validations: - message: host or backendRefs needs to be set rule: has(self.host) || self.backendRefs.size() > 0 + - message: BackendRefs must be used, backendRef is not supported. + rule: '!has(self.backendRef)' + - message: only supports Service kind. + rule: 'has(self.backendRefs) ? self.backendRefs.all(f, f.kind + == ''Service'') : true' + - message: BackendRefs only supports Core group. + rule: 'has(self.backendRefs) ? (self.backendRefs.all(f, + f.group == "")) : true' samplingRate: default: 100 description: |- diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml index 3906b325b3d..da8c50015d2 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -260,7 +260,6 @@ spec: description: |- BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent. - Only Service kind is supported for now. Deprecated: Use BackendRefs instead. @@ -342,7 +341,6 @@ spec: description: |- BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. - Only Service kind is supported for now. items: description: BackendRef defines how an ObjectReference that is specific to BackendRef. @@ -420,17 +418,608 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - maxItems: 1 + maxItems: 16 type: array - x-kubernetes-validations: - - message: only support Service kind. - rule: self.all(f, f.kind == 'Service') - - message: BackendRefs only supports Core group. - rule: self.all(f, f.group == '') + backendSettings: + description: |- + BackendSettings holds configuration for managing the connection + to the backend. + properties: + circuitBreaker: + description: |- + Circuit Breaker settings for the upstream connections and requests. + If not set, circuit breakers will be enabled with the default thresholds + properties: + maxConnections: + default: 1024 + description: The maximum number of connections that + Envoy will establish to the referenced backend defined + within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxParallelRequests: + default: 1024 + description: The maximum number of parallel requests + that Envoy will make to the referenced backend defined + within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxParallelRetries: + default: 1024 + description: The maximum number of parallel retries + that Envoy will make to the referenced backend defined + within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxPendingRequests: + default: 1024 + description: The maximum number of pending requests + that Envoy will queue to the referenced backend + defined within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxRequestsPerConnection: + description: |- + The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule. + Default: unlimited. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + type: object + connection: + description: Connection includes backend connection settings. + properties: + bufferLimit: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + BufferLimit Soft limit on size of the cluster’s connections read and write buffers. + BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space. + If unspecified, an implementation defined default is applied (32768 bytes). + For example, 20Mi, 1Gi, 256Ki etc. + Note: that when the suffix is not provided, the value is interpreted as bytes. + x-kubernetes-int-or-string: true + socketBufferLimit: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket + to backend. + SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space. + For example, 20Mi, 1Gi, 256Ki etc. + Note that when the suffix is not provided, the value is interpreted as bytes. + x-kubernetes-int-or-string: true + type: object + dns: + description: DNS includes dns resolution settings. + properties: + dnsRefreshRate: + description: |- + DNSRefreshRate specifies the rate at which DNS records should be refreshed. + Defaults to 30 seconds. + type: string + respectDnsTtl: + description: |- + RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected. + If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL. + Defaults to true. + type: boolean + type: object + healthCheck: + description: HealthCheck allows gateway to perform active + health checking on backends. + properties: + active: + description: Active health check configuration + properties: + healthyThreshold: + default: 1 + description: HealthyThreshold defines the number + of healthy health checks required before a backend + host is marked healthy. + format: int32 + minimum: 1 + type: integer + http: + description: |- + HTTP defines the configuration of http health checker. + It's required while the health checker type is HTTP. + properties: + expectedResponse: + description: ExpectedResponse defines a list + of HTTP expected responses to match. + properties: + binary: + description: Binary payload base64 encoded. + format: byte + type: string + text: + description: Text payload in plain text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines the type of + the payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type is Text, text field + needs to be set. + rule: 'self.type == ''Text'' ? has(self.text) + : !has(self.text)' + - message: If payload type is Binary, binary + field needs to be set. + rule: 'self.type == ''Binary'' ? has(self.binary) + : !has(self.binary)' + expectedStatuses: + description: |- + ExpectedStatuses defines a list of HTTP response statuses considered healthy. + Defaults to 200 only + items: + description: HTTPStatus defines the http + status code. + exclusiveMaximum: true + maximum: 600 + minimum: 100 + type: integer + type: array + method: + description: |- + Method defines the HTTP method used for health checking. + Defaults to GET + type: string + path: + description: Path defines the HTTP path that + will be requested during health checking. + maxLength: 1024 + minLength: 1 + type: string + required: + - path + type: object + interval: + default: 3s + description: Interval defines the time between + active health checks. + format: duration + type: string + tcp: + description: |- + TCP defines the configuration of tcp health checker. + It's required while the health checker type is TCP. + properties: + receive: + description: Receive defines the expected + response payload. + properties: + binary: + description: Binary payload base64 encoded. + format: byte + type: string + text: + description: Text payload in plain text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines the type of + the payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type is Text, text field + needs to be set. + rule: 'self.type == ''Text'' ? has(self.text) + : !has(self.text)' + - message: If payload type is Binary, binary + field needs to be set. + rule: 'self.type == ''Binary'' ? has(self.binary) + : !has(self.binary)' + send: + description: Send defines the request payload. + properties: + binary: + description: Binary payload base64 encoded. + format: byte + type: string + text: + description: Text payload in plain text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines the type of + the payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type is Text, text field + needs to be set. + rule: 'self.type == ''Text'' ? has(self.text) + : !has(self.text)' + - message: If payload type is Binary, binary + field needs to be set. + rule: 'self.type == ''Binary'' ? has(self.binary) + : !has(self.binary)' + type: object + timeout: + default: 1s + description: Timeout defines the time to wait + for a health check response. + format: duration + type: string + type: + allOf: + - enum: + - HTTP + - TCP + - enum: + - HTTP + - TCP + description: Type defines the type of health checker. + type: string + unhealthyThreshold: + default: 3 + description: UnhealthyThreshold defines the number + of unhealthy health checks required before a + backend host is marked unhealthy. + format: int32 + minimum: 1 + type: integer + required: + - type + type: object + x-kubernetes-validations: + - message: If Health Checker type is HTTP, http field + needs to be set. + rule: 'self.type == ''HTTP'' ? has(self.http) : + !has(self.http)' + - message: If Health Checker type is TCP, tcp field + needs to be set. + rule: 'self.type == ''TCP'' ? has(self.tcp) : !has(self.tcp)' + passive: + description: Passive passive check configuration + properties: + baseEjectionTime: + default: 30s + description: BaseEjectionTime defines the base + duration for which a host will be ejected on + consecutive failures. + format: duration + type: string + consecutive5XxErrors: + default: 5 + description: Consecutive5xxErrors sets the number + of consecutive 5xx errors triggering ejection. + format: int32 + type: integer + consecutiveGatewayErrors: + default: 0 + description: ConsecutiveGatewayErrors sets the + number of consecutive gateway errors triggering + ejection. + format: int32 + type: integer + consecutiveLocalOriginFailures: + default: 5 + description: |- + ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection. + Parameter takes effect only when split_external_local_origin_errors is set to true. + format: int32 + type: integer + interval: + default: 3s + description: Interval defines the time between + passive health checks. + format: duration + type: string + maxEjectionPercent: + default: 10 + description: MaxEjectionPercent sets the maximum + percentage of hosts in a cluster that can be + ejected. + format: int32 + type: integer + splitExternalLocalOriginErrors: + default: false + description: SplitExternalLocalOriginErrors enables + splitting of errors between external and local + origin. + type: boolean + type: object + type: object + http2: + description: HTTP2 provides HTTP/2 configuration for backend + connections. + properties: + initialConnectionWindowSize: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. + If not set, the default value is 1 MiB. + x-kubernetes-int-or-string: true + initialStreamWindowSize: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + InitialStreamWindowSize sets the initial window size for HTTP/2 streams. + If not set, the default value is 64 KiB(64*1024). + x-kubernetes-int-or-string: true + maxConcurrentStreams: + description: |- + MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. + If not set, the default value is 100. + format: int32 + maximum: 2147483647 + minimum: 1 + type: integer + onInvalidMessage: + description: |- + OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error + It's recommended for L2 Envoy deployments to set this value to TerminateStream. + https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two + Default: TerminateConnection + type: string + type: object + loadBalancer: + description: |- + LoadBalancer policy to apply when routing traffic from the gateway to + the backend endpoints + properties: + consistentHash: + description: |- + ConsistentHash defines the configuration when the load balancer type is + set to ConsistentHash + properties: + cookie: + description: Cookie configures the cookie hash + policy when the consistent hash type is set + to Cookie. + properties: + attributes: + additionalProperties: + type: string + description: Additional Attributes to set + for the generated cookie. + type: object + name: + description: |- + Name of the cookie to hash. + If this cookie does not exist in the request, Envoy will generate a cookie and set + the TTL on the response back to the client based on Layer 4 + attributes of the backend endpoint, to ensure that these future requests + go to the same backend endpoint. Make sure to set the TTL field for this case. + type: string + ttl: + description: |- + TTL of the generated cookie if the cookie is not present. This value sets the + Max-Age attribute value. + type: string + required: + - name + type: object + header: + description: Header configures the header hash + policy when the consistent hash type is set + to Header. + properties: + name: + description: Name of the header to hash. + type: string + required: + - name + type: object + tableSize: + default: 65537 + description: The table size for consistent hashing, + must be prime number limited to 5000011. + format: int64 + maximum: 5000011 + minimum: 2 + type: integer + type: + description: |- + ConsistentHashType defines the type of input to hash on. Valid Type values are + "SourceIP", + "Header", + "Cookie". + enum: + - SourceIP + - Header + - Cookie + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If consistent hash type is header, the + header field must be set. + rule: 'self.type == ''Header'' ? has(self.header) + : !has(self.header)' + - message: If consistent hash type is cookie, the + cookie field must be set. + rule: 'self.type == ''Cookie'' ? has(self.cookie) + : !has(self.cookie)' + slowStart: + description: |- + SlowStart defines the configuration related to the slow start load balancer policy. + If set, during slow start window, traffic sent to the newly added hosts will gradually increase. + Currently this is only supported for RoundRobin and LeastRequest load balancers + properties: + window: + description: |- + Window defines the duration of the warm up period for newly added host. + During slow start window, traffic sent to the newly added hosts will gradually increase. + Currently only supports linear growth of traffic. For additional details, + see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig + type: string + required: + - window + type: object + type: + description: |- + Type decides the type of Load Balancer policy. + Valid LoadBalancerType values are + "ConsistentHash", + "LeastRequest", + "Random", + "RoundRobin". + enum: + - ConsistentHash + - LeastRequest + - Random + - RoundRobin + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If LoadBalancer type is consistentHash, consistentHash + field needs to be set. + rule: 'self.type == ''ConsistentHash'' ? has(self.consistentHash) + : !has(self.consistentHash)' + - message: Currently SlowStart is only supported for RoundRobin + and LeastRequest load balancers. + rule: 'self.type in [''Random'', ''ConsistentHash''] + ? !has(self.slowStart) : true ' + proxyProtocol: + description: ProxyProtocol enables the Proxy Protocol + when communicating with the backend. + properties: + version: + description: |- + Version of ProxyProtol + Valid ProxyProtocolVersion values are + "V1" + "V2" + enum: + - V1 + - V2 + type: string + required: + - version + type: object + tcpKeepalive: + description: |- + TcpKeepalive settings associated with the upstream client connection. + Disabled by default. + properties: + idleTime: + description: |- + The duration a connection needs to be idle before keep-alive + probes start being sent. + The duration format is + Defaults to `7200s`. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: |- + The duration between keep-alive probes. + Defaults to `75s`. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + probes: + description: |- + The total number of unacknowledged probes to send before deciding + the connection is dead. + Defaults to 9. + format: int32 + type: integer + type: object + timeout: + description: Timeout settings for the backend connections. + properties: + http: + description: Timeout settings for HTTP. + properties: + connectionIdleTimeout: + description: |- + The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection. + Default: 1 hour. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + maxConnectionDuration: + description: |- + The maximum duration of an HTTP connection. + Default: unlimited. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + tcp: + description: Timeout settings for TCP. + properties: + connectTimeout: + description: |- + The timeout for network connection establishment, including TCP and TLS handshakes. + Default: 10 seconds. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + type: object + type: object type: object x-kubernetes-validations: - message: backendRef or backendRefs needs to be set rule: has(self.backendRef) || self.backendRefs.size() > 0 + - message: BackendRefs must be used, backendRef is not supported. + rule: '!has(self.backendRef)' + - message: Exactly one backendRef can be specified in backendRefs. + rule: has(self.backendRefs) && self.backendRefs.size()==1 + - message: BackendRefs only supports Service and Backend kind. + rule: 'has(self.backendRefs) ? self.backendRefs.all(f, f.kind + == ''Service'' || f.kind == ''Backend'') : true' + - message: BackendRefs only supports Core and gateway.envoyproxy.io + group. + rule: 'has(self.backendRefs) ? (self.backendRefs.all(f, f.group + == "" || f.group == ''gateway.envoyproxy.io'')) : true' headersToExtAuth: description: |- HeadersToExtAuth defines the client request headers that will be included @@ -456,7 +1045,6 @@ spec: description: |- BackendRef references a Kubernetes object that represents the backend server to which the authorization request will be sent. - Only Service kind is supported for now. Deprecated: Use BackendRefs instead. @@ -538,7 +1126,6 @@ spec: description: |- BackendRefs references a Kubernetes object that represents the backend server to which the authorization request will be sent. - Only Service kind is supported for now. items: description: BackendRef defines how an ObjectReference that is specific to BackendRef. @@ -616,13 +1203,593 @@ spec: - message: Must have port for Service reference rule: '(size(self.group) == 0 && self.kind == ''Service'') ? has(self.port) : true' - maxItems: 1 + maxItems: 16 type: array - x-kubernetes-validations: - - message: only support Service kind. - rule: self.all(f, f.kind == 'Service') - - message: BackendRefs only supports Core group. - rule: self.all(f, f.group == '') + backendSettings: + description: |- + BackendSettings holds configuration for managing the connection + to the backend. + properties: + circuitBreaker: + description: |- + Circuit Breaker settings for the upstream connections and requests. + If not set, circuit breakers will be enabled with the default thresholds + properties: + maxConnections: + default: 1024 + description: The maximum number of connections that + Envoy will establish to the referenced backend defined + within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxParallelRequests: + default: 1024 + description: The maximum number of parallel requests + that Envoy will make to the referenced backend defined + within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxParallelRetries: + default: 1024 + description: The maximum number of parallel retries + that Envoy will make to the referenced backend defined + within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxPendingRequests: + default: 1024 + description: The maximum number of pending requests + that Envoy will queue to the referenced backend + defined within a xRoute rule. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + maxRequestsPerConnection: + description: |- + The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule. + Default: unlimited. + format: int64 + maximum: 4294967295 + minimum: 0 + type: integer + type: object + connection: + description: Connection includes backend connection settings. + properties: + bufferLimit: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + BufferLimit Soft limit on size of the cluster’s connections read and write buffers. + BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space. + If unspecified, an implementation defined default is applied (32768 bytes). + For example, 20Mi, 1Gi, 256Ki etc. + Note: that when the suffix is not provided, the value is interpreted as bytes. + x-kubernetes-int-or-string: true + socketBufferLimit: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + SocketBufferLimit provides configuration for the maximum buffer size in bytes for each socket + to backend. + SocketBufferLimit applies to socket streaming channel between TCP/IP stacks, it's in kernel space. + For example, 20Mi, 1Gi, 256Ki etc. + Note that when the suffix is not provided, the value is interpreted as bytes. + x-kubernetes-int-or-string: true + type: object + dns: + description: DNS includes dns resolution settings. + properties: + dnsRefreshRate: + description: |- + DNSRefreshRate specifies the rate at which DNS records should be refreshed. + Defaults to 30 seconds. + type: string + respectDnsTtl: + description: |- + RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected. + If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL. + Defaults to true. + type: boolean + type: object + healthCheck: + description: HealthCheck allows gateway to perform active + health checking on backends. + properties: + active: + description: Active health check configuration + properties: + healthyThreshold: + default: 1 + description: HealthyThreshold defines the number + of healthy health checks required before a backend + host is marked healthy. + format: int32 + minimum: 1 + type: integer + http: + description: |- + HTTP defines the configuration of http health checker. + It's required while the health checker type is HTTP. + properties: + expectedResponse: + description: ExpectedResponse defines a list + of HTTP expected responses to match. + properties: + binary: + description: Binary payload base64 encoded. + format: byte + type: string + text: + description: Text payload in plain text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines the type of + the payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type is Text, text field + needs to be set. + rule: 'self.type == ''Text'' ? has(self.text) + : !has(self.text)' + - message: If payload type is Binary, binary + field needs to be set. + rule: 'self.type == ''Binary'' ? has(self.binary) + : !has(self.binary)' + expectedStatuses: + description: |- + ExpectedStatuses defines a list of HTTP response statuses considered healthy. + Defaults to 200 only + items: + description: HTTPStatus defines the http + status code. + exclusiveMaximum: true + maximum: 600 + minimum: 100 + type: integer + type: array + method: + description: |- + Method defines the HTTP method used for health checking. + Defaults to GET + type: string + path: + description: Path defines the HTTP path that + will be requested during health checking. + maxLength: 1024 + minLength: 1 + type: string + required: + - path + type: object + interval: + default: 3s + description: Interval defines the time between + active health checks. + format: duration + type: string + tcp: + description: |- + TCP defines the configuration of tcp health checker. + It's required while the health checker type is TCP. + properties: + receive: + description: Receive defines the expected + response payload. + properties: + binary: + description: Binary payload base64 encoded. + format: byte + type: string + text: + description: Text payload in plain text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines the type of + the payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type is Text, text field + needs to be set. + rule: 'self.type == ''Text'' ? has(self.text) + : !has(self.text)' + - message: If payload type is Binary, binary + field needs to be set. + rule: 'self.type == ''Binary'' ? has(self.binary) + : !has(self.binary)' + send: + description: Send defines the request payload. + properties: + binary: + description: Binary payload base64 encoded. + format: byte + type: string + text: + description: Text payload in plain text. + type: string + type: + allOf: + - enum: + - Text + - Binary + - enum: + - Text + - Binary + description: Type defines the type of + the payload. + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If payload type is Text, text field + needs to be set. + rule: 'self.type == ''Text'' ? has(self.text) + : !has(self.text)' + - message: If payload type is Binary, binary + field needs to be set. + rule: 'self.type == ''Binary'' ? has(self.binary) + : !has(self.binary)' + type: object + timeout: + default: 1s + description: Timeout defines the time to wait + for a health check response. + format: duration + type: string + type: + allOf: + - enum: + - HTTP + - TCP + - enum: + - HTTP + - TCP + description: Type defines the type of health checker. + type: string + unhealthyThreshold: + default: 3 + description: UnhealthyThreshold defines the number + of unhealthy health checks required before a + backend host is marked unhealthy. + format: int32 + minimum: 1 + type: integer + required: + - type + type: object + x-kubernetes-validations: + - message: If Health Checker type is HTTP, http field + needs to be set. + rule: 'self.type == ''HTTP'' ? has(self.http) : + !has(self.http)' + - message: If Health Checker type is TCP, tcp field + needs to be set. + rule: 'self.type == ''TCP'' ? has(self.tcp) : !has(self.tcp)' + passive: + description: Passive passive check configuration + properties: + baseEjectionTime: + default: 30s + description: BaseEjectionTime defines the base + duration for which a host will be ejected on + consecutive failures. + format: duration + type: string + consecutive5XxErrors: + default: 5 + description: Consecutive5xxErrors sets the number + of consecutive 5xx errors triggering ejection. + format: int32 + type: integer + consecutiveGatewayErrors: + default: 0 + description: ConsecutiveGatewayErrors sets the + number of consecutive gateway errors triggering + ejection. + format: int32 + type: integer + consecutiveLocalOriginFailures: + default: 5 + description: |- + ConsecutiveLocalOriginFailures sets the number of consecutive local origin failures triggering ejection. + Parameter takes effect only when split_external_local_origin_errors is set to true. + format: int32 + type: integer + interval: + default: 3s + description: Interval defines the time between + passive health checks. + format: duration + type: string + maxEjectionPercent: + default: 10 + description: MaxEjectionPercent sets the maximum + percentage of hosts in a cluster that can be + ejected. + format: int32 + type: integer + splitExternalLocalOriginErrors: + default: false + description: SplitExternalLocalOriginErrors enables + splitting of errors between external and local + origin. + type: boolean + type: object + type: object + http2: + description: HTTP2 provides HTTP/2 configuration for backend + connections. + properties: + initialConnectionWindowSize: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + InitialConnectionWindowSize sets the initial window size for HTTP/2 connections. + If not set, the default value is 1 MiB. + x-kubernetes-int-or-string: true + initialStreamWindowSize: + allOf: + - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + - pattern: ^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$ + anyOf: + - type: integer + - type: string + description: |- + InitialStreamWindowSize sets the initial window size for HTTP/2 streams. + If not set, the default value is 64 KiB(64*1024). + x-kubernetes-int-or-string: true + maxConcurrentStreams: + description: |- + MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection. + If not set, the default value is 100. + format: int32 + maximum: 2147483647 + minimum: 1 + type: integer + onInvalidMessage: + description: |- + OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error + It's recommended for L2 Envoy deployments to set this value to TerminateStream. + https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two + Default: TerminateConnection + type: string + type: object + loadBalancer: + description: |- + LoadBalancer policy to apply when routing traffic from the gateway to + the backend endpoints + properties: + consistentHash: + description: |- + ConsistentHash defines the configuration when the load balancer type is + set to ConsistentHash + properties: + cookie: + description: Cookie configures the cookie hash + policy when the consistent hash type is set + to Cookie. + properties: + attributes: + additionalProperties: + type: string + description: Additional Attributes to set + for the generated cookie. + type: object + name: + description: |- + Name of the cookie to hash. + If this cookie does not exist in the request, Envoy will generate a cookie and set + the TTL on the response back to the client based on Layer 4 + attributes of the backend endpoint, to ensure that these future requests + go to the same backend endpoint. Make sure to set the TTL field for this case. + type: string + ttl: + description: |- + TTL of the generated cookie if the cookie is not present. This value sets the + Max-Age attribute value. + type: string + required: + - name + type: object + header: + description: Header configures the header hash + policy when the consistent hash type is set + to Header. + properties: + name: + description: Name of the header to hash. + type: string + required: + - name + type: object + tableSize: + default: 65537 + description: The table size for consistent hashing, + must be prime number limited to 5000011. + format: int64 + maximum: 5000011 + minimum: 2 + type: integer + type: + description: |- + ConsistentHashType defines the type of input to hash on. Valid Type values are + "SourceIP", + "Header", + "Cookie". + enum: + - SourceIP + - Header + - Cookie + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If consistent hash type is header, the + header field must be set. + rule: 'self.type == ''Header'' ? has(self.header) + : !has(self.header)' + - message: If consistent hash type is cookie, the + cookie field must be set. + rule: 'self.type == ''Cookie'' ? has(self.cookie) + : !has(self.cookie)' + slowStart: + description: |- + SlowStart defines the configuration related to the slow start load balancer policy. + If set, during slow start window, traffic sent to the newly added hosts will gradually increase. + Currently this is only supported for RoundRobin and LeastRequest load balancers + properties: + window: + description: |- + Window defines the duration of the warm up period for newly added host. + During slow start window, traffic sent to the newly added hosts will gradually increase. + Currently only supports linear growth of traffic. For additional details, + see https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/cluster/v3/cluster.proto#config-cluster-v3-cluster-slowstartconfig + type: string + required: + - window + type: object + type: + description: |- + Type decides the type of Load Balancer policy. + Valid LoadBalancerType values are + "ConsistentHash", + "LeastRequest", + "Random", + "RoundRobin". + enum: + - ConsistentHash + - LeastRequest + - Random + - RoundRobin + type: string + required: + - type + type: object + x-kubernetes-validations: + - message: If LoadBalancer type is consistentHash, consistentHash + field needs to be set. + rule: 'self.type == ''ConsistentHash'' ? has(self.consistentHash) + : !has(self.consistentHash)' + - message: Currently SlowStart is only supported for RoundRobin + and LeastRequest load balancers. + rule: 'self.type in [''Random'', ''ConsistentHash''] + ? !has(self.slowStart) : true ' + proxyProtocol: + description: ProxyProtocol enables the Proxy Protocol + when communicating with the backend. + properties: + version: + description: |- + Version of ProxyProtol + Valid ProxyProtocolVersion values are + "V1" + "V2" + enum: + - V1 + - V2 + type: string + required: + - version + type: object + tcpKeepalive: + description: |- + TcpKeepalive settings associated with the upstream client connection. + Disabled by default. + properties: + idleTime: + description: |- + The duration a connection needs to be idle before keep-alive + probes start being sent. + The duration format is + Defaults to `7200s`. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: |- + The duration between keep-alive probes. + Defaults to `75s`. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + probes: + description: |- + The total number of unacknowledged probes to send before deciding + the connection is dead. + Defaults to 9. + format: int32 + type: integer + type: object + timeout: + description: Timeout settings for the backend connections. + properties: + http: + description: Timeout settings for HTTP. + properties: + connectionIdleTimeout: + description: |- + The idle timeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection. + Default: 1 hour. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + maxConnectionDuration: + description: |- + The maximum duration of an HTTP connection. + Default: unlimited. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + tcp: + description: Timeout settings for TCP. + properties: + connectTimeout: + description: |- + The timeout for network connection establishment, including TCP and TLS handshakes. + Default: 10 seconds. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + type: object + type: object headersToBackend: description: |- HeadersToBackend are the authorization response headers that will be added @@ -643,6 +1810,17 @@ spec: x-kubernetes-validations: - message: backendRef or backendRefs needs to be set rule: has(self.backendRef) || self.backendRefs.size() > 0 + - message: BackendRefs must be used, backendRef is not supported. + rule: '!has(self.backendRef)' + - message: Exactly one backendRef can be specified in backendRefs. + rule: has(self.backendRefs) && self.backendRefs.size()==1 + - message: BackendRefs only supports Service and Backend kind. + rule: 'has(self.backendRefs) ? self.backendRefs.all(f, f.kind + == ''Service'' || f.kind == ''Backend'') : true' + - message: BackendRefs only supports Core and gateway.envoyproxy.io + group. + rule: 'has(self.backendRefs) ? (self.backendRefs.all(f, f.group + == "" || f.group == ''gateway.envoyproxy.io'')) : true' type: object x-kubernetes-validations: - message: one of grpc or http must be specified @@ -650,24 +1828,6 @@ spec: - message: only one of grpc or http can be specified rule: (has(self.grpc) && !has(self.http)) || (!has(self.grpc) && has(self.http)) - - message: group is invalid, only the core API group (specified by - omitting the group field or setting it to an empty string) is - supported - rule: 'has(self.grpc) ? (!has(self.grpc.backendRef) || !has(self.grpc.backendRef.group) - || self.grpc.backendRef.group == "") : true' - - message: kind is invalid, only Service (specified by omitting the - kind field or setting it to 'Service') is supported - rule: 'has(self.grpc) ? (!has(self.grpc.backendRef) || !has(self.grpc.backendRef.kind) - || self.grpc.backendRef.kind == ''Service'') : true' - - message: group is invalid, only the core API group (specified by - omitting the group field or setting it to an empty string) is - supported - rule: 'has(self.http) ? (!has(self.http.backendRef) || !has(self.http.backendRef.group) - || self.http.backendRef.group == "") : true' - - message: kind is invalid, only Service (specified by omitting the - kind field or setting it to 'Service') is supported - rule: 'has(self.http) ? (!has(self.http.backendRef) || !has(self.http.backendRef.kind) - || self.http.backendRef.kind == ''Service'') : true' jwt: description: JWT defines the configuration for JSON Web Token (JWT) authentication. diff --git a/examples/extension-server/cmd/extension-server/main.go b/examples/extension-server/cmd/extension-server/main.go index 33e08ddc914..9df1f4a885c 100644 --- a/examples/extension-server/cmd/extension-server/main.go +++ b/examples/extension-server/cmd/extension-server/main.go @@ -13,11 +13,11 @@ import ( "os/signal" "syscall" - pb "github.com/envoyproxy/gateway/proto/extension" + "github.com/exampleorg/envoygateway-extension/internal/extensionserver" "github.com/urfave/cli/v2" "google.golang.org/grpc" - "github.com/exampleorg/envoygateway-extension/internal/extensionserver" + pb "github.com/envoyproxy/gateway/proto/extension" ) func main() { diff --git a/examples/extension-server/go.mod b/examples/extension-server/go.mod index a1c8e2fc44c..f20e9f23ba5 100644 --- a/examples/extension-server/go.mod +++ b/examples/extension-server/go.mod @@ -30,7 +30,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect golang.org/x/net v0.27.0 // indirect - golang.org/x/sys v0.22.0 // indirect + golang.org/x/sys v0.23.0 // indirect golang.org/x/text v0.16.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect diff --git a/examples/extension-server/go.sum b/examples/extension-server/go.sum index e6a6ba81bb1..2b8472bc0a1 100644 --- a/examples/extension-server/go.sum +++ b/examples/extension-server/go.sum @@ -84,8 +84,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= diff --git a/examples/extension-server/internal/extensionserver/server.go b/examples/extension-server/internal/extensionserver/server.go index a2776a9f966..2c060869b88 100644 --- a/examples/extension-server/internal/extensionserver/server.go +++ b/examples/extension-server/internal/extensionserver/server.go @@ -11,15 +11,15 @@ import ( "fmt" "log/slog" - pb "github.com/envoyproxy/gateway/proto/extension" corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" listenerv3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" bav3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/basic_auth/v3" hcm "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" "github.com/envoyproxy/go-control-plane/pkg/wellknown" + "github.com/exampleorg/envoygateway-extension/api/v1alpha1" "google.golang.org/protobuf/types/known/anypb" - "github.com/exampleorg/envoygateway-extension/api/v1alpha1" + pb "github.com/envoyproxy/gateway/proto/extension" ) type Server struct { diff --git a/go.mod b/go.mod index e66adb8a3db..e23ce14fff6 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,7 @@ require ( go.opentelemetry.io/proto/otlp v1.3.1 go.uber.org/zap v1.27.0 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 - golang.org/x/sys v0.22.0 + golang.org/x/sys v0.23.0 google.golang.org/grpc v1.65.0 google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index ed3fe16fab6..cdfd32616df 100644 --- a/go.sum +++ b/go.sum @@ -1447,8 +1447,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= diff --git a/internal/gatewayapi/backendtrafficpolicy.go b/internal/gatewayapi/backendtrafficpolicy.go index 120918a8f6a..d5e66e6e7c0 100644 --- a/internal/gatewayapi/backendtrafficpolicy.go +++ b/internal/gatewayapi/backendtrafficpolicy.go @@ -9,10 +9,8 @@ import ( "errors" "fmt" "math" - "math/big" "sort" "strings" - "time" perr "github.com/pkg/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -307,60 +305,42 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen errs = errors.Join(errs, err) } } - if policy.Spec.LoadBalancer != nil { - if lb, err = t.buildLoadBalancer(policy); err != nil { - err = perr.WithMessage(err, "LoadBalancer") - errs = errors.Join(errs, err) - } + if lb, err = buildLoadBalancer(policy.Spec.ClusterSettings); err != nil { + err = perr.WithMessage(err, "LoadBalancer") + errs = errors.Join(errs, err) } - if policy.Spec.ProxyProtocol != nil { - pp = t.buildProxyProtocol(policy) - } - if policy.Spec.HealthCheck != nil { - hc = t.buildHealthCheck(policy) - } - if policy.Spec.CircuitBreaker != nil { - if cb, err = t.buildCircuitBreaker(policy); err != nil { - err = perr.WithMessage(err, "CircuitBreaker") - errs = errors.Join(errs, err) - } + pp = buildProxyProtocol(policy.Spec.ClusterSettings) + hc = buildHealthCheck(policy.Spec.ClusterSettings) + if cb, err = buildCircuitBreaker(policy.Spec.ClusterSettings); err != nil { + err = perr.WithMessage(err, "CircuitBreaker") + errs = errors.Join(errs, err) } if policy.Spec.FaultInjection != nil { fi = t.buildFaultInjection(policy) } - if policy.Spec.TCPKeepalive != nil { - if ka, err = t.buildTCPKeepAlive(policy); err != nil { - err = perr.WithMessage(err, "TCPKeepalive") - errs = errors.Join(errs, err) - } + if ka, err = buildTCPKeepAlive(policy.Spec.ClusterSettings); err != nil { + err = perr.WithMessage(err, "TCPKeepalive") + errs = errors.Join(errs, err) } if policy.Spec.Retry != nil { rt = t.buildRetry(policy) } - if policy.Spec.Timeout != nil { - if to, err = t.buildTimeout(policy, nil); err != nil { - err = perr.WithMessage(err, "Timeout") - errs = errors.Join(errs, err) - } + if to, err = buildTimeout(policy.Spec.ClusterSettings, nil); err != nil { + err = perr.WithMessage(err, "Timeout") + errs = errors.Join(errs, err) } - if policy.Spec.Connection != nil { - if bc, err = t.buildBackendConnection(policy); err != nil { - err = perr.WithMessage(err, "BackendConnection") - errs = errors.Join(errs, err) - } + if bc, err = buildBackendConnection(policy.Spec.ClusterSettings); err != nil { + err = perr.WithMessage(err, "BackendConnection") + errs = errors.Join(errs, err) } - if policy.Spec.HTTP2 != nil { - if h2, err = buildIRHTTP2Settings(policy.Spec.HTTP2); err != nil { - err = perr.WithMessage(err, "HTTP2") - errs = errors.Join(errs, err) - } + if h2, err = buildIRHTTP2Settings(policy.Spec.HTTP2); err != nil { + err = perr.WithMessage(err, "HTTP2") + errs = errors.Join(errs, err) } - if policy.Spec.DNS != nil { - ds = t.translateDNS(policy) - } + ds = translateDNS(policy.Spec.ClusterSettings) // Early return if got any errors if errs != nil { @@ -414,17 +394,15 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen Retry: rt, BackendConnection: bc, HTTP2: h2, + DNS: ds, } - r.DNS = ds // Update the Host field in HealthCheck, now that we have access to the Route Hostname. r.Traffic.HealthCheck.SetHTTPHostIfAbsent(r.Hostname) // Some timeout setting originate from the route. - if policy.Spec.Timeout != nil { - if to, err = t.buildTimeout(policy, r); err == nil { - r.Traffic.Timeout = to - } + if to, err = buildTimeout(policy.Spec.ClusterSettings, r); err == nil { + r.Traffic.Timeout = to } if policy.Spec.UseClientProtocol != nil { @@ -461,52 +439,36 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back errs = errors.Join(errs, err) } } - if policy.Spec.LoadBalancer != nil { - if lb, err = t.buildLoadBalancer(policy); err != nil { - err = perr.WithMessage(err, "LoadBalancer") - errs = errors.Join(errs, err) - } - } - if policy.Spec.ProxyProtocol != nil { - pp = t.buildProxyProtocol(policy) + if lb, err = buildLoadBalancer(policy.Spec.ClusterSettings); err != nil { + err = perr.WithMessage(err, "LoadBalancer") + errs = errors.Join(errs, err) } - if policy.Spec.HealthCheck != nil { - hc = t.buildHealthCheck(policy) - } - if policy.Spec.CircuitBreaker != nil { - if cb, err = t.buildCircuitBreaker(policy); err != nil { - err = perr.WithMessage(err, "CircuitBreaker") - errs = errors.Join(errs, err) - } + pp = buildProxyProtocol(policy.Spec.ClusterSettings) + hc = buildHealthCheck(policy.Spec.ClusterSettings) + if cb, err = buildCircuitBreaker(policy.Spec.ClusterSettings); err != nil { + err = perr.WithMessage(err, "CircuitBreaker") + errs = errors.Join(errs, err) } if policy.Spec.FaultInjection != nil { fi = t.buildFaultInjection(policy) } - if policy.Spec.TCPKeepalive != nil { - if ka, err = t.buildTCPKeepAlive(policy); err != nil { - err = perr.WithMessage(err, "TCPKeepalive") - errs = errors.Join(errs, err) - } + if ka, err = buildTCPKeepAlive(policy.Spec.ClusterSettings); err != nil { + err = perr.WithMessage(err, "TCPKeepalive") + errs = errors.Join(errs, err) } if policy.Spec.Retry != nil { rt = t.buildRetry(policy) } - if policy.Spec.Timeout != nil { - if ct, err = t.buildTimeout(policy, nil); err != nil { - err = perr.WithMessage(err, "Timeout") - errs = errors.Join(errs, err) - } + if ct, err = buildTimeout(policy.Spec.ClusterSettings, nil); err != nil { + err = perr.WithMessage(err, "Timeout") + errs = errors.Join(errs, err) } - if policy.Spec.HTTP2 != nil { - if h2, err = buildIRHTTP2Settings(policy.Spec.HTTP2); err != nil { - err = perr.WithMessage(err, "HTTP2") - errs = errors.Join(errs, err) - } + if h2, err = buildIRHTTP2Settings(policy.Spec.HTTP2); err != nil { + err = perr.WithMessage(err, "HTTP2") + errs = errors.Join(errs, err) } - if policy.Spec.DNS != nil { - ds = t.translateDNS(policy) - } + ds = translateDNS(policy.Spec.ClusterSettings) // Early return if got any errors if errs != nil { @@ -529,26 +491,15 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back } for _, r := range tcp.Routes { - // policy(targeting xRoute) has already set it, so we skip it. - if r.LoadBalancer != nil || r.ProxyProtocol != nil || - r.HealthCheck != nil || r.CircuitBreaker != nil || - r.TCPKeepalive != nil || r.Timeout != nil { - continue - } - - r.LoadBalancer = lb - r.ProxyProtocol = pp - r.HealthCheck = hc - r.CircuitBreaker = cb - r.TCPKeepalive = ka - - if r.Timeout == nil { - r.Timeout = ct - } - - if r.DNS == nil { - r.DNS = ds - } + // only set attributes which weren't already set by a more + // specific policy + setIfNil(&r.LoadBalancer, lb) + setIfNil(&r.ProxyProtocol, pp) + setIfNil(&r.HealthCheck, hc) + setIfNil(&r.CircuitBreaker, cb) + setIfNil(&r.TCPKeepalive, ka) + setIfNil(&r.Timeout, ct) + setIfNil(&r.DNS, ds) } } @@ -564,19 +515,11 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back route := udp.Route - // policy(targeting xRoute) has already set it, so we skip it. - if route.LoadBalancer != nil || route.Timeout != nil { - continue - } - - route.LoadBalancer = lb - if route.Timeout == nil { - route.Timeout = ct - } - - if route.DNS == nil { - route.DNS = ds - } + // only set attributes which weren't already set by a more + // specific policy + setIfNil(&route.LoadBalancer, lb) + setIfNil(&route.Timeout, ct) + setIfNil(&route.DNS, ds) } for _, http := range x.HTTP { @@ -604,25 +547,18 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back TCPKeepalive: ka, Retry: rt, HTTP2: h2, - } - - if r.DNS == nil { - r.DNS = ds + DNS: ds, } // Update the Host field in HealthCheck, now that we have access to the Route Hostname. r.Traffic.HealthCheck.SetHTTPHostIfAbsent(r.Hostname) - if policy.Spec.Timeout != nil { - if ct, err = t.buildTimeout(policy, r); err == nil { - r.Traffic.Timeout = ct - } + if ct, err = buildTimeout(policy.Spec.ClusterSettings, r); err == nil { + r.Traffic.Timeout = ct } if policy.Spec.UseClientProtocol != nil { - if r.UseClientProtocol == nil { - r.UseClientProtocol = policy.Spec.UseClientProtocol - } + setIfNil(&r.UseClientProtocol, policy.Spec.UseClientProtocol) } } } @@ -815,222 +751,6 @@ func buildRateLimitRule(rule egv1a1.RateLimitRule) (*ir.RateLimitRule, error) { return irRule, nil } -func (t *Translator) buildLoadBalancer(policy *egv1a1.BackendTrafficPolicy) (*ir.LoadBalancer, error) { - var lb *ir.LoadBalancer - switch policy.Spec.LoadBalancer.Type { - case egv1a1.ConsistentHashLoadBalancerType: - consistentHash, err := t.buildConsistentHashLoadBalancer(policy) - if err != nil { - return nil, perr.WithMessage(err, "ConsistentHash") - } - - lb = &ir.LoadBalancer{ - ConsistentHash: consistentHash, - } - case egv1a1.LeastRequestLoadBalancerType: - lb = &ir.LoadBalancer{} - if policy.Spec.LoadBalancer.SlowStart != nil { - if policy.Spec.LoadBalancer.SlowStart.Window != nil { - lb.LeastRequest = &ir.LeastRequest{ - SlowStart: &ir.SlowStart{ - Window: policy.Spec.LoadBalancer.SlowStart.Window, - }, - } - } - } - case egv1a1.RandomLoadBalancerType: - lb = &ir.LoadBalancer{ - Random: &ir.Random{}, - } - case egv1a1.RoundRobinLoadBalancerType: - lb = &ir.LoadBalancer{ - RoundRobin: &ir.RoundRobin{ - SlowStart: &ir.SlowStart{}, - }, - } - if policy.Spec.LoadBalancer.SlowStart != nil { - if policy.Spec.LoadBalancer.SlowStart.Window != nil { - lb.RoundRobin = &ir.RoundRobin{ - SlowStart: &ir.SlowStart{ - Window: policy.Spec.LoadBalancer.SlowStart.Window, - }, - } - } - } - } - - return lb, nil -} - -func (t *Translator) buildConsistentHashLoadBalancer(policy *egv1a1.BackendTrafficPolicy) (*ir.ConsistentHash, error) { - consistentHash := &ir.ConsistentHash{} - - if policy.Spec.LoadBalancer.ConsistentHash.TableSize != nil { - tableSize := policy.Spec.LoadBalancer.ConsistentHash.TableSize - - if *tableSize > MaxConsistentHashTableSize || !big.NewInt(int64(*tableSize)).ProbablyPrime(0) { - return nil, fmt.Errorf("invalid TableSize value %d", *tableSize) - } - - consistentHash.TableSize = tableSize - } - - switch policy.Spec.LoadBalancer.ConsistentHash.Type { - case egv1a1.SourceIPConsistentHashType: - consistentHash.SourceIP = ptr.To(true) - case egv1a1.HeaderConsistentHashType: - consistentHash.Header = &ir.Header{ - Name: policy.Spec.LoadBalancer.ConsistentHash.Header.Name, - } - case egv1a1.CookieConsistentHashType: - consistentHash.Cookie = policy.Spec.LoadBalancer.ConsistentHash.Cookie - } - - return consistentHash, nil -} - -func (t *Translator) translateDNS(policy *egv1a1.BackendTrafficPolicy) *ir.DNS { - ds := &ir.DNS{} - if policy.Spec.DNS.RespectDNSTTL != nil { - ds.RespectDNSTTL = policy.Spec.DNS.RespectDNSTTL - } - if policy.Spec.DNS.DNSRefreshRate != nil { - ds.DNSRefreshRate = policy.Spec.DNS.DNSRefreshRate - } - return ds -} - -func (t *Translator) buildProxyProtocol(policy *egv1a1.BackendTrafficPolicy) *ir.ProxyProtocol { - var pp *ir.ProxyProtocol - switch policy.Spec.ProxyProtocol.Version { - case egv1a1.ProxyProtocolVersionV1: - pp = &ir.ProxyProtocol{ - Version: ir.ProxyProtocolVersionV1, - } - case egv1a1.ProxyProtocolVersionV2: - pp = &ir.ProxyProtocol{ - Version: ir.ProxyProtocolVersionV2, - } - } - - return pp -} - -func (t *Translator) buildHealthCheck(policy *egv1a1.BackendTrafficPolicy) *ir.HealthCheck { - if policy.Spec.HealthCheck == nil { - return nil - } - - irhc := &ir.HealthCheck{} - if policy.Spec.HealthCheck.Passive != nil { - irhc.Passive = t.buildPassiveHealthCheck(policy) - } - - if policy.Spec.HealthCheck.Active != nil { - irhc.Active = t.buildActiveHealthCheck(policy) - } - - return irhc -} - -func (t *Translator) buildPassiveHealthCheck(policy *egv1a1.BackendTrafficPolicy) *ir.OutlierDetection { - if policy.Spec.HealthCheck == nil || policy.Spec.HealthCheck.Passive == nil { - return nil - } - - hc := policy.Spec.HealthCheck.Passive - irOD := &ir.OutlierDetection{ - Interval: hc.Interval, - SplitExternalLocalOriginErrors: hc.SplitExternalLocalOriginErrors, - ConsecutiveLocalOriginFailures: hc.ConsecutiveLocalOriginFailures, - ConsecutiveGatewayErrors: hc.ConsecutiveGatewayErrors, - Consecutive5xxErrors: hc.Consecutive5xxErrors, - BaseEjectionTime: hc.BaseEjectionTime, - MaxEjectionPercent: hc.MaxEjectionPercent, - } - return irOD -} - -func (t *Translator) buildActiveHealthCheck(policy *egv1a1.BackendTrafficPolicy) *ir.ActiveHealthCheck { - if policy.Spec.HealthCheck == nil || policy.Spec.HealthCheck.Active == nil { - return nil - } - - hc := policy.Spec.HealthCheck.Active - irHC := &ir.ActiveHealthCheck{ - Timeout: hc.Timeout, - Interval: hc.Interval, - UnhealthyThreshold: hc.UnhealthyThreshold, - HealthyThreshold: hc.HealthyThreshold, - } - switch hc.Type { - case egv1a1.ActiveHealthCheckerTypeHTTP: - irHC.HTTP = t.buildHTTPActiveHealthChecker(hc.HTTP) - case egv1a1.ActiveHealthCheckerTypeTCP: - irHC.TCP = t.buildTCPActiveHealthChecker(hc.TCP) - } - - return irHC -} - -func (t *Translator) buildHTTPActiveHealthChecker(h *egv1a1.HTTPActiveHealthChecker) *ir.HTTPHealthChecker { - if h == nil { - return nil - } - - irHTTP := &ir.HTTPHealthChecker{ - Path: h.Path, - Method: h.Method, - } - if irHTTP.Method != nil { - *irHTTP.Method = strings.ToUpper(*irHTTP.Method) - } - - // deduplicate http statuses - statusSet := sets.NewInt() - for _, r := range h.ExpectedStatuses { - statusSet.Insert(int(r)) - } - irStatuses := make([]ir.HTTPStatus, 0, statusSet.Len()) - - for _, r := range statusSet.List() { - irStatuses = append(irStatuses, ir.HTTPStatus(r)) - } - irHTTP.ExpectedStatuses = irStatuses - - irHTTP.ExpectedResponse = translateActiveHealthCheckPayload(h.ExpectedResponse) - return irHTTP -} - -func (t *Translator) buildTCPActiveHealthChecker(h *egv1a1.TCPActiveHealthChecker) *ir.TCPHealthChecker { - if h == nil { - return nil - } - - irTCP := &ir.TCPHealthChecker{ - Send: translateActiveHealthCheckPayload(h.Send), - Receive: translateActiveHealthCheckPayload(h.Receive), - } - return irTCP -} - -func translateActiveHealthCheckPayload(p *egv1a1.ActiveHealthCheckPayload) *ir.HealthCheckPayload { - if p == nil { - return nil - } - - irPayload := &ir.HealthCheckPayload{} - switch p.Type { - case egv1a1.ActiveHealthCheckPayloadTypeText: - irPayload.Text = p.Text - case egv1a1.ActiveHealthCheckPayloadTypeBinary: - irPayload.Binary = make([]byte, len(p.Binary)) - copy(irPayload.Binary, p.Binary) - } - - return irPayload -} - func ratelimitUnitToDuration(unit egv1a1.RateLimitUnit) int64 { var seconds int64 @@ -1047,144 +767,6 @@ func ratelimitUnitToDuration(unit egv1a1.RateLimitUnit) int64 { return seconds } -func (t *Translator) buildCircuitBreaker(policy *egv1a1.BackendTrafficPolicy) (*ir.CircuitBreaker, error) { - var cb *ir.CircuitBreaker - pcb := policy.Spec.CircuitBreaker - - if pcb != nil { - cb = &ir.CircuitBreaker{} - - if pcb.MaxConnections != nil { - if ui32, ok := int64ToUint32(*pcb.MaxConnections); ok { - cb.MaxConnections = &ui32 - } else { - return nil, fmt.Errorf("invalid MaxConnections value %d", *pcb.MaxConnections) - } - } - - if pcb.MaxParallelRequests != nil { - if ui32, ok := int64ToUint32(*pcb.MaxParallelRequests); ok { - cb.MaxParallelRequests = &ui32 - } else { - return nil, fmt.Errorf("invalid MaxParallelRequests value %d", *pcb.MaxParallelRequests) - } - } - - if pcb.MaxPendingRequests != nil { - if ui32, ok := int64ToUint32(*pcb.MaxPendingRequests); ok { - cb.MaxPendingRequests = &ui32 - } else { - return nil, fmt.Errorf("invalid MaxPendingRequests value %d", *pcb.MaxPendingRequests) - } - } - - if pcb.MaxParallelRetries != nil { - if ui32, ok := int64ToUint32(*pcb.MaxParallelRetries); ok { - cb.MaxParallelRetries = &ui32 - } else { - return nil, fmt.Errorf("invalid MaxParallelRetries value %d", *pcb.MaxParallelRetries) - } - } - - if pcb.MaxRequestsPerConnection != nil { - if ui32, ok := int64ToUint32(*pcb.MaxRequestsPerConnection); ok { - cb.MaxRequestsPerConnection = &ui32 - } else { - return nil, fmt.Errorf("invalid MaxRequestsPerConnection value %d", *pcb.MaxRequestsPerConnection) - } - } - - } - - return cb, nil -} - -func (t *Translator) buildTimeout(policy *egv1a1.BackendTrafficPolicy, r *ir.HTTPRoute) (*ir.Timeout, error) { - var ( - tto *ir.TCPTimeout - hto *ir.HTTPTimeout - terr bool - errs error - ) - - pto := policy.Spec.Timeout - - if pto.TCP != nil && pto.TCP.ConnectTimeout != nil { - d, err := time.ParseDuration(string(*pto.TCP.ConnectTimeout)) - if err != nil { - terr = true - errs = errors.Join(errs, fmt.Errorf("invalid ConnectTimeout value %s", *pto.TCP.ConnectTimeout)) - } else { - tto = &ir.TCPTimeout{ - ConnectTimeout: ptr.To(metav1.Duration{Duration: d}), - } - } - } - - if pto.HTTP != nil { - var cit *metav1.Duration - var mcd *metav1.Duration - - if pto.HTTP.ConnectionIdleTimeout != nil { - d, err := time.ParseDuration(string(*pto.HTTP.ConnectionIdleTimeout)) - if err != nil { - terr = true - errs = errors.Join(errs, fmt.Errorf("invalid ConnectionIdleTimeout value %s", *pto.HTTP.ConnectionIdleTimeout)) - } else { - cit = ptr.To(metav1.Duration{Duration: d}) - } - } - - if pto.HTTP.MaxConnectionDuration != nil { - d, err := time.ParseDuration(string(*pto.HTTP.MaxConnectionDuration)) - if err != nil { - terr = true - errs = errors.Join(errs, fmt.Errorf("invalid MaxConnectionDuration value %s", *pto.HTTP.MaxConnectionDuration)) - } else { - mcd = ptr.To(metav1.Duration{Duration: d}) - } - } - - hto = &ir.HTTPTimeout{ - ConnectionIdleTimeout: cit, - MaxConnectionDuration: mcd, - } - } - - // http request timeout is translated during the gateway-api route resource translation - // merge route timeout setting with backendtrafficpolicy timeout settings - if terr { - if r != nil && r.Traffic != nil && r.Traffic.Timeout != nil { - return r.Traffic.Timeout.DeepCopy(), errs - } - } else { - // http request timeout is translated during the gateway-api route resource translation - // merge route timeout setting with backendtrafficpolicy timeout settings - if r != nil && - r.Traffic != nil && - r.Traffic.Timeout != nil && - r.Traffic.Timeout.HTTP != nil && - r.Traffic.Timeout.HTTP.RequestTimeout != nil { - if hto == nil { - hto = &ir.HTTPTimeout{ - RequestTimeout: r.Traffic.Timeout.HTTP.RequestTimeout, - } - } else { - hto.RequestTimeout = r.Traffic.Timeout.HTTP.RequestTimeout - } - } - - if hto != nil || tto != nil { - return &ir.Timeout{ - TCP: tto, - HTTP: hto, - }, nil - } - } - - return nil, errs -} - func int64ToUint32(in int64) (uint32, bool) { if in >= 0 && in <= math.MaxUint32 { return uint32(in), true @@ -1192,31 +774,6 @@ func int64ToUint32(in int64) (uint32, bool) { return 0, false } -func (t *Translator) buildBackendConnection(policy *egv1a1.BackendTrafficPolicy) (*ir.BackendConnection, error) { - var ( - bcIR = &ir.BackendConnection{} - bc = &egv1a1.BackendConnection{} - ) - - if policy.Spec.Connection != nil { - bc = policy.Spec.Connection - - if bc.BufferLimit != nil { - bf, ok := bc.BufferLimit.AsInt64() - if !ok { - return nil, fmt.Errorf("invalid BufferLimit value %s", bc.BufferLimit.String()) - } - if bf < 0 || bf > math.MaxUint32 { - return nil, fmt.Errorf("BufferLimit value %s is out of range", bc.BufferLimit.String()) - } - - bcIR.BufferLimitBytes = ptr.To(uint32(bf)) - } - } - - return bcIR, nil -} - func (t *Translator) buildFaultInjection(policy *egv1a1.BackendTrafficPolicy) *ir.FaultInjection { var fi *ir.FaultInjection if policy.Spec.FaultInjection != nil { @@ -1244,36 +801,6 @@ func (t *Translator) buildFaultInjection(policy *egv1a1.BackendTrafficPolicy) *i return fi } -func (t *Translator) buildTCPKeepAlive(policy *egv1a1.BackendTrafficPolicy) (*ir.TCPKeepalive, error) { - var ka *ir.TCPKeepalive - if policy.Spec.TCPKeepalive != nil { - pka := policy.Spec.TCPKeepalive - ka = &ir.TCPKeepalive{} - - if pka.Probes != nil { - ka.Probes = pka.Probes - } - - if pka.IdleTime != nil { - d, err := time.ParseDuration(string(*pka.IdleTime)) - if err != nil { - return nil, fmt.Errorf("invalid IdleTime value %s", *pka.IdleTime) - } - ka.IdleTime = ptr.To(uint32(d.Seconds())) - } - - if pka.Interval != nil { - d, err := time.ParseDuration(string(*pka.Interval)) - if err != nil { - return nil, fmt.Errorf("invalid Interval value %s", *pka.Interval) - } - ka.Interval = ptr.To(uint32(d.Seconds())) - } - - } - return ka, nil -} - func (t *Translator) buildRetry(policy *egv1a1.BackendTrafficPolicy) *ir.Retry { var rt *ir.Retry if policy.Spec.Retry != nil { diff --git a/internal/gatewayapi/clienttrafficpolicy.go b/internal/gatewayapi/clienttrafficpolicy.go index 1d7e8e89a84..c1877ffa653 100644 --- a/internal/gatewayapi/clienttrafficpolicy.go +++ b/internal/gatewayapi/clienttrafficpolicy.go @@ -417,7 +417,7 @@ func (t *Translator) translateClientTrafficPolicyForListener(policy *egv1a1.Clie } // Translate Proxy Protocol - enableProxyProtocol = buildProxyProtocol(policy.Spec.EnableProxyProtocol) + enableProxyProtocol = ptr.Deref(policy.Spec.EnableProxyProtocol, false) // Translate Client Timeout Settings timeout, err = buildClientTimeout(policy.Spec.Timeout) @@ -604,14 +604,6 @@ func buildClientTimeout(clientTimeout *egv1a1.ClientTimeout) (*ir.ClientTimeout, return irClientTimeout, nil } -func buildProxyProtocol(enableProxyProtocol *bool) bool { - if enableProxyProtocol != nil && *enableProxyProtocol { - return true - } - - return false -} - func translateClientIPDetection(clientIPDetection *egv1a1.ClientIPDetectionSettings, httpIR *ir.HTTPListener) { // Return early if not set if clientIPDetection == nil { diff --git a/internal/gatewayapi/clustersettings.go b/internal/gatewayapi/clustersettings.go new file mode 100644 index 00000000000..3034fed1324 --- /dev/null +++ b/internal/gatewayapi/clustersettings.go @@ -0,0 +1,500 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +package gatewayapi + +import ( + "errors" + "fmt" + "math" + "math/big" + "strings" + "time" + + perr "github.com/pkg/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/utils/ptr" + + egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/ir" +) + +func translateTrafficFeatures(policy *egv1a1.ClusterSettings) (*ir.TrafficFeatures, error) { + if policy == nil { + return nil, nil + } + ret := &ir.TrafficFeatures{} + + if timeout, err := buildTimeout(*policy, nil); err != nil { + return nil, err + } else { + ret.Timeout = timeout + } + + if bc, err := buildBackendConnection(*policy); err != nil { + return nil, err + } else { + ret.BackendConnection = bc + } + + if ka, err := buildTCPKeepAlive(*policy); err != nil { + return nil, err + } else { + ret.TCPKeepalive = ka + } + + if cb, err := buildCircuitBreaker(*policy); err != nil { + return nil, err + } else { + ret.CircuitBreaker = cb + } + + if lb, err := buildLoadBalancer(*policy); err != nil { + return nil, err + } else { + ret.LoadBalancer = lb + } + + ret.ProxyProtocol = buildProxyProtocol(*policy) + + ret.HealthCheck = buildHealthCheck(*policy) + + ret.DNS = translateDNS(*policy) + + if h2, err := buildIRHTTP2Settings(policy.HTTP2); err != nil { + return nil, err + } else { + ret.HTTP2 = h2 + } + + // If nothing was set in any of the above calls, return nil instead of an empty + // container + var empty ir.TrafficFeatures + if empty == *ret { + ret = nil + } + + return ret, nil +} + +func buildTimeout(policy egv1a1.ClusterSettings, r *ir.HTTPRoute) (*ir.Timeout, error) { + if policy.Timeout == nil { + return nil, nil + } + var ( + tto *ir.TCPTimeout + hto *ir.HTTPTimeout + terr bool + errs error + ) + + pto := policy.Timeout + + if pto.TCP != nil && pto.TCP.ConnectTimeout != nil { + d, err := time.ParseDuration(string(*pto.TCP.ConnectTimeout)) + if err != nil { + terr = true + errs = errors.Join(errs, fmt.Errorf("invalid ConnectTimeout value %s", *pto.TCP.ConnectTimeout)) + } else { + tto = &ir.TCPTimeout{ + ConnectTimeout: ptr.To(metav1.Duration{Duration: d}), + } + } + } + + if pto.HTTP != nil { + var cit *metav1.Duration + var mcd *metav1.Duration + + if pto.HTTP.ConnectionIdleTimeout != nil { + d, err := time.ParseDuration(string(*pto.HTTP.ConnectionIdleTimeout)) + if err != nil { + terr = true + errs = errors.Join(errs, fmt.Errorf("invalid ConnectionIdleTimeout value %s", *pto.HTTP.ConnectionIdleTimeout)) + } else { + cit = ptr.To(metav1.Duration{Duration: d}) + } + } + + if pto.HTTP.MaxConnectionDuration != nil { + d, err := time.ParseDuration(string(*pto.HTTP.MaxConnectionDuration)) + if err != nil { + terr = true + errs = errors.Join(errs, fmt.Errorf("invalid MaxConnectionDuration value %s", *pto.HTTP.MaxConnectionDuration)) + } else { + mcd = ptr.To(metav1.Duration{Duration: d}) + } + } + + hto = &ir.HTTPTimeout{ + ConnectionIdleTimeout: cit, + MaxConnectionDuration: mcd, + } + } + + // http request timeout is translated during the gateway-api route resource translation + // merge route timeout setting with backendtrafficpolicy timeout settings + if terr { + if r != nil && r.Traffic != nil && r.Traffic.Timeout != nil { + return r.Traffic.Timeout.DeepCopy(), errs + } + } else { + // http request timeout is translated during the gateway-api route resource translation + // merge route timeout setting with backendtrafficpolicy timeout settings + if r != nil && + r.Traffic != nil && + r.Traffic.Timeout != nil && + r.Traffic.Timeout.HTTP != nil && + r.Traffic.Timeout.HTTP.RequestTimeout != nil { + if hto == nil { + hto = &ir.HTTPTimeout{ + RequestTimeout: r.Traffic.Timeout.HTTP.RequestTimeout, + } + } else { + hto.RequestTimeout = r.Traffic.Timeout.HTTP.RequestTimeout + } + } + + if hto != nil || tto != nil { + return &ir.Timeout{ + TCP: tto, + HTTP: hto, + }, nil + } + } + + return nil, errs +} + +func buildBackendConnection(policy egv1a1.ClusterSettings) (*ir.BackendConnection, error) { + if policy.Connection == nil { + return nil, nil + } + var ( + bcIR = &ir.BackendConnection{} + bc = &egv1a1.BackendConnection{} + ) + + if policy.Connection != nil { + bc = policy.Connection + + if bc.BufferLimit != nil { + bf, ok := bc.BufferLimit.AsInt64() + if !ok { + return nil, fmt.Errorf("invalid BufferLimit value %s", bc.BufferLimit.String()) + } + if bf < 0 || bf > math.MaxUint32 { + return nil, fmt.Errorf("BufferLimit value %s is out of range", bc.BufferLimit.String()) + } + + bcIR.BufferLimitBytes = ptr.To(uint32(bf)) + } + } + + return bcIR, nil +} + +func buildTCPKeepAlive(policy egv1a1.ClusterSettings) (*ir.TCPKeepalive, error) { + if policy.TCPKeepalive == nil { + return nil, nil + } + + pka := policy.TCPKeepalive + ka := &ir.TCPKeepalive{} + + if pka.Probes != nil { + ka.Probes = pka.Probes + } + + if pka.IdleTime != nil { + d, err := time.ParseDuration(string(*pka.IdleTime)) + if err != nil { + return nil, fmt.Errorf("invalid IdleTime value %s", *pka.IdleTime) + } + ka.IdleTime = ptr.To(uint32(d.Seconds())) + } + + if pka.Interval != nil { + d, err := time.ParseDuration(string(*pka.Interval)) + if err != nil { + return nil, fmt.Errorf("invalid Interval value %s", *pka.Interval) + } + ka.Interval = ptr.To(uint32(d.Seconds())) + } + return ka, nil +} + +func buildCircuitBreaker(policy egv1a1.ClusterSettings) (*ir.CircuitBreaker, error) { + if policy.CircuitBreaker == nil { + return nil, nil + } + + var cb *ir.CircuitBreaker + pcb := policy.CircuitBreaker + + if pcb != nil { + cb = &ir.CircuitBreaker{} + + if pcb.MaxConnections != nil { + if ui32, ok := int64ToUint32(*pcb.MaxConnections); ok { + cb.MaxConnections = &ui32 + } else { + return nil, fmt.Errorf("invalid MaxConnections value %d", *pcb.MaxConnections) + } + } + + if pcb.MaxParallelRequests != nil { + if ui32, ok := int64ToUint32(*pcb.MaxParallelRequests); ok { + cb.MaxParallelRequests = &ui32 + } else { + return nil, fmt.Errorf("invalid MaxParallelRequests value %d", *pcb.MaxParallelRequests) + } + } + + if pcb.MaxPendingRequests != nil { + if ui32, ok := int64ToUint32(*pcb.MaxPendingRequests); ok { + cb.MaxPendingRequests = &ui32 + } else { + return nil, fmt.Errorf("invalid MaxPendingRequests value %d", *pcb.MaxPendingRequests) + } + } + + if pcb.MaxParallelRetries != nil { + if ui32, ok := int64ToUint32(*pcb.MaxParallelRetries); ok { + cb.MaxParallelRetries = &ui32 + } else { + return nil, fmt.Errorf("invalid MaxParallelRetries value %d", *pcb.MaxParallelRetries) + } + } + + if pcb.MaxRequestsPerConnection != nil { + if ui32, ok := int64ToUint32(*pcb.MaxRequestsPerConnection); ok { + cb.MaxRequestsPerConnection = &ui32 + } else { + return nil, fmt.Errorf("invalid MaxRequestsPerConnection value %d", *pcb.MaxRequestsPerConnection) + } + } + + } + + return cb, nil +} + +func buildLoadBalancer(policy egv1a1.ClusterSettings) (*ir.LoadBalancer, error) { + if policy.LoadBalancer == nil { + return nil, nil + } + var lb *ir.LoadBalancer + switch policy.LoadBalancer.Type { + case egv1a1.ConsistentHashLoadBalancerType: + consistentHash, err := buildConsistentHashLoadBalancer(*policy.LoadBalancer) + if err != nil { + return nil, perr.WithMessage(err, "ConsistentHash") + } + + lb = &ir.LoadBalancer{ + ConsistentHash: consistentHash, + } + case egv1a1.LeastRequestLoadBalancerType: + lb = &ir.LoadBalancer{} + if policy.LoadBalancer.SlowStart != nil { + if policy.LoadBalancer.SlowStart.Window != nil { + lb.LeastRequest = &ir.LeastRequest{ + SlowStart: &ir.SlowStart{ + Window: policy.LoadBalancer.SlowStart.Window, + }, + } + } + } + case egv1a1.RandomLoadBalancerType: + lb = &ir.LoadBalancer{ + Random: &ir.Random{}, + } + case egv1a1.RoundRobinLoadBalancerType: + lb = &ir.LoadBalancer{ + RoundRobin: &ir.RoundRobin{ + SlowStart: &ir.SlowStart{}, + }, + } + if policy.LoadBalancer.SlowStart != nil { + if policy.LoadBalancer.SlowStart.Window != nil { + lb.RoundRobin = &ir.RoundRobin{ + SlowStart: &ir.SlowStart{ + Window: policy.LoadBalancer.SlowStart.Window, + }, + } + } + } + } + + return lb, nil +} + +func buildConsistentHashLoadBalancer(policy egv1a1.LoadBalancer) (*ir.ConsistentHash, error) { + consistentHash := &ir.ConsistentHash{} + + if policy.ConsistentHash.TableSize != nil { + tableSize := policy.ConsistentHash.TableSize + + if *tableSize > MaxConsistentHashTableSize || !big.NewInt(int64(*tableSize)).ProbablyPrime(0) { + return nil, fmt.Errorf("invalid TableSize value %d", *tableSize) + } + + consistentHash.TableSize = tableSize + } + + switch policy.ConsistentHash.Type { + case egv1a1.SourceIPConsistentHashType: + consistentHash.SourceIP = ptr.To(true) + case egv1a1.HeaderConsistentHashType: + consistentHash.Header = &ir.Header{ + Name: policy.ConsistentHash.Header.Name, + } + case egv1a1.CookieConsistentHashType: + consistentHash.Cookie = policy.ConsistentHash.Cookie + } + + return consistentHash, nil +} + +func buildProxyProtocol(policy egv1a1.ClusterSettings) *ir.ProxyProtocol { + if policy.ProxyProtocol == nil { + return nil + } + var pp *ir.ProxyProtocol + switch policy.ProxyProtocol.Version { + case egv1a1.ProxyProtocolVersionV1: + pp = &ir.ProxyProtocol{ + Version: ir.ProxyProtocolVersionV1, + } + case egv1a1.ProxyProtocolVersionV2: + pp = &ir.ProxyProtocol{ + Version: ir.ProxyProtocolVersionV2, + } + } + + return pp +} + +func buildHealthCheck(policy egv1a1.ClusterSettings) *ir.HealthCheck { + if policy.HealthCheck == nil { + return nil + } + + irhc := &ir.HealthCheck{} + irhc.Passive = buildPassiveHealthCheck(*policy.HealthCheck) + irhc.Active = buildActiveHealthCheck(*policy.HealthCheck) + + return irhc +} + +func buildPassiveHealthCheck(policy egv1a1.HealthCheck) *ir.OutlierDetection { + if policy.Passive == nil { + return nil + } + + hc := policy.Passive + irOD := &ir.OutlierDetection{ + Interval: hc.Interval, + SplitExternalLocalOriginErrors: hc.SplitExternalLocalOriginErrors, + ConsecutiveLocalOriginFailures: hc.ConsecutiveLocalOriginFailures, + ConsecutiveGatewayErrors: hc.ConsecutiveGatewayErrors, + Consecutive5xxErrors: hc.Consecutive5xxErrors, + BaseEjectionTime: hc.BaseEjectionTime, + MaxEjectionPercent: hc.MaxEjectionPercent, + } + return irOD +} + +func buildActiveHealthCheck(policy egv1a1.HealthCheck) *ir.ActiveHealthCheck { + if policy.Active == nil { + return nil + } + + hc := policy.Active + irHC := &ir.ActiveHealthCheck{ + Timeout: hc.Timeout, + Interval: hc.Interval, + UnhealthyThreshold: hc.UnhealthyThreshold, + HealthyThreshold: hc.HealthyThreshold, + } + switch hc.Type { + case egv1a1.ActiveHealthCheckerTypeHTTP: + irHC.HTTP = buildHTTPActiveHealthChecker(hc.HTTP) + case egv1a1.ActiveHealthCheckerTypeTCP: + irHC.TCP = buildTCPActiveHealthChecker(hc.TCP) + } + + return irHC +} + +func buildHTTPActiveHealthChecker(h *egv1a1.HTTPActiveHealthChecker) *ir.HTTPHealthChecker { + if h == nil { + return nil + } + + irHTTP := &ir.HTTPHealthChecker{ + Path: h.Path, + Method: h.Method, + } + if irHTTP.Method != nil { + *irHTTP.Method = strings.ToUpper(*irHTTP.Method) + } + + // deduplicate http statuses + statusSet := sets.NewInt() + for _, r := range h.ExpectedStatuses { + statusSet.Insert(int(r)) + } + irStatuses := make([]ir.HTTPStatus, 0, statusSet.Len()) + + for _, r := range statusSet.List() { + irStatuses = append(irStatuses, ir.HTTPStatus(r)) + } + irHTTP.ExpectedStatuses = irStatuses + + irHTTP.ExpectedResponse = translateActiveHealthCheckPayload(h.ExpectedResponse) + return irHTTP +} + +func buildTCPActiveHealthChecker(h *egv1a1.TCPActiveHealthChecker) *ir.TCPHealthChecker { + if h == nil { + return nil + } + + irTCP := &ir.TCPHealthChecker{ + Send: translateActiveHealthCheckPayload(h.Send), + Receive: translateActiveHealthCheckPayload(h.Receive), + } + return irTCP +} + +func translateActiveHealthCheckPayload(p *egv1a1.ActiveHealthCheckPayload) *ir.HealthCheckPayload { + if p == nil { + return nil + } + + irPayload := &ir.HealthCheckPayload{} + switch p.Type { + case egv1a1.ActiveHealthCheckPayloadTypeText: + irPayload.Text = p.Text + case egv1a1.ActiveHealthCheckPayloadTypeBinary: + irPayload.Binary = make([]byte, len(p.Binary)) + copy(irPayload.Binary, p.Binary) + } + + return irPayload +} + +func translateDNS(policy egv1a1.ClusterSettings) *ir.DNS { + if policy.DNS == nil { + return nil + } + return &ir.DNS{ + RespectDNSTTL: policy.DNS.RespectDNSTTL, + DNSRefreshRate: policy.DNS.DNSRefreshRate, + } +} diff --git a/internal/gatewayapi/envoyextensionpolicy.go b/internal/gatewayapi/envoyextensionpolicy.go index 5f871a6f8c0..2bf37c576b5 100644 --- a/internal/gatewayapi/envoyextensionpolicy.go +++ b/internal/gatewayapi/envoyextensionpolicy.go @@ -471,9 +471,15 @@ func (t *Translator) buildExtProc( NamespaceDerefOr(extProc.BackendRefs[0].Namespace, policyNamespacedName.Namespace)) } + traffic, err := translateTrafficFeatures(extProc.BackendCluster.BackendSettings) + if err != nil { + return nil, err + } + extProcIR := &ir.ExtProc{ Name: name, Destination: rd, + Traffic: traffic, Authority: authority, } diff --git a/internal/gatewayapi/helpers.go b/internal/gatewayapi/helpers.go index 22c81032ebb..a29736216bc 100644 --- a/internal/gatewayapi/helpers.go +++ b/internal/gatewayapi/helpers.go @@ -560,3 +560,10 @@ func getPolicyTargetRefs[T client.Object](policy egv1a1.PolicyTargetReferences, return ret } + +// Sets *target to value if and only if *target is nil +func setIfNil[T any](target **T, value *T) { + if *target == nil { + *target = value + } +} diff --git a/internal/gatewayapi/http.go b/internal/gatewayapi/http.go index 95b0cd6310e..e54b3f761d7 100644 --- a/internal/gatewayapi/http.go +++ b/internal/gatewayapi/http.go @@ -23,6 +23,9 @@ const ( ) func buildIRHTTP2Settings(http2Settings *egv1a1.HTTP2Settings) (*ir.HTTP2Settings, error) { + if http2Settings == nil { + return nil, nil + } var ( http2 = &ir.HTTP2Settings{} errs error diff --git a/internal/gatewayapi/listener.go b/internal/gatewayapi/listener.go index adbd302b957..b63645a85e1 100644 --- a/internal/gatewayapi/listener.go +++ b/internal/gatewayapi/listener.go @@ -313,7 +313,7 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources * } // TODO: how to get authority from the backendRefs? - ds, err := t.processBackendRefs(sink.ALS.BackendRefs, envoyproxy.Namespace, resources, envoyproxy) + ds, traffic, err := t.processBackendRefs(sink.ALS.BackendCluster, envoyproxy.Namespace, resources, envoyproxy) if err != nil { return nil, err } @@ -324,6 +324,7 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources * Name: fmt.Sprintf("accesslog_als_%d_%d", i, j), // TODO: rename this, so that we can share backend with tracing? Settings: ds, }, + Traffic: traffic, Type: sink.ALS.Type, CELMatches: validExprs, } @@ -350,20 +351,20 @@ func (t *Translator) processAccessLog(envoyproxy *egv1a1.EnvoyProxy, resources * continue } - // TODO: remove support for Host/Port in v1.2 - al := &ir.OpenTelemetryAccessLog{ - CELMatches: validExprs, - Resources: sink.OpenTelemetry.Resources, - } - // TODO: how to get authority from the backendRefs? - ds, err := t.processBackendRefs(sink.OpenTelemetry.BackendRefs, envoyproxy.Namespace, resources, envoyproxy) + ds, traffic, err := t.processBackendRefs(sink.OpenTelemetry.BackendCluster, envoyproxy.Namespace, resources, envoyproxy) if err != nil { return nil, err } - al.Destination = ir.RouteDestination{ - Name: fmt.Sprintf("accesslog_otel_%d_%d", i, j), // TODO: rename this, so that we can share backend with tracing? - Settings: ds, + // TODO: remove support for Host/Port in v1.2 + al := &ir.OpenTelemetryAccessLog{ + CELMatches: validExprs, + Resources: sink.OpenTelemetry.Resources, + Destination: ir.RouteDestination{ + Name: fmt.Sprintf("accesslog_otel_%d_%d", i, j), // TODO: rename this, so that we can share backend with tracing? + Settings: ds, + }, + Traffic: traffic, } if len(ds) == 0 { @@ -401,7 +402,7 @@ func (t *Translator) processTracing(gw *gwapiv1.Gateway, envoyproxy *egv1a1.Envo tracing := envoyproxy.Spec.Telemetry.Tracing // TODO: how to get authority from the backendRefs? - ds, err := t.processBackendRefs(tracing.Provider.BackendRefs, envoyproxy.Namespace, resources, envoyproxy) + ds, traffic, err := t.processBackendRefs(tracing.Provider.BackendCluster, envoyproxy.Namespace, resources, envoyproxy) if err != nil { return nil, err } @@ -440,6 +441,7 @@ func (t *Translator) processTracing(gw *gwapiv1.Gateway, envoyproxy *egv1a1.Envo Settings: ds, }, Provider: tracing.Provider, + Traffic: traffic, }, nil } @@ -455,7 +457,7 @@ func (t *Translator) processMetrics(envoyproxy *egv1a1.EnvoyProxy, resources *Re continue } - _, err := t.processBackendRefs(sink.OpenTelemetry.BackendRefs, envoyproxy.Namespace, resources, envoyproxy) + _, _, err := t.processBackendRefs(sink.OpenTelemetry.BackendCluster, envoyproxy.Namespace, resources, envoyproxy) if err != nil { return nil, err } @@ -467,25 +469,29 @@ func (t *Translator) processMetrics(envoyproxy *egv1a1.EnvoyProxy, resources *Re }, nil } -func (t *Translator) processBackendRefs(backendRefs []egv1a1.BackendRef, namespace string, resources *Resources, envoyProxy *egv1a1.EnvoyProxy) ([]*ir.DestinationSetting, error) { - result := make([]*ir.DestinationSetting, 0, len(backendRefs)) - for _, ref := range backendRefs { +func (t *Translator) processBackendRefs(backendCluster egv1a1.BackendCluster, namespace string, resources *Resources, envoyProxy *egv1a1.EnvoyProxy) ([]*ir.DestinationSetting, *ir.TrafficFeatures, error) { + traffic, err := translateTrafficFeatures(backendCluster.BackendSettings) + if err != nil { + return nil, nil, err + } + result := make([]*ir.DestinationSetting, 0, len(backendCluster.BackendRefs)) + for _, ref := range backendCluster.BackendRefs { ns := NamespaceDerefOr(ref.Namespace, namespace) kind := KindDerefOr(ref.Kind, KindService) if kind != KindService { - return nil, errors.New("only service kind is supported for backendRefs") + return nil, nil, errors.New("only service kind is supported for backendRefs") } if err := validateBackendService(ref.BackendObjectReference, resources, ns, corev1.ProtocolTCP); err != nil { - return nil, err + return nil, nil, err } ds := t.processServiceDestinationSetting(ref.BackendObjectReference, ns, ir.TCP, resources, envoyProxy) result = append(result, ds) } if len(result) == 0 { - return nil, nil + return nil, traffic, nil } - return result, nil + return result, traffic, nil } func destinationSettingFromHostAndPort(host string, port uint32) []*ir.DestinationSetting { diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go index 336e931cfce..8a3c0272276 100644 --- a/internal/gatewayapi/route.go +++ b/internal/gatewayapi/route.go @@ -314,12 +314,60 @@ func (t *Translator) processHTTPRouteRule(httpRoute *HTTPRouteContext, ruleIdx i ruleRoutes = append(ruleRoutes, irRoute) } + var sessionPersistence *ir.SessionPersistence + if rule.SessionPersistence != nil { + if rule.SessionPersistence.IdleTimeout != nil { + return nil, fmt.Errorf("idle timeout is not supported in envoy gateway") + } + + var sessionName string + if rule.SessionPersistence.SessionName == nil { + // SessionName is optional on the gateway-api, but envoy requires it + // so we generate the one here. + + // We generate a unique session name per route. + // `/` isn't allowed in the header key, so we just replace it with `-`. + sessionName = strings.ReplaceAll(irRouteDestinationName(httpRoute, ruleIdx), "/", "-") + } else { + sessionName = *rule.SessionPersistence.SessionName + } + + switch { + case rule.SessionPersistence.Type == nil || // Cookie-based session persistence is default. + *rule.SessionPersistence.Type == gwapiv1.CookieBasedSessionPersistence: + sessionPersistence = &ir.SessionPersistence{ + Cookie: &ir.CookieBasedSessionPersistence{ + Name: sessionName, + }, + } + if rule.SessionPersistence.AbsoluteTimeout != nil && + rule.SessionPersistence.CookieConfig != nil && rule.SessionPersistence.CookieConfig.LifetimeType != nil && + *rule.SessionPersistence.CookieConfig.LifetimeType == gwapiv1.PermanentCookieLifetimeType { + ttl, err := time.ParseDuration(string(*rule.SessionPersistence.AbsoluteTimeout)) + if err != nil { + return nil, err + } + sessionPersistence.Cookie.TTL = &metav1.Duration{Duration: ttl} + } + case *rule.SessionPersistence.Type == gwapiv1.HeaderBasedSessionPersistence: + sessionPersistence = &ir.SessionPersistence{ + Header: &ir.HeaderBasedSessionPersistence{ + Name: sessionName, + }, + } + default: + // Unknown session persistence type is specified. + return nil, fmt.Errorf("unknown session persistence type %s", *rule.SessionPersistence.Type) + } + } + // A rule is matched if any one of its matches // is satisfied (i.e. a logical "OR"), so generate // a unique Xds IR HTTPRoute per match. for matchIdx, match := range rule.Matches { irRoute := &ir.HTTPRoute{ - Name: irRouteName(httpRoute, ruleIdx, matchIdx), + Name: irRouteName(httpRoute, ruleIdx, matchIdx), + SessionPersistence: sessionPersistence, } processTimeout(irRoute, rule) @@ -699,6 +747,7 @@ func (t *Translator) processHTTPRouteParentRefListener(route RouteContext, route Mirrors: routeRoute.Mirrors, ExtensionRefs: routeRoute.ExtensionRefs, IsHTTP2: routeRoute.IsHTTP2, + SessionPersistence: routeRoute.SessionPersistence, } if routeRoute.Traffic != nil { hostRoute.Traffic = &ir.TrafficFeatures{ diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go index d071e4ffdda..125505aa5ad 100644 --- a/internal/gatewayapi/securitypolicy.go +++ b/internal/gatewayapi/securitypolicy.go @@ -813,6 +813,7 @@ func (t *Translator) buildExtAuth(policy *egv1a1.SecurityPolicy, resources *Reso ds *ir.DestinationSetting authority string err error + traffic *ir.TrafficFeatures ) switch { @@ -826,12 +827,18 @@ func (t *Translator) buildExtAuth(policy *egv1a1.SecurityPolicy, resources *Reso backendRef = egv1a1.ToBackendObjectReference(http.BackendRefs[0]) } protocol = ir.HTTP + if traffic, err = translateTrafficFeatures(http.BackendSettings); err != nil { + return nil, err + } case grpc != nil: backendRef = grpc.BackendRef if len(grpc.BackendRefs) != 0 { backendRef = egv1a1.ToBackendObjectReference(grpc.BackendRefs[0]) } protocol = ir.GRPC + if traffic, err = translateTrafficFeatures(grpc.BackendSettings); err != nil { + return nil, err + } // These are sanity checks, they should never happen because the API server // should have caught them default: // http == nil && grpc == nil: @@ -841,11 +848,8 @@ func (t *Translator) buildExtAuth(policy *egv1a1.SecurityPolicy, resources *Reso if err = t.validateExtServiceBackendReference(backendRef, policy.Namespace, policy.Kind, resources); err != nil { return nil, err } - authority = fmt.Sprintf("%s.%s:%d", - backendRef.Name, - NamespaceDerefOr(backendRef.Namespace, policy.Namespace), - *backendRef.Port) + authority = backendRefAuthority(resources, backendRef, policy) pnn := utils.NamespacedName(policy) if ds, err = t.processExtServiceDestination( backendRef, @@ -866,6 +870,7 @@ func (t *Translator) buildExtAuth(policy *egv1a1.SecurityPolicy, resources *Reso Name: irConfigName(policy), HeadersToExtAuth: policy.Spec.ExtAuth.HeadersToExtAuth, FailOpen: policy.Spec.ExtAuth.FailOpen, + Traffic: traffic, } if http != nil { @@ -884,6 +889,31 @@ func (t *Translator) buildExtAuth(policy *egv1a1.SecurityPolicy, resources *Reso return extAuth, nil } +func backendRefAuthority(resources *Resources, backendRef *gwapiv1.BackendObjectReference, policy *egv1a1.SecurityPolicy) string { + if backendRef == nil { + return "" + } + + backendNamespace := NamespaceDerefOr(backendRef.Namespace, policy.Namespace) + backendKind := KindDerefOr(backendRef.Kind, KindService) + if backendKind == egv1a1.KindBackend { + backend := resources.GetBackend(backendNamespace, string(backendRef.Name)) + if backend != nil { + // TODO: exists multi FQDN endpoints? + for _, ep := range backend.Spec.Endpoints { + if ep.FQDN != nil { + return fmt.Sprintf("%s:%d", ep.FQDN.Hostname, ep.FQDN.Port) + } + } + } + } + + return fmt.Sprintf("%s.%s:%d", + backendRef.Name, + backendNamespace, + *backendRef.Port) +} + func irExtServiceDestinationName(policy *egv1a1.SecurityPolicy, backendRef *gwapiv1.BackendObjectReference) string { nn := types.NamespacedName{ Name: string(backendRef.Name), diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-dns-settings.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-dns-settings.out.yaml index 89d9902328f..12bbf12dbe7 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-dns-settings.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-dns-settings.out.yaml @@ -342,9 +342,6 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - dns: - dnsRefreshRate: 10s - respectDnsTtl: true hostname: gateway.envoyproxy.io isHTTP2: false metadata: @@ -356,7 +353,10 @@ xdsIR: distinct: false name: "" prefix: /v3 - traffic: {} + traffic: + dns: + dnsRefreshRate: 10s + respectDnsTtl: true envoy-gateway/gateway-2: accessLog: text: @@ -386,9 +386,6 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - dns: - dnsRefreshRate: 5s - respectDnsTtl: false hostname: gateway.envoyproxy.io isHTTP2: false metadata: @@ -400,7 +397,10 @@ xdsIR: distinct: false name: "" prefix: /v2 - traffic: {} + traffic: + dns: + dnsRefreshRate: 5s + respectDnsTtl: false - destination: name: httproute/default/httproute-1/rule/0 settings: @@ -410,9 +410,6 @@ xdsIR: port: 8080 protocol: HTTP weight: 1 - dns: - dnsRefreshRate: 1s - respectDnsTtl: true hostname: gateway.envoyproxy.io isHTTP2: false metadata: @@ -424,4 +421,7 @@ xdsIR: distinct: false name: "" prefix: / - traffic: {} + traffic: + dns: + dnsRefreshRate: 1s + respectDnsTtl: true diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.in.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.in.yaml new file mode 100644 index 00000000000..1f25d8f7e0b --- /dev/null +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.in.yaml @@ -0,0 +1,262 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: default + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - www.foo.com + parentRefs: + - namespace: default + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: /foo + backendRefs: + - name: service-1 + port: 8080 +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-2 + spec: + hostnames: + - www.bar.com + parentRefs: + - namespace: default + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: /bar + backendRefs: + - name: service-1 + port: 8080 +services: +- apiVersion: v1 + kind: Service + metadata: + namespace: envoy-gateway + name: grpc-backend + spec: + ports: + - port: 8000 + name: grpc + protocol: TCP +- apiVersion: v1 + kind: Service + metadata: + namespace: default + name: grpc-backend-2 + spec: + ports: + - port: 9000 + name: grpc + protocol: TCP +endpointSlices: +- apiVersion: discovery.k8s.io/v1 + kind: EndpointSlice + metadata: + name: endpointslice-grpc-backend + namespace: envoy-gateway + labels: + kubernetes.io/service-name: grpc-backend + addressType: IPv4 + ports: + - name: http + protocol: TCP + port: 8000 + endpoints: + - addresses: + - 7.7.7.7 + conditions: + ready: true +- apiVersion: discovery.k8s.io/v1 + kind: EndpointSlice + metadata: + name: endpointslice-grpc-backend-2 + namespace: default + labels: + kubernetes.io/service-name: grpc-backend-2 + addressType: IPv4 + ports: + - name: grpc + protocol: TCP + port: 9000 + endpoints: + - addresses: + - 8.8.8.8 + conditions: + ready: true +referenceGrants: +- apiVersion: gateway.networking.k8s.io/v1alpha2 + kind: ReferenceGrant + metadata: + namespace: envoy-gateway + name: referencegrant-1 + spec: + from: + - group: gateway.envoyproxy.io + kind: EnvoyExtensionPolicy + namespace: default + to: + - group: '' + kind: Service + - group: gateway.envoyproxy.io + kind: Backend +configMaps: +- apiVersion: v1 + kind: ConfigMap + metadata: + name: ca-cmap + namespace: default + data: + ca.crt: | + -----BEGIN CERTIFICATE----- + MIIDJzCCAg+gAwIBAgIUAl6UKIuKmzte81cllz5PfdN2IlIwDQYJKoZIhvcNAQEL + BQAwIzEQMA4GA1UEAwwHbXljaWVudDEPMA0GA1UECgwGa3ViZWRiMB4XDTIzMTAw + MjA1NDE1N1oXDTI0MTAwMTA1NDE1N1owIzEQMA4GA1UEAwwHbXljaWVudDEPMA0G + A1UECgwGa3ViZWRiMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwSTc + 1yj8HW62nynkFbXo4VXKv2jC0PM7dPVky87FweZcTKLoWQVPQE2p2kLDK6OEszmM + yyr+xxWtyiveremrWqnKkNTYhLfYPhgQkczib7eUalmFjUbhWdLvHakbEgCodn3b + kz57mInX2VpiDOKg4kyHfiuXWpiBqrCx0KNLpxo3DEQcFcsQTeTHzh4752GV04RU + Ti/GEWyzIsl4Rg7tGtAwmcIPgUNUfY2Q390FGqdH4ahn+mw/6aFbW31W63d9YJVq + ioyOVcaMIpM5B/c7Qc8SuhCI1YGhUyg4cRHLEw5VtikioyE3X04kna3jQAj54YbR + bpEhc35apKLB21HOUQIDAQABo1MwUTAdBgNVHQ4EFgQUyvl0VI5vJVSuYFXu7B48 + 6PbMEAowHwYDVR0jBBgwFoAUyvl0VI5vJVSuYFXu7B486PbMEAowDwYDVR0TAQH/ + BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAMLxrgFVMuNRq2wAwcBt7SnNR5Cfz + 2MvXq5EUmuawIUi9kaYjwdViDREGSjk7JW17vl576HjDkdfRwi4E28SydRInZf6J + i8HZcZ7caH6DxR335fgHVzLi5NiTce/OjNBQzQ2MJXVDd8DBmG5fyatJiOJQ4bWE + A7FlP0RdP3CO3GWE0M5iXOB2m1qWkE2eyO4UHvwTqNQLdrdAXgDQlbam9e4BG3Gg + d/6thAkWDbt/QNT+EJHDCvhDRKh1RuGHyg+Y+/nebTWWrFWsktRrbOoHCZiCpXI1 + 3eXE6nt0YkgtDxG22KqnhpAg9gUSs2hlhoxyvkzyF0mu6NhPlwAgnq7+/Q== + -----END CERTIFICATE----- +backendTLSPolicies: +- apiVersion: gateway.networking.k8s.io/v1alpha2 + kind: BackendTLSPolicy + metadata: + name: policy-btls-grpc + namespace: envoy-gateway + spec: + targetRefs: + - group: '' + kind: Service + name: grpc-backend + sectionName: "8000" + validation: + caCertificateRefs: + - name: ca-cmap + group: '' + kind: ConfigMap + hostname: grpc-backend +- apiVersion: gateway.networking.k8s.io/v1alpha2 + kind: BackendTLSPolicy + metadata: + name: policy-btls-backend-ip + namespace: envoy-gateway + spec: + targetRefs: + - group: gateway.envoyproxy.io + kind: Backend + name: backend-ip-tls + validation: + caCertificateRefs: + - name: ca-cmap + group: '' + kind: ConfigMap + hostname: ip-backend +envoyExtensionPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + namespace: default + name: policy-for-http-route + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + extProc: + - backendRefs: + - Name: grpc-backend + Namespace: envoy-gateway + Port: 8000 + - Name: grpc-backend-2 + Port: 9000 + - Name: backend-ip + Kind: Backend + Group: gateway.envoyproxy.io + - Name: backend-ip-tls + Namespace: envoy-gateway + Kind: Backend + Group: gateway.envoyproxy.io + backendSettings: + dns: + respectDnsTtl: true + http2: + initialStreamWindowSize: 128Ki + initialConnectionWindowSize: 2Mi + maxConcurrentStreams: 200 + onInvalidMessage: TerminateStream + loadBalancer: + type: ConsistentHash + consistentHash: + type: Header + header: + name: X-some-header + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + healthCheck: + passive: + consecutiveGatewayErrors: 4 + interval: 5s + circuitBreaker: + maxConnections: 2048 + timeout: + tcp: + connectTimeout: 15s + connection: + bufferLimit: 20Mi +backends: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: Backend + metadata: + name: backend-ip + namespace: default + spec: + endpoints: + - ip: + address: 1.1.1.1 + port: 3001 +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: Backend + metadata: + name: backend-ip-tls + namespace: envoy-gateway + spec: + endpoints: + - ip: + address: 2.2.2.2 + port: 3443 diff --git a/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.out.yaml b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.out.yaml new file mode 100644 index 00000000000..17f9e8c15a6 --- /dev/null +++ b/internal/gatewayapi/testdata/envoyextensionpolicy-with-extproc-with-traffic-features.out.yaml @@ -0,0 +1,431 @@ +backendTLSPolicies: +- apiVersion: gateway.networking.k8s.io/v1alpha2 + kind: BackendTLSPolicy + metadata: + creationTimestamp: null + name: policy-btls-grpc + namespace: envoy-gateway + spec: + targetRefs: + - group: "" + kind: Service + name: grpc-backend + sectionName: "8000" + validation: + caCertificateRefs: + - group: "" + kind: ConfigMap + name: ca-cmap + hostname: grpc-backend + status: + ancestors: + - ancestorRef: + group: gateway.envoyproxy.io + kind: EnvoyExtensionPolicy + name: policy-for-http-route + namespace: default + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +- apiVersion: gateway.networking.k8s.io/v1alpha2 + kind: BackendTLSPolicy + metadata: + creationTimestamp: null + name: policy-btls-backend-ip + namespace: envoy-gateway + spec: + targetRefs: + - group: gateway.envoyproxy.io + kind: Backend + name: backend-ip-tls + validation: + caCertificateRefs: + - group: "" + kind: ConfigMap + name: ca-cmap + hostname: ip-backend + status: + ancestors: + - ancestorRef: + group: gateway.envoyproxy.io + kind: EnvoyExtensionPolicy + name: policy-for-http-route + namespace: default + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +backends: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: Backend + metadata: + creationTimestamp: null + name: backend-ip + namespace: default + spec: + endpoints: + - ip: + address: 1.1.1.1 + port: 3001 + status: + conditions: + - lastTransitionTime: null + message: The Backend was accepted + reason: Accepted + status: "True" + type: Invalid +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: Backend + metadata: + creationTimestamp: null + name: backend-ip-tls + namespace: envoy-gateway + spec: + endpoints: + - ip: + address: 2.2.2.2 + port: 3443 + status: + conditions: + - lastTransitionTime: null + message: The Backend was accepted + reason: Accepted + status: "True" + type: Invalid +envoyExtensionPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyExtensionPolicy + metadata: + creationTimestamp: null + name: policy-for-http-route + namespace: default + spec: + extProc: + - backendRefs: + - name: grpc-backend + namespace: envoy-gateway + port: 8000 + - name: grpc-backend-2 + port: 9000 + - group: gateway.envoyproxy.io + kind: Backend + name: backend-ip + - group: gateway.envoyproxy.io + kind: Backend + name: backend-ip-tls + namespace: envoy-gateway + backendSettings: + circuitBreaker: + maxConnections: 2048 + connection: + bufferLimit: 20Mi + dns: + respectDnsTtl: true + healthCheck: + passive: + consecutiveGatewayErrors: 4 + interval: 5s + http2: + initialConnectionWindowSize: 2Mi + initialStreamWindowSize: 128Ki + maxConcurrentStreams: 200 + onInvalidMessage: TerminateStream + loadBalancer: + consistentHash: + header: + name: X-some-header + type: Header + type: ConsistentHash + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + timeout: + tcp: + connectTimeout: 15s + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: default + sectionName: http + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: default + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 2 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-1 + namespace: default + spec: + hostnames: + - www.foo.com + parentRefs: + - name: gateway-1 + namespace: default + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: /foo + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: default + sectionName: http +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-2 + namespace: default + spec: + hostnames: + - www.bar.com + parentRefs: + - name: gateway-1 + namespace: default + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: /bar + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: default + sectionName: http +infraIR: + default/gateway-1: + proxy: + listeners: + - address: null + name: default/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: default + name: default/gateway-1 +xdsIR: + default/gateway-1: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + metadata: + kind: Gateway + name: gateway-1 + namespace: default + sectionName: http + name: default/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - destination: + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + envoyExtensions: + extProcs: + - authority: grpc-backend.envoy-gateway:8000 + destination: + name: envoyextensionpolicy/default/policy-for-http-route/0 + settings: + - addressType: IP + protocol: GRPC + tls: + caCertificate: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + name: policy-btls-grpc/envoy-gateway-ca + sni: grpc-backend + weight: 1 + - addressType: IP + endpoints: + - host: 8.8.8.8 + port: 9000 + protocol: GRPC + weight: 1 + - addressType: IP + endpoints: + - host: 1.1.1.1 + port: 3001 + protocol: GRPC + weight: 1 + - addressType: IP + endpoints: + - host: 2.2.2.2 + port: 3443 + protocol: GRPC + tls: + caCertificate: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + name: policy-btls-backend-ip/envoy-gateway-ca + sni: ip-backend + weight: 1 + name: envoyextensionpolicy/default/policy-for-http-route/extproc/0 + traffic: + backendConnection: + bufferLimit: 20971520 + circuitBreaker: + maxConnections: 2048 + dns: + respectDnsTtl: true + healthCheck: + passive: + consecutiveGatewayErrors: 4 + interval: 5s + http2: + initialConnectionWindowSize: 131072 + initialStreamWindowSize: 2097152 + maxConcurrentStreams: 200 + resetStreamOnError: true + loadBalancer: + consistentHash: + header: + name: X-some-header + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + timeout: + tcp: + connectTimeout: 15s + hostname: www.foo.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + name: httproute/default/httproute-1/rule/0/match/0/www_foo_com + pathMatch: + distinct: false + name: "" + prefix: /foo + - destination: + name: httproute/default/httproute-2/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: www.bar.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-2 + namespace: default + name: httproute/default/httproute-2/rule/0/match/0/www_bar_com + pathMatch: + distinct: false + name: "" + prefix: /bar diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.in.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.in.yaml new file mode 100644 index 00000000000..72d40451a1f --- /dev/null +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.in.yaml @@ -0,0 +1,196 @@ +envoyProxyForGatewayClass: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + namespace: envoy-gateway-system + name: test + spec: + telemetry: + accessLog: + settings: + - format: + type: Text + text: | + [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n + sinks: + - type: File + file: + path: /dev/stdout + - type: ALS + als: + logName: accesslog + backendSettings: + http2: + initialStreamWindowSize: 128Ki + initialConnectionWindowSize: 2Mi + maxConcurrentStreams: 200 + onInvalidMessage: TerminateStream + loadBalancer: + type: ConsistentHash + consistentHash: + type: Header + header: + name: X-some-header + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + healthCheck: + passive: + consecutiveGatewayErrors: 4 + interval: 5s + circuitBreaker: + maxConnections: 2048 + timeout: + tcp: + connectTimeout: 15s + connection: + bufferLimit: 20Mi + backendRefs: + - name: envoy-als + namespace: monitoring + port: 9000 + http: + requestHeaders: + - x-client-ip-address + responseHeaders: + - cache-control + responseTrailers: + - expires + type: HTTP + - type: ALS + als: + backendRefs: + - name: envoy-als + namespace: monitoring + port: 9000 + type: TCP + - type: OpenTelemetry + openTelemetry: + backendSettings: + http2: + initialStreamWindowSize: 128Ki + initialConnectionWindowSize: 2Mi + maxConcurrentStreams: 200 + onInvalidMessage: TerminateStream + loadBalancer: + type: ConsistentHash + consistentHash: + type: Header + header: + name: X-some-header + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + healthCheck: + passive: + consecutiveGatewayErrors: 4 + interval: 5s + circuitBreaker: + maxConnections: 2048 + timeout: + tcp: + connectTimeout: 15s + connection: + bufferLimit: 20Mi + host: otel-collector.monitoring.svc.cluster.local + port: 4317 + resources: + k8s.cluster.name: "cluster-1" + provider: + type: Kubernetes + kubernetes: + envoyService: + type: LoadBalancer + envoyDeployment: + replicas: 2 + container: + env: + - name: env_a + value: env_a_value + - name: env_b + value: env_b_name + image: "envoyproxy/envoy:distroless-dev" + resources: + requests: + cpu: 100m + memory: 512Mi + securityContext: + runAsUser: 2000 + allowPrivilegeEscalation: false + pod: + annotations: + key1: val1 + key2: val2 + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: cloud.google.com/gke-nodepool + operator: In + values: + - router-node + tolerations: + - effect: NoSchedule + key: node-type + operator: Exists + value: "router" + securityContext: + runAsUser: 1000 + runAsGroup: 3000 + fsGroup: 2000 + fsGroupChangePolicy: "OnRootMismatch" + volumes: + - name: certs + secret: + secretName: envoy-cert +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: Same +services: +- apiVersion: v1 + kind: Service + metadata: + name: envoy-als + namespace: monitoring + spec: + type: ClusterIP + ports: + - name: grpc + port: 9000 + appProtocol: grpc + protocol: TCP + targetPort: 9000 +endpointSlices: +- apiVersion: discovery.k8s.io/v1 + kind: EndpointSlice + metadata: + name: endpointslice-envoy-als + namespace: monitoring + labels: + kubernetes.io/service-name: envoy-als + addressType: IPv4 + ports: + - name: grpc + protocol: TCP + appProtocol: grpc + port: 9090 + endpoints: + - addresses: + - "10.240.0.10" + conditions: + ready: true diff --git a/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.out.yaml b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.out.yaml new file mode 100644 index 00000000000..28ef831b03a --- /dev/null +++ b/internal/gatewayapi/testdata/envoyproxy-accesslog-with-traffic.out.yaml @@ -0,0 +1,326 @@ +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: Same + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 0 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +infraIR: + envoy-gateway/gateway-1: + proxy: + config: + apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: EnvoyProxy + metadata: + creationTimestamp: null + name: test + namespace: envoy-gateway-system + spec: + logging: {} + provider: + kubernetes: + envoyDeployment: + container: + env: + - name: env_a + value: env_a_value + - name: env_b + value: env_b_name + image: envoyproxy/envoy:distroless-dev + resources: + requests: + cpu: 100m + memory: 512Mi + securityContext: + allowPrivilegeEscalation: false + runAsUser: 2000 + pod: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: cloud.google.com/gke-nodepool + operator: In + values: + - router-node + annotations: + key1: val1 + key2: val2 + securityContext: + fsGroup: 2000 + fsGroupChangePolicy: OnRootMismatch + runAsGroup: 3000 + runAsUser: 1000 + tolerations: + - effect: NoSchedule + key: node-type + operator: Exists + value: router + volumes: + - name: certs + secret: + secretName: envoy-cert + replicas: 2 + envoyService: + type: LoadBalancer + type: Kubernetes + telemetry: + accessLog: + settings: + - format: + text: | + [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n + type: Text + sinks: + - file: + path: /dev/stdout + type: File + - als: + backendRefs: + - name: envoy-als + namespace: monitoring + port: 9000 + backendSettings: + circuitBreaker: + maxConnections: 2048 + connection: + bufferLimit: 20Mi + healthCheck: + passive: + consecutiveGatewayErrors: 4 + interval: 5s + http2: + initialConnectionWindowSize: 2Mi + initialStreamWindowSize: 128Ki + maxConcurrentStreams: 200 + onInvalidMessage: TerminateStream + loadBalancer: + consistentHash: + header: + name: X-some-header + type: Header + type: ConsistentHash + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + timeout: + tcp: + connectTimeout: 15s + http: + requestHeaders: + - x-client-ip-address + responseHeaders: + - cache-control + responseTrailers: + - expires + logName: accesslog + type: HTTP + type: ALS + - als: + backendRefs: + - name: envoy-als + namespace: monitoring + port: 9000 + type: TCP + type: ALS + - openTelemetry: + backendSettings: + circuitBreaker: + maxConnections: 2048 + connection: + bufferLimit: 20Mi + healthCheck: + passive: + consecutiveGatewayErrors: 4 + interval: 5s + http2: + initialConnectionWindowSize: 2Mi + initialStreamWindowSize: 128Ki + maxConcurrentStreams: 200 + onInvalidMessage: TerminateStream + loadBalancer: + consistentHash: + header: + name: X-some-header + type: Header + type: ConsistentHash + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + timeout: + tcp: + connectTimeout: 15s + host: otel-collector.monitoring.svc.cluster.local + port: 4317 + resources: + k8s.cluster.name: cluster-1 + type: OpenTelemetry + status: {} + listeners: + - address: null + name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + name: envoy-gateway/gateway-1 +xdsIR: + envoy-gateway/gateway-1: + accessLog: + als: + - destination: + name: accesslog_als_0_1 + settings: + - addressType: IP + endpoints: + - host: 10.240.0.10 + port: 9090 + protocol: GRPC + http: + requestHeaders: + - x-client-ip-address + responseHeaders: + - cache-control + responseTrailers: + - expires + name: accesslog + text: | + [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n + traffic: + backendConnection: + bufferLimit: 20971520 + circuitBreaker: + maxConnections: 2048 + healthCheck: + passive: + consecutiveGatewayErrors: 4 + interval: 5s + http2: + initialConnectionWindowSize: 131072 + initialStreamWindowSize: 2097152 + maxConcurrentStreams: 200 + resetStreamOnError: true + loadBalancer: + consistentHash: + header: + name: X-some-header + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + timeout: + tcp: + connectTimeout: 15s + type: HTTP + - destination: + name: accesslog_als_0_2 + settings: + - addressType: IP + endpoints: + - host: 10.240.0.10 + port: 9090 + protocol: GRPC + name: envoy-gateway-system/test + text: | + [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n + type: TCP + openTelemetry: + - authority: otel-collector.monitoring.svc.cluster.local + destination: + name: accesslog_otel_0_3 + settings: + - endpoints: + - host: otel-collector.monitoring.svc.cluster.local + port: 4317 + protocol: GRPC + weight: 1 + resources: + k8s.cluster.name: cluster-1 + text: | + [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n + traffic: + backendConnection: + bufferLimit: 20971520 + circuitBreaker: + maxConnections: 2048 + healthCheck: + passive: + consecutiveGatewayErrors: 4 + interval: 5s + http2: + initialConnectionWindowSize: 131072 + initialStreamWindowSize: 2097152 + maxConcurrentStreams: 200 + resetStreamOnError: true + loadBalancer: + consistentHash: + header: + name: X-some-header + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + timeout: + tcp: + connectTimeout: 15s + text: + - format: | + [%START_TIME%] "%REQ(:METHOD)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"\n + path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + metadata: + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http + name: envoy-gateway/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 diff --git a/internal/gatewayapi/testdata/envoyproxy-tracing-backend.in.yaml b/internal/gatewayapi/testdata/envoyproxy-tracing-backend.in.yaml index 9cd3485cec3..4c06c534135 100644 --- a/internal/gatewayapi/testdata/envoyproxy-tracing-backend.in.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-tracing-backend.in.yaml @@ -9,6 +9,33 @@ envoyProxyForGatewayClass: tracing: samplingRate: 100 provider: + backendSettings: + http2: + initialStreamWindowSize: 128Ki + initialConnectionWindowSize: 2Mi + maxConcurrentStreams: 200 + onInvalidMessage: TerminateStream + loadBalancer: + type: ConsistentHash + consistentHash: + type: Header + header: + name: X-some-header + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + healthCheck: + passive: + consecutiveGatewayErrors: 4 + interval: 5s + circuitBreaker: + maxConnections: 2048 + timeout: + tcp: + connectTimeout: 15s + connection: + bufferLimit: 20Mi backendRefs: - name: otel-collector namespace: monitoring diff --git a/internal/gatewayapi/testdata/envoyproxy-tracing-backend.out.yaml b/internal/gatewayapi/testdata/envoyproxy-tracing-backend.out.yaml index 70e07bd18f2..b3a44d78fdc 100644 --- a/internal/gatewayapi/testdata/envoyproxy-tracing-backend.out.yaml +++ b/internal/gatewayapi/testdata/envoyproxy-tracing-backend.out.yaml @@ -106,6 +106,33 @@ infraIR: - name: otel-collector namespace: monitoring port: 4317 + backendSettings: + circuitBreaker: + maxConnections: 2048 + connection: + bufferLimit: 20Mi + healthCheck: + passive: + consecutiveGatewayErrors: 4 + interval: 5s + http2: + initialConnectionWindowSize: 2Mi + initialStreamWindowSize: 128Ki + maxConcurrentStreams: 200 + onInvalidMessage: TerminateStream + loadBalancer: + consistentHash: + header: + name: X-some-header + type: Header + type: ConsistentHash + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + timeout: + tcp: + connectTimeout: 15s type: OpenTelemetry samplingRate: 100 status: {} @@ -156,6 +183,58 @@ xdsIR: - name: otel-collector namespace: monitoring port: 4317 + backendSettings: + circuitBreaker: + maxConnections: 2048 + connection: + bufferLimit: 20Mi + healthCheck: + passive: + consecutiveGatewayErrors: 4 + interval: 5s + http2: + initialConnectionWindowSize: 2Mi + initialStreamWindowSize: 128Ki + maxConcurrentStreams: 200 + onInvalidMessage: TerminateStream + loadBalancer: + consistentHash: + header: + name: X-some-header + type: Header + type: ConsistentHash + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + timeout: + tcp: + connectTimeout: 15s type: OpenTelemetry samplingRate: 100 serviceName: gateway-1.envoy-gateway + traffic: + backendConnection: + bufferLimit: 20971520 + circuitBreaker: + maxConnections: 2048 + healthCheck: + passive: + consecutiveGatewayErrors: 4 + interval: 5s + http2: + initialConnectionWindowSize: 131072 + initialStreamWindowSize: 2097152 + maxConcurrentStreams: 200 + resetStreamOnError: true + loadBalancer: + consistentHash: + header: + name: X-some-header + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + timeout: + tcp: + connectTimeout: 15s diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.in.yaml new file mode 100644 index 00000000000..e1f50e75b2d --- /dev/null +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.in.yaml @@ -0,0 +1,107 @@ +gateways: + - apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: default + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +httpRoutes: + - apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - www.foo.com + parentRefs: + - namespace: default + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: /foo1 + backendRefs: + - name: service-1 + port: 8080 + - matches: + - path: + value: /foo2 + backendRefs: + - name: service-2 + port: 8080 + - apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-2 + spec: + hostnames: + - www.bar.com + parentRefs: + - namespace: default + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: /bar + backendRefs: + - name: service-3 + port: 8080 +backends: + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: Backend + metadata: + name: backend-fqdn + namespace: default + spec: + endpoints: + - fqdn: + hostname: 'primary.foo.com' + port: 3000 +referenceGrants: + - apiVersion: gateway.networking.k8s.io/v1alpha2 + kind: ReferenceGrant + metadata: + namespace: envoy-gateway + name: referencegrant-1 + spec: + from: + - group: gateway.envoyproxy.io + kind: SecurityPolicy + namespace: default + to: + - group: "" + kind: Service +securityPolicies: + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + namespace: default + name: policy-for-http-route-1 + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + extAuth: + failOpen: true + headersToExtAuth: + - header1 + - header2 + grpc: + backendRefs: + - name: backend-fqdn + kind: Backend + group: gateway.envoyproxy.io + port: 3000 diff --git a/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.out.yaml new file mode 100644 index 00000000000..a89bf53a8cf --- /dev/null +++ b/internal/gatewayapi/testdata/securitypolicy-with-extauth-backend.out.yaml @@ -0,0 +1,314 @@ +backends: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: Backend + metadata: + creationTimestamp: null + name: backend-fqdn + namespace: default + spec: + endpoints: + - fqdn: + hostname: primary.foo.com + port: 3000 + status: + conditions: + - lastTransitionTime: null + message: The Backend was accepted + reason: Accepted + status: "True" + type: Invalid +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + creationTimestamp: null + name: gateway-1 + namespace: default + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 2 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-1 + namespace: default + spec: + hostnames: + - www.foo.com + parentRefs: + - name: gateway-1 + namespace: default + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: /foo1 + - backendRefs: + - name: service-2 + port: 8080 + matches: + - path: + value: /foo2 + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: default + sectionName: http +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + creationTimestamp: null + name: httproute-2 + namespace: default + spec: + hostnames: + - www.bar.com + parentRefs: + - name: gateway-1 + namespace: default + sectionName: http + rules: + - backendRefs: + - name: service-3 + port: 8080 + matches: + - path: + value: /bar + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: default + sectionName: http +infraIR: + default/gateway-1: + proxy: + listeners: + - address: null + name: default/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: default + name: default/gateway-1 +securityPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: SecurityPolicy + metadata: + creationTimestamp: null + name: policy-for-http-route-1 + namespace: default + spec: + extAuth: + failOpen: true + grpc: + backendRefs: + - group: gateway.envoyproxy.io + kind: Backend + name: backend-fqdn + port: 3000 + headersToExtAuth: + - header1 + - header2 + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: default + sectionName: http + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +xdsIR: + default/gateway-1: + accessLog: + text: + - path: /dev/stdout + http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + metadata: + kind: Gateway + name: gateway-1 + namespace: default + sectionName: http + name: default/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - destination: + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: www.foo.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + name: httproute/default/httproute-1/rule/0/match/0/www_foo_com + pathMatch: + distinct: false + name: "" + prefix: /foo1 + security: + extAuth: + failOpen: true + grpc: + authority: primary.foo.com:3000 + destination: + name: securitypolicy/default/policy-for-http-route-1/default/backend-fqdn + settings: + - addressType: FQDN + endpoints: + - host: primary.foo.com + port: 3000 + protocol: GRPC + weight: 1 + headersToExtAuth: + - header1 + - header2 + name: securitypolicy/default/policy-for-http-route-1 + - destination: + name: httproute/default/httproute-1/rule/1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: www.foo.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + name: httproute/default/httproute-1/rule/1/match/0/www_foo_com + pathMatch: + distinct: false + name: "" + prefix: /foo2 + security: + extAuth: + failOpen: true + grpc: + authority: primary.foo.com:3000 + destination: + name: securitypolicy/default/policy-for-http-route-1/default/backend-fqdn + settings: + - addressType: FQDN + endpoints: + - host: primary.foo.com + port: 3000 + protocol: GRPC + weight: 1 + headersToExtAuth: + - header1 + - header2 + name: securitypolicy/default/policy-for-http-route-1 + - destination: + name: httproute/default/httproute-2/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: www.bar.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-2 + namespace: default + name: httproute/default/httproute-2/rule/0/match/0/www_bar_com + pathMatch: + distinct: false + name: "" + prefix: /bar diff --git a/internal/infrastructure/kubernetes/proxy/resource.go b/internal/infrastructure/kubernetes/proxy/resource.go index 5045de6390a..406694be9bb 100644 --- a/internal/infrastructure/kubernetes/proxy/resource.go +++ b/internal/infrastructure/kubernetes/proxy/resource.go @@ -226,9 +226,9 @@ func expectedProxyContainers(infra *ir.ProxyInfra, }, }, TimeoutSeconds: 1, - PeriodSeconds: 10, + PeriodSeconds: 5, SuccessThreshold: 1, - FailureThreshold: 3, + FailureThreshold: 1, }, Lifecycle: &corev1.Lifecycle{ PreStop: &corev1.LifecycleHandler{ diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml index 0622977315d..7f1bc6c41ab 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/component-level.yaml @@ -74,12 +74,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml index 8f2752be07c..99232820298 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml @@ -258,12 +258,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml index 1d5a93c5ba2..b59b07a086c 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml @@ -256,12 +256,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml index 7ee2909f896..0808d5c0180 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml @@ -241,12 +241,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml index 7190df8f86f..73bc606336c 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml @@ -212,12 +212,12 @@ spec: name: EnvoyHTTPSPort protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml index 3ceb7cee0ea..4f2f396b763 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml @@ -260,12 +260,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml index 9b8a0fcaf4b..5391a49388b 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 @@ -252,12 +252,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml index 970f58ba1ab..169eeb59394 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml @@ -241,12 +241,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml index 3bb5ccbe620..725055a9f4d 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml @@ -242,12 +242,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml index 060e0d42b92..b993f3bfbc1 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml @@ -260,12 +260,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml index ffc184f3fd8..c43c64302f3 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml @@ -246,12 +246,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml index 850b8a2510e..568aa4164ad 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-concurrency.yaml @@ -74,12 +74,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml index e75a89be5bc..612363ca2e6 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml @@ -243,12 +243,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml index 424eae5f2a3..a0324cb54e4 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml @@ -241,12 +241,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml index fb4fc761bb2..c31ea245056 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml @@ -241,12 +241,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml index 96a1e21f963..a0ebcf2e918 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml @@ -241,12 +241,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml index 7436383cc8e..e1d7c76a069 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml @@ -241,12 +241,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml index e98fd731131..b985e8d0f02 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/bootstrap.yaml @@ -77,12 +77,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml index edcfa7b5322..445bf70d28c 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/component-level.yaml @@ -78,12 +78,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml index 88983936f25..8af199519a4 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml @@ -263,12 +263,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml index 07ceadcfb6d..902de504983 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml @@ -263,12 +263,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml index 4000dacbda3..992d976f40e 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml @@ -261,12 +261,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml index 44777d51a52..3bd69459a53 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml @@ -245,12 +245,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml index bee1b53938a..fa7078ae684 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml @@ -216,12 +216,12 @@ spec: name: EnvoyHTTPSPort protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml index e84fd418ead..21ddbb9e6fc 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml @@ -265,12 +265,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml index 460de06f269..f3fca2808d7 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 @@ -256,12 +256,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml index 5fe7b493015..8d70d4d85cd 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml @@ -245,12 +245,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml index 9ab5e2cc0dd..9f70f8bb642 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml @@ -246,12 +246,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml index 51f0ccc3a8a..1395e60cba7 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml @@ -265,12 +265,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml index cfc2685d49d..1bb027eacc5 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml @@ -250,12 +250,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml index c01d19873f1..44e6370811c 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-concurrency.yaml @@ -78,12 +78,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml index ef9f75cc636..397b43b9753 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml @@ -245,12 +245,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml index 81d0cbac111..a1aa0917bfd 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml @@ -247,12 +247,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml index 83f2881be23..57258870015 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml @@ -245,12 +245,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml index f1dc2a9bc6f..2dd83e8e3d6 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml @@ -245,12 +245,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml index cc8f66c7e33..72d297ca12a 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml @@ -245,12 +245,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml index 4083f99d3fe..20fcb8589a2 100644 --- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml +++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml @@ -245,12 +245,12 @@ spec: name: metrics protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /ready port: 19001 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/ratelimit/resource.go b/internal/infrastructure/kubernetes/ratelimit/resource.go index 162396f62db..b2fd1c3f6c3 100644 --- a/internal/infrastructure/kubernetes/ratelimit/resource.go +++ b/internal/infrastructure/kubernetes/ratelimit/resource.go @@ -184,9 +184,9 @@ func expectedRateLimitContainers(rateLimit *egv1a1.RateLimit, rateLimitDeploymen }, }, TimeoutSeconds: 1, - PeriodSeconds: 10, + PeriodSeconds: 5, SuccessThreshold: 1, - FailureThreshold: 3, + FailureThreshold: 1, }, }, } diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml index c750b09a0b9..ebde9a4c436 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/custom.yaml @@ -87,12 +87,12 @@ spec: name: grpc protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /healthcheck port: 8080 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml index c750b09a0b9..ebde9a4c436 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default-env.yaml @@ -87,12 +87,12 @@ spec: name: grpc protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /healthcheck port: 8080 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml index 277d5e649d9..b010414bd90 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/default.yaml @@ -88,12 +88,12 @@ spec: name: grpc protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /healthcheck port: 8080 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml index 0cbbd6dbbb8..449ed2c1d70 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/disable-prometheus.yaml @@ -84,12 +84,12 @@ spec: name: grpc protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /healthcheck port: 8080 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml index 1d53f34a9bc..cbb129feb51 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing-custom.yaml @@ -103,12 +103,12 @@ spec: name: grpc protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /healthcheck port: 8080 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml index 56bd0a7dfe3..867c5df1b1e 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/enable-tracing.yaml @@ -103,12 +103,12 @@ spec: name: grpc protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /healthcheck port: 8080 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml index 4468e0df0e4..e0bf55b5d8a 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/extension-env.yaml @@ -91,12 +91,12 @@ spec: name: grpc protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /healthcheck port: 8080 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml index 826deab69ba..03ff65426d8 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/override-env.yaml @@ -87,12 +87,12 @@ spec: name: grpc protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /healthcheck port: 8080 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml index 790de9e159a..b7dea3664e2 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/patch-deployment.yaml @@ -88,12 +88,12 @@ spec: name: grpc protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /healthcheck port: 8080 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/redis-tls-settings.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/redis-tls-settings.yaml index e3e723c1d40..9af52d675b7 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/redis-tls-settings.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/redis-tls-settings.yaml @@ -95,12 +95,12 @@ spec: name: grpc protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /healthcheck port: 8080 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml index 5cbedb98853..7c965aa04b0 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/tolerations.yaml @@ -95,12 +95,12 @@ spec: name: grpc protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /healthcheck port: 8080 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/volumes.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/volumes.yaml index fcee6df457d..4f69dea329c 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/volumes.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/volumes.yaml @@ -95,12 +95,12 @@ spec: name: grpc protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /healthcheck port: 8080 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-node-selector.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-node-selector.yaml index 1365ac63f8f..5d525b44d1f 100644 --- a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-node-selector.yaml +++ b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-node-selector.yaml @@ -88,12 +88,12 @@ spec: name: grpc protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /healthcheck port: 8080 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-topology-spread-constraints.yaml b/internal/infrastructure/kubernetes/ratelimit/testdata/deployments/with-topology-spread-constraints.yaml index 1558a925c33..e9a5fdd66a7 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 @@ -88,12 +88,12 @@ spec: name: grpc protocol: TCP readinessProbe: - failureThreshold: 3 + failureThreshold: 1 httpGet: path: /healthcheck port: 8080 scheme: HTTP - periodSeconds: 10 + periodSeconds: 5 successThreshold: 1 timeoutSeconds: 1 resources: diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 7cc5ed8f354..f2807da484a 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -565,8 +565,8 @@ type HTTPRoute struct { UseClientProtocol *bool `json:"useClientProtocol,omitempty" yaml:"useClientProtocol,omitempty"` // Metadata is used to enrich envoy route metadata with user and provider-specific information Metadata *ResourceMetadata `json:"metadata,omitempty" yaml:"metadata,omitempty"` - // DNS is used to configure how DNS resolution is handled for the route - DNS *DNS `json:"dns,omitempty" yaml:"dns,omitempty"` + // SessionPersistence holds the configuration for session persistence. + SessionPersistence *SessionPersistence `json:"sessionPersistence,omitempty" yaml:"sessionPersistence,omitempty"` } // DNS contains configuration options for DNS resolution. @@ -578,6 +578,33 @@ type DNS struct { RespectDNSTTL *bool `json:"respectDnsTtl,omitempty"` } +// SessionPersistence defines the desired state of SessionPersistence. +// +k8s:deepcopy-gen=true +type SessionPersistence struct { + // Cookie defines the configuration for cookie-based session persistence. + // Either Cookie or Header must be non-empty. + Cookie *CookieBasedSessionPersistence `json:"cookie,omitempty" yaml:"cookie,omitempty"` + // Header defines the configuration for header-based session persistence. + // Either Cookie or Header must be non-empty. + Header *HeaderBasedSessionPersistence `json:"header,omitempty" yaml:"header,omitempty"` +} + +// CookieBasedSessionPersistence defines the configuration for cookie-based session persistence. +// +k8s:deepcopy-gen=true +type CookieBasedSessionPersistence struct { + // Name defines the name of the persistent session token. + Name string `json:"name"` + + TTL *metav1.Duration `json:"ttl,omitempty" yaml:"ttl,omitempty"` +} + +// HeaderBasedSessionPersistence defines the configuration for header-based session persistence. +// +k8s:deepcopy-gen=true +type HeaderBasedSessionPersistence struct { + // Name defines the name of the persistent session token. + Name string `json:"name"` +} + // TrafficFeatures holds the information associated with the Backend Traffic Policy. // +k8s:deepcopy-gen=true type TrafficFeatures struct { @@ -605,6 +632,8 @@ type TrafficFeatures struct { // HTTP2 provides HTTP/2 configuration for clusters // +optional HTTP2 *HTTP2Settings `json:"http2,omitempty" yaml:"http2,omitempty"` + // DNS is used to configure how DNS resolution is handled by the Envoy Proxy cluster + DNS *DNS `json:"dns,omitempty" yaml:"dns,omitempty"` } func (b *TrafficFeatures) Validate() error { @@ -817,6 +846,9 @@ type ExtAuth struct { // Only one of GRPCService or HTTPService may be specified. HTTP *HTTPExtAuthService `json:"http,omitempty"` + // Traffic contains configuration for traffic features for the ExtAuth service + Traffic *TrafficFeatures `json:"traffic,omitempty"` + // HeadersToExtAuth defines the client request headers that will be included // in the request to the external authorization service. // Note: If not specified, the default behavior for gRPC and HTTP external @@ -1514,7 +1546,8 @@ type UDPRoute struct { Timeout *Timeout `json:"timeout,omitempty" yaml:"timeout,omitempty"` // settings of upstream connection BackendConnection *BackendConnection `json:"backendConnection,omitempty" yaml:"backendConnection,omitempty"` - DNS *DNS `json:"dns,omitempty" yaml:"dns,omitempty"` + // DNS is used to configure how DNS resolution is handled by the Envoy Proxy cluster + DNS *DNS `json:"dns,omitempty" yaml:"dns,omitempty"` } // Validate the fields within the UDPListener structure @@ -1653,6 +1686,7 @@ type ALSAccessLog struct { CELMatches []string `json:"celMatches,omitempty" yaml:"celMatches,omitempty"` LogName string `json:"name" yaml:"name"` Destination RouteDestination `json:"destination,omitempty" yaml:"destination,omitempty"` + Traffic *TrafficFeatures `json:"traffic,omitempty" yaml:"traffic,omitempty"` Type egv1a1.ALSEnvoyProxyAccessLogType `json:"type" yaml:"type"` Text *string `json:"text,omitempty" yaml:"text,omitempty"` Attributes map[string]string `json:"attributes,omitempty" yaml:"attributes,omitempty"` @@ -1676,6 +1710,7 @@ type OpenTelemetryAccessLog struct { Attributes map[string]string `json:"attributes,omitempty" yaml:"attributes,omitempty"` Resources map[string]string `json:"resources,omitempty" yaml:"resources,omitempty"` Destination RouteDestination `json:"destination,omitempty" yaml:"destination,omitempty"` + Traffic *TrafficFeatures `json:"traffic,omitempty" yaml:"traffic,omitempty"` } // EnvoyPatchPolicy defines the intermediate representation of the EnvoyPatchPolicy resource. @@ -1734,6 +1769,7 @@ type Tracing struct { SamplingRate float64 `json:"samplingRate,omitempty"` CustomTags map[string]egv1a1.CustomTag `json:"customTags,omitempty"` Destination RouteDestination `json:"destination,omitempty"` + Traffic *TrafficFeatures `json:"traffic,omitempty"` Provider egv1a1.TracingProvider `json:"provider"` } @@ -2230,6 +2266,9 @@ type ExtProc struct { // Destination defines the destination for the gRPC External Processing service. Destination RouteDestination `json:"destination" yaml:"destination"` + // Traffic holds the features associated with traffic management + Traffic *TrafficFeatures `json:"traffic,omitempty" yaml:"traffic,omitempty"` + // Authority is the hostname:port of the HTTP External Processing service. Authority string `json:"authority" yaml:"authority"` diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index dabb7af5afd..5e3398a0678 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -25,6 +25,11 @@ func (in *ALSAccessLog) DeepCopyInto(out *ALSAccessLog) { copy(*out, *in) } in.Destination.DeepCopyInto(&out.Destination) + if in.Traffic != nil { + in, out := &in.Traffic, &out.Traffic + *out = new(TrafficFeatures) + (*in).DeepCopyInto(*out) + } if in.Text != nil { in, out := &in.Text, &out.Text *out = new(string) @@ -531,6 +536,26 @@ func (in *ConsistentHash) DeepCopy() *ConsistentHash { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CookieBasedSessionPersistence) DeepCopyInto(out *CookieBasedSessionPersistence) { + *out = *in + if in.TTL != nil { + in, out := &in.TTL, &out.TTL + *out = new(v1.Duration) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CookieBasedSessionPersistence. +func (in *CookieBasedSessionPersistence) DeepCopy() *CookieBasedSessionPersistence { + if in == nil { + return nil + } + out := new(CookieBasedSessionPersistence) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CoreListenerDetails) DeepCopyInto(out *CoreListenerDetails) { *out = *in @@ -792,6 +817,11 @@ func (in *ExtAuth) DeepCopyInto(out *ExtAuth) { *out = new(HTTPExtAuthService) (*in).DeepCopyInto(*out) } + if in.Traffic != nil { + in, out := &in.Traffic, &out.Traffic + *out = new(TrafficFeatures) + (*in).DeepCopyInto(*out) + } if in.HeadersToExtAuth != nil { in, out := &in.HeadersToExtAuth, &out.HeadersToExtAuth *out = make([]string, len(*in)) @@ -818,6 +848,11 @@ func (in *ExtAuth) DeepCopy() *ExtAuth { func (in *ExtProc) DeepCopyInto(out *ExtProc) { *out = *in in.Destination.DeepCopyInto(&out.Destination) + if in.Traffic != nil { + in, out := &in.Traffic, &out.Traffic + *out = new(TrafficFeatures) + (*in).DeepCopyInto(*out) + } if in.MessageTimeout != nil { in, out := &in.MessageTimeout, &out.MessageTimeout *out = new(v1.Duration) @@ -1348,9 +1383,9 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) { *out = new(ResourceMetadata) (*in).DeepCopyInto(*out) } - if in.DNS != nil { - in, out := &in.DNS, &out.DNS - *out = new(DNS) + if in.SessionPersistence != nil { + in, out := &in.SessionPersistence, &out.SessionPersistence + *out = new(SessionPersistence) (*in).DeepCopyInto(*out) } } @@ -1410,6 +1445,21 @@ func (in *HTTPWasmCode) DeepCopy() *HTTPWasmCode { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HeaderBasedSessionPersistence) DeepCopyInto(out *HeaderBasedSessionPersistence) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeaderBasedSessionPersistence. +func (in *HeaderBasedSessionPersistence) DeepCopy() *HeaderBasedSessionPersistence { + if in == nil { + return nil + } + out := new(HeaderBasedSessionPersistence) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HeaderSettings) DeepCopyInto(out *HeaderSettings) { *out = *in @@ -1825,6 +1875,11 @@ func (in *OpenTelemetryAccessLog) DeepCopyInto(out *OpenTelemetryAccessLog) { } } in.Destination.DeepCopyInto(&out.Destination) + if in.Traffic != nil { + in, out := &in.Traffic, &out.Traffic + *out = new(TrafficFeatures) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenTelemetryAccessLog. @@ -2334,6 +2389,31 @@ func (in *SecurityFeatures) DeepCopy() *SecurityFeatures { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SessionPersistence) DeepCopyInto(out *SessionPersistence) { + *out = *in + if in.Cookie != nil { + in, out := &in.Cookie, &out.Cookie + *out = new(CookieBasedSessionPersistence) + (*in).DeepCopyInto(*out) + } + if in.Header != nil { + in, out := &in.Header, &out.Header + *out = new(HeaderBasedSessionPersistence) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SessionPersistence. +func (in *SessionPersistence) DeepCopy() *SessionPersistence { + if in == nil { + return nil + } + out := new(SessionPersistence) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SlowStart) DeepCopyInto(out *SlowStart) { *out = *in @@ -2832,6 +2912,11 @@ func (in *Tracing) DeepCopyInto(out *Tracing) { } } in.Destination.DeepCopyInto(&out.Destination) + if in.Traffic != nil { + in, out := &in.Traffic, &out.Traffic + *out = new(TrafficFeatures) + (*in).DeepCopyInto(*out) + } in.Provider.DeepCopyInto(&out.Provider) } @@ -2903,6 +2988,11 @@ func (in *TrafficFeatures) DeepCopyInto(out *TrafficFeatures) { *out = new(HTTP2Settings) (*in).DeepCopyInto(*out) } + if in.DNS != nil { + in, out := &in.DNS, &out.DNS + *out = new(DNS) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrafficFeatures. diff --git a/internal/provider/kubernetes/controller.go b/internal/provider/kubernetes/controller.go index f7e88da222d..73d8799e900 100644 --- a/internal/provider/kubernetes/controller.go +++ b/internal/provider/kubernetes/controller.go @@ -769,13 +769,35 @@ func (r *gatewayAPIReconciler) findReferenceGrant(ctx context.Context, from, to } for _, refGrant := range refGrants { - if refGrant.Namespace == to.namespace { - for _, src := range refGrant.Spec.From { - if src.Kind == gwapiv1a2.Kind(from.kind) && string(src.Namespace) == from.namespace { - return &refGrant, nil - } + if refGrant.Namespace != to.namespace { + continue + } + + var fromAllowed bool + for _, refGrantFrom := range refGrant.Spec.From { + if string(refGrantFrom.Kind) == from.kind && string(refGrantFrom.Namespace) == from.namespace { + fromAllowed = true + break } } + + if !fromAllowed { + continue + } + + var toAllowed bool + for _, refGrantTo := range refGrant.Spec.To { + if string(refGrantTo.Kind) == to.kind && (refGrantTo.Name == nil || *refGrantTo.Name == "" || string(*refGrantTo.Name) == to.name) { + toAllowed = true + break + } + } + + if !toAllowed { + continue + } + + return &refGrant, nil } // No ReferenceGrant found. diff --git a/internal/provider/kubernetes/predicates_test.go b/internal/provider/kubernetes/predicates_test.go index 6379263bdb0..d5ac876f4b2 100644 --- a/internal/provider/kubernetes/predicates_test.go +++ b/internal/provider/kubernetes/predicates_test.go @@ -471,12 +471,14 @@ func TestValidateServiceForReconcile(t *testing.T) { { Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "otel-collector", - Namespace: ptr.To(gwapiv1.Namespace("default")), - Port: ptr.To(gwapiv1.PortNumber(4317)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "otel-collector", + Namespace: ptr.To(gwapiv1.Namespace("default")), + Port: ptr.To(gwapiv1.PortNumber(4317)), + }, }, }, }, @@ -491,12 +493,14 @@ func TestValidateServiceForReconcile(t *testing.T) { { Type: egv1a1.MetricSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "otel-collector", - Namespace: ptr.To(gwapiv1.Namespace("default")), - Port: ptr.To(gwapiv1.PortNumber(4317)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "otel-collector", + Namespace: ptr.To(gwapiv1.Namespace("default")), + Port: ptr.To(gwapiv1.PortNumber(4317)), + }, }, }, }, @@ -507,12 +511,14 @@ func TestValidateServiceForReconcile(t *testing.T) { Tracing: &egv1a1.ProxyTracing{ Provider: egv1a1.TracingProvider{ Type: egv1a1.TracingProviderTypeOpenTelemetry, - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "otel-collector", - Namespace: ptr.To(gwapiv1.Namespace("default")), - Port: ptr.To(gwapiv1.PortNumber(4317)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "otel-collector", + Namespace: ptr.To(gwapiv1.Namespace("default")), + Port: ptr.To(gwapiv1.PortNumber(4317)), + }, }, }, }, @@ -675,10 +681,12 @@ func TestValidateServiceForReconcile(t *testing.T) { }, ExtAuth: &egv1a1.ExtAuth{ HTTP: &egv1a1.HTTPExtAuthService{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "ext-auth-http-service", + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "ext-auth-http-service", + }, }, }, }, @@ -708,10 +716,12 @@ func TestValidateServiceForReconcile(t *testing.T) { }, ExtAuth: &egv1a1.ExtAuth{ GRPC: &egv1a1.GRPCExtAuthService{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "ext-auth-grpc-service", + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "ext-auth-grpc-service", + }, }, }, }, @@ -741,10 +751,12 @@ func TestValidateServiceForReconcile(t *testing.T) { }, ExtProc: []egv1a1.ExtProc{ { - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "ext-proc-service", + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "ext-proc-service", + }, }, }, }, @@ -774,10 +786,12 @@ func TestValidateServiceForReconcile(t *testing.T) { }, ExtProc: []egv1a1.ExtProc{ { - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "ext-proc-service", + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "ext-proc-service", + }, }, }, }, diff --git a/internal/xds/bootstrap/bootstrap_test.go b/internal/xds/bootstrap/bootstrap_test.go index 19e020c499e..2023a7096bd 100644 --- a/internal/xds/bootstrap/bootstrap_test.go +++ b/internal/xds/bootstrap/bootstrap_test.go @@ -86,12 +86,14 @@ func TestGetRenderedBootstrapConfig(t *testing.T) { OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ Host: ptr.To("otel-collector.monitoring.svc"), Port: 4317, - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "otel-collector", - Namespace: ptr.To(gwapiv1.Namespace("monitoring")), - Port: ptr.To(gwapiv1.PortNumber(4317)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "otel-collector", + Namespace: ptr.To(gwapiv1.Namespace("monitoring")), + Port: ptr.To(gwapiv1.PortNumber(4317)), + }, }, }, }, diff --git a/internal/xds/translator/accesslog.go b/internal/xds/translator/accesslog.go index 01c448b65e9..8acb6e4b005 100644 --- a/internal/xds/translator/accesslog.go +++ b/internal/xds/translator/accesslog.go @@ -478,14 +478,27 @@ func processClusterForAccessLog(tCtx *types.ResourceVersionTable, al *ir.AccessL if al == nil { return nil } - // add clusters for ALS access logs for _, als := range al.ALS { + traffic := als.Traffic + // Make sure that there are safe defaults for the traffic + if traffic == nil { + traffic = &ir.TrafficFeatures{} + } if err := addXdsCluster(tCtx, &xdsClusterArgs{ - name: als.Destination.Name, - settings: als.Destination.Settings, - tSocket: nil, - endpointType: EndpointTypeStatic, + name: als.Destination.Name, + settings: als.Destination.Settings, + tSocket: nil, + endpointType: EndpointTypeStatic, + loadBalancer: traffic.LoadBalancer, + proxyProtocol: traffic.ProxyProtocol, + circuitBreaker: traffic.CircuitBreaker, + healthCheck: traffic.HealthCheck, + timeout: traffic.Timeout, + tcpkeepalive: traffic.TCPKeepalive, + backendConnection: traffic.BackendConnection, + dns: traffic.DNS, + http2Settings: traffic.HTTP2, }); err != nil && !errors.Is(err, ErrXdsClusterExists) { return err } @@ -493,12 +506,27 @@ func processClusterForAccessLog(tCtx *types.ResourceVersionTable, al *ir.AccessL // add clusters for Open Telemetry access logs for _, otel := range al.OpenTelemetry { + traffic := otel.Traffic + // Make sure that there are safe defaults for the traffic + if traffic == nil { + traffic = &ir.TrafficFeatures{} + } + if err := addXdsCluster(tCtx, &xdsClusterArgs{ - name: otel.Destination.Name, - settings: otel.Destination.Settings, - tSocket: nil, - endpointType: EndpointTypeDNS, - metrics: metrics, + name: otel.Destination.Name, + settings: otel.Destination.Settings, + tSocket: nil, + endpointType: EndpointTypeDNS, + metrics: metrics, + loadBalancer: traffic.LoadBalancer, + proxyProtocol: traffic.ProxyProtocol, + circuitBreaker: traffic.CircuitBreaker, + healthCheck: traffic.HealthCheck, + timeout: traffic.Timeout, + tcpkeepalive: traffic.TCPKeepalive, + backendConnection: traffic.BackendConnection, + dns: traffic.DNS, + http2Settings: traffic.HTTP2, }); err != nil && !errors.Is(err, ErrXdsClusterExists) { return err } diff --git a/internal/xds/translator/cluster.go b/internal/xds/translator/cluster.go index 697736dbc4d..e0f8b3ceba1 100644 --- a/internal/xds/translator/cluster.go +++ b/internal/xds/translator/cluster.go @@ -739,10 +739,7 @@ func (httpRoute *HTTPRouteTranslator) asClusterArgs(extra *ExtraArgs) *xdsCluste clusterArgs.timeout = bt.Timeout clusterArgs.tcpkeepalive = bt.TCPKeepalive clusterArgs.backendConnection = bt.BackendConnection - } - - if httpRoute.DNS != nil { - clusterArgs.dns = httpRoute.DNS + clusterArgs.dns = bt.DNS } return clusterArgs diff --git a/internal/xds/translator/extauth.go b/internal/xds/translator/extauth.go index 35ca41e79f6..3b64326c4c3 100644 --- a/internal/xds/translator/extauth.go +++ b/internal/xds/translator/extauth.go @@ -222,13 +222,13 @@ func (*extAuth) patchResources(tCtx *types.ResourceVersionTable, } if route.Security.ExtAuth.HTTP != nil { if err := createExtServiceXDSCluster( - &route.Security.ExtAuth.HTTP.Destination, tCtx); err != nil && !errors.Is( + &route.Security.ExtAuth.HTTP.Destination, route.Security.ExtAuth.Traffic, tCtx); err != nil && !errors.Is( err, ErrXdsClusterExists) { errs = errors.Join(errs, err) } } else { if err := createExtServiceXDSCluster( - &route.Security.ExtAuth.GRPC.Destination, tCtx); err != nil && !errors.Is( + &route.Security.ExtAuth.GRPC.Destination, route.Security.ExtAuth.Traffic, tCtx); err != nil && !errors.Is( err, ErrXdsClusterExists) { errs = errors.Join(errs, err) } diff --git a/internal/xds/translator/extproc.go b/internal/xds/translator/extproc.go index 6f4db53a08b..2bc6c4b6ba6 100644 --- a/internal/xds/translator/extproc.go +++ b/internal/xds/translator/extproc.go @@ -173,12 +173,11 @@ func (*extProc) patchResources(tCtx *types.ResourceVersionTable, for i := range route.EnvoyExtensions.ExtProcs { ep := route.EnvoyExtensions.ExtProcs[i] if err := createExtServiceXDSCluster( - &ep.Destination, tCtx); err != nil && !errors.Is( + &ep.Destination, ep.Traffic, tCtx); err != nil && !errors.Is( err, ErrXdsClusterExists) { errs = errors.Join(errs, err) } } - } return errs diff --git a/internal/xds/translator/httpfilters.go b/internal/xds/translator/httpfilters.go index ad5789fb6ff..1b994fba669 100644 --- a/internal/xds/translator/httpfilters.go +++ b/internal/xds/translator/httpfilters.go @@ -114,8 +114,10 @@ func newOrderedHTTPFilter(filter *hcmv3.HttpFilter) *OrderedHTTPFilter { order = 5 case isFilterType(filter, egv1a1.EnvoyFilterJWTAuthn): order = 6 + case isFilterType(filter, egv1a1.EnvoyFilterSessionPersistence): + order = 7 case isFilterType(filter, egv1a1.EnvoyFilterExtProc): - order = 7 + mustGetFilterIndex(filter.Name) + order = 8 + mustGetFilterIndex(filter.Name) case isFilterType(filter, egv1a1.EnvoyFilterWasm): order = 100 + mustGetFilterIndex(filter.Name) case isFilterType(filter, egv1a1.EnvoyFilterRBAC): diff --git a/internal/xds/translator/session_persistence.go b/internal/xds/translator/session_persistence.go new file mode 100644 index 00000000000..703e553ce47 --- /dev/null +++ b/internal/xds/translator/session_persistence.go @@ -0,0 +1,169 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +package translator + +import ( + "errors" + "fmt" + "strings" + + corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" + routev3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" + statefulsessionv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/stateful_session/v3" + hcmv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" + cookiev3 "github.com/envoyproxy/go-control-plane/envoy/extensions/http/stateful_session/cookie/v3" + headerv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/http/stateful_session/header/v3" + httpv3 "github.com/envoyproxy/go-control-plane/envoy/type/http/v3" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/anypb" + "google.golang.org/protobuf/types/known/durationpb" + + egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" + "github.com/envoyproxy/gateway/internal/ir" + "github.com/envoyproxy/gateway/internal/xds/types" +) + +const ( + cookieConfigName = "envoy.http.stateful_session.cookie" + headerConfigName = "envoy.http.stateful_session.header" +) + +type sessionPersistence struct{} + +func init() { + registerHTTPFilter(&sessionPersistence{}) +} + +var _ httpFilter = &sessionPersistence{} + +// patchHCM patches the HttpConnectionManager with the filter. +// Note: this method may be called multiple times for the same filter, please +// make sure to avoid duplicate additions of the same filter. +func (s *sessionPersistence) patchHCM(mgr *hcmv3.HttpConnectionManager, irListener *ir.HTTPListener) error { + if mgr == nil { + return errors.New("hcm is nil") + } + + if irListener == nil { + return errors.New("ir listener is nil") + } + + for _, route := range irListener.Routes { + sp := route.SessionPersistence + if sp == nil { + continue + } + + if hcmContainsFilter(mgr, perRouteFilterName(egv1a1.EnvoyFilterSessionPersistence, route.Name)) { + continue + } + + var sessionCfg proto.Message + var configName string + switch { + case sp.Cookie != nil: + configName = cookieConfigName + sessionCfg = &cookiev3.CookieBasedSessionState{ + Cookie: &httpv3.Cookie{ + Name: sp.Cookie.Name, + Path: routePathToCookiePath(route.PathMatch), + Ttl: durationpb.New(sp.Cookie.TTL.Duration), + }, + } + case sp.Header != nil: + configName = headerConfigName + sessionCfg = &headerv3.HeaderBasedSessionState{ + Name: sp.Header.Name, + } + } + + sessionCfgAny, err := anypb.New(sessionCfg) + if err != nil { + return fmt.Errorf("failed to marshal %s config: %w", egv1a1.EnvoyFilterSessionPersistence.String(), err) + } + + cfg := &statefulsessionv3.StatefulSession{ + SessionState: &corev3.TypedExtensionConfig{ + Name: configName, + TypedConfig: sessionCfgAny, + }, + } + + cfgAny, err := anypb.New(cfg) + if err != nil { + return fmt.Errorf("failed to marshal %s config: %w", egv1a1.EnvoyFilterSessionPersistence.String(), err) + } + + mgr.HttpFilters = append(mgr.HttpFilters, &hcmv3.HttpFilter{ + Name: perRouteFilterName(egv1a1.EnvoyFilterSessionPersistence, route.Name), + Disabled: true, + ConfigType: &hcmv3.HttpFilter_TypedConfig{ + TypedConfig: cfgAny, + }, + }) + } + + return nil +} + +func routePathToCookiePath(path *ir.StringMatch) string { + if path == nil { + return "/" + } + switch { + case path.Exact != nil: + return *path.Exact + case path.Prefix != nil: + return *path.Prefix + case path.SafeRegex != nil: + return getLongestNonRegexPrefix(*path.SafeRegex) + } + + // Shouldn't reach here because the path should be either of the above three kinds. + return "/" +} + +// getLongestNonRegexPrefix takes a regex path and returns the longest non-regex prefix. +// > 3. For an xRoute using a path that is a regex, the Path should be set to the longest non-regex prefix +// (.e.g. if the path is /p1/p2/*/p3 and the request path was /p1/p2/foo/p3, then the cookie path would be /p1/p2). +// https://gateway-api.sigs.k8s.io/geps/gep-1619/#path +func getLongestNonRegexPrefix(path string) string { + parts := strings.Split(path, "/") + var longestNonRegexPrefix []string + for _, part := range parts { + if part == "*" || strings.Contains(part, "*") { + break + } + longestNonRegexPrefix = append(longestNonRegexPrefix, part) + } + + return strings.Join(longestNonRegexPrefix, "/") +} + +// patchRoute patches the provide Route with a filter's Route level configuration. +func (s *sessionPersistence) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error { + if route == nil { + return errors.New("xds route is nil") + } + if irRoute == nil { + return errors.New("ir route is nil") + } + if irRoute.SessionPersistence == nil { + return nil + } + + if err := enableFilterOnRoute(route, perRouteFilterName(egv1a1.EnvoyFilterSessionPersistence, route.Name)); err != nil { + return err + } + + return nil +} + +// patchResources adds all the other needed resources referenced by this +// filter to the resource version table. +func (s *sessionPersistence) patchResources(tCtx *types.ResourceVersionTable, routes []*ir.HTTPRoute) error { + return nil +} diff --git a/internal/xds/translator/testdata/in/xds-ir/accesslog-als-tcp.yaml b/internal/xds/translator/testdata/in/xds-ir/accesslog-als-tcp.yaml index 2d8f0c6aa48..4b437f443e8 100644 --- a/internal/xds/translator/testdata/in/xds-ir/accesslog-als-tcp.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/accesslog-als-tcp.yaml @@ -17,6 +17,27 @@ accesslog: port: 9000 protocol: GRPC weight: 1 + traffic: + backendConnection: + bufferLimit: 20971520 + circuitBreaker: + maxConnections: 2048 + healthCheck: + passive: + baseEjectionTime: 30s + consecutiveGatewayErrors: 4 + consecutive5XxErrors: 5 + consecutiveLocalOriginFailures: 5 + interval: 5s + maxEjectionPercent: 10 + splitExternalLocalOriginErrors: false + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + timeout: + tcp: + connectTimeout: 15s attributes: attr1: value1 attr2: value2 diff --git a/internal/xds/translator/testdata/in/xds-ir/ext-auth-backend.yaml b/internal/xds/translator/testdata/in/xds-ir/ext-auth-backend.yaml new file mode 100644 index 00000000000..4f93e2e7734 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/ext-auth-backend.yaml @@ -0,0 +1,123 @@ +http: + - address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + name: default/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - name: httproute/default/httproute-1/rule/0/match/0/www_foo_com + hostname: www.foo.com + isHTTP2: false + pathMatch: + distinct: false + name: "" + prefix: /foo1 + backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + security: + extAuth: + name: securitypolicy/default/policy-for-http-route-1 + failOpen: false + grpc: + authority: primary.foo.com + destination: + name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend + settings: + - addressType: FQDN + endpoints: + - host: primary.foo.com + port: 9000 + protocol: GRPC + weight: 1 + headersToExtAuth: + - header1 + - header2 + - name: httproute/default/httproute-1/rule/1/match/0/www_foo_com + hostname: www.foo.com + isHTTP2: false + pathMatch: + distinct: false + name: "" + prefix: /foo2 + backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-1/rule/1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + security: + extAuth: + name: securitypolicy/default/policy-for-http-route-1 + failOpen: false + grpc: + authority: primary.foo.com + destination: + name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend + settings: + - addressType: IP + endpoints: + - host: primary.foo.com + port: 3000 + protocol: GRPC + weight: 1 + headersToExtAuth: + - header1 + - header2 + - name: httproute/default/httproute-2/rule/0/match/0/www_bar_com + hostname: www.bar.com + isHTTP2: false + pathMatch: + distinct: false + name: "" + prefix: /bar + backendWeights: + invalid: 0 + valid: 0 + destination: + name: httproute/default/httproute-2/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + security: + extAuth: + name: securitypolicy/default/policy-for-gateway-1 + failOpen: true + http: + authority: primary.foo.com + destination: + name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend + settings: + - addressType: FQDN + endpoints: + - host: primary.foo.com + port: 80 + protocol: HTTP + weight: 1 + headersToBackend: + - header1 + - header2 + path: /auth diff --git a/internal/xds/translator/testdata/in/xds-ir/ext-proc-with-traffic-settings.yaml b/internal/xds/translator/testdata/in/xds-ir/ext-proc-with-traffic-settings.yaml new file mode 100644 index 00000000000..136fd53ff6a --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/ext-proc-with-traffic-settings.yaml @@ -0,0 +1,124 @@ +http: +- address: 0.0.0.0 + hostnames: + - '*' + isHTTP2: false + metadata: + kind: Gateway + name: gateway-1 + namespace: default + sectionName: http + name: default/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - destination: + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + envoyExtensions: + extProcs: + - authority: grpc-backend.envoy-gateway:8000 + destination: + name: envoyextensionpolicy/default/policy-for-http-route/0 + settings: + - addressType: IP + protocol: GRPC + tls: + caCertificate: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + name: policy-btls-grpc/envoy-gateway-ca + sni: grpc-backend + weight: 1 + - addressType: IP + endpoints: + - host: 8.8.8.8 + port: 9000 + protocol: GRPC + weight: 1 + - addressType: IP + endpoints: + - host: 1.1.1.1 + port: 3001 + protocol: GRPC + weight: 1 + - addressType: IP + endpoints: + - host: 2.2.2.2 + port: 3443 + protocol: GRPC + tls: + caCertificate: + certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + name: policy-btls-backend-ip/envoy-gateway-ca + sni: ip-backend + weight: 1 + name: envoyextensionpolicy/default/policy-for-http-route/extproc/0 + traffic: + backendConnection: + bufferLimit: 20971520 + circuitBreaker: + maxConnections: 2048 + healthCheck: + passive: + baseEjectionTime: 30s + consecutiveGatewayErrors: 4 + consecutive5XxErrors: 5 + consecutiveLocalOriginFailures: 5 + interval: 5s + maxEjectionPercent: 10 + splitExternalLocalOriginErrors: false + http2: + initialConnectionWindowSize: 131072 + initialStreamWindowSize: 2097152 + maxConcurrentStreams: 200 + resetStreamOnError: true + loadBalancer: + roundRobin: + slowStart: + window: 5s + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + timeout: + tcp: + connectTimeout: 15s + hostname: www.foo.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + name: httproute/default/httproute-1/rule/0/match/0/www_foo_com + pathMatch: + distinct: false + name: "" + prefix: /foo + - destination: + name: httproute/default/httproute-2/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + protocol: HTTP + weight: 1 + hostname: www.bar.com + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-2 + namespace: default + name: httproute/default/httproute-2/rule/0/match/0/www_bar_com + pathMatch: + distinct: false + name: "" + prefix: /bar diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-session-persistence.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-session-persistence.yaml new file mode 100644 index 00000000000..536c5ad50cb --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/http-route-session-persistence.yaml @@ -0,0 +1,66 @@ +http: +- name: "first-listener" + address: "0.0.0.0" + port: 10080 + hostnames: + - "*" + path: + mergeSlashes: true + escapedSlashesAction: UnescapeAndRedirect + routes: + - name: "header-based-session-persistence-route" + hostname: "*" + pathMatch: + safeRegex: "/v1/.*" + sessionPersistence: + header: { + name: "session-header" + } + destination: + name: "regex-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - name: "cookie-based-session-persistence-route-regex" + hostname: "*" + pathMatch: + safeRegex: "/v1/.*/hoge" + sessionPersistence: + cookie: + name: "session-header" + ttl: "1h" + destination: + name: "regex-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - name: "cookie-based-session-persistence-route-prefix" + hostname: "*" + pathMatch: + prefix: "/v2/" + sessionPersistence: + cookie: + name: "session-header" + ttl: "1h" + destination: + name: "regex-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - name: "cookie-based-session-persistence-route-exact" + hostname: "*" + pathMatch: + exact: "/v3/user" + sessionPersistence: + cookie: + name: "session-cookie" + ttl: "1h" + destination: + name: "regex-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 diff --git a/internal/xds/translator/testdata/in/xds-ir/tracing.yaml b/internal/xds/translator/testdata/in/xds-ir/tracing.yaml index 0f3555524ff..2bd8aff1b7d 100644 --- a/internal/xds/translator/testdata/in/xds-ir/tracing.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/tracing.yaml @@ -25,6 +25,27 @@ tracing: - host: "otel-collector.default.svc.cluster.local" port: 4317 protocol: "GRPC" + traffic: + backendConnection: + bufferLimit: 20971520 + circuitBreaker: + maxConnections: 2048 + healthCheck: + passive: + baseEjectionTime: 30s + consecutiveGatewayErrors: 4 + consecutive5XxErrors: 5 + consecutiveLocalOriginFailures: 5 + interval: 5s + maxEjectionPercent: 10 + splitExternalLocalOriginErrors: false + proxyProtocol: + version: V2 + tcpKeepalive: + probes: 7 + timeout: + tcp: + connectTimeout: 15s provider: host: otel-collector.monitoring.svc.cluster.local port: 4317 diff --git a/internal/xds/translator/testdata/out/xds-ir/accesslog-als-tcp.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/accesslog-als-tcp.clusters.yaml index 9603f302b73..be515fc1afb 100755 --- a/internal/xds/translator/testdata/out/xds-ir/accesslog-als-tcp.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/accesslog-als-tcp.clusters.yaml @@ -1,9 +1,10 @@ - circuitBreakers: thresholds: - - maxRetries: 1024 + - maxConnections: 2048 + maxRetries: 1024 commonLbConfig: localityWeightedLbConfig: {} - connectTimeout: 10s + connectTimeout: 15s dnsLookupFamily: V4_ONLY edsClusterConfig: edsConfig: @@ -12,8 +13,24 @@ serviceName: accesslog/monitoring/envoy-als/port/9000 lbPolicy: LEAST_REQUEST name: accesslog/monitoring/envoy-als/port/9000 - outlierDetection: {} - perConnectionBufferLimitBytes: 32768 + outlierDetection: + baseEjectionTime: 30s + consecutive5xx: 5 + consecutiveGatewayFailure: 4 + consecutiveLocalOriginFailure: 5 + interval: 5s + maxEjectionPercent: 10 + perConnectionBufferLimitBytes: 20971520 + transportSocket: + name: envoy.transport_sockets.upstream_proxy_protocol + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.proxy_protocol.v3.ProxyProtocolUpstreamTransport + config: + version: V2 + transportSocket: + name: envoy.transport_sockets.raw_buffer + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.raw_buffer.v3.RawBuffer type: EDS typedExtensionProtocolOptions: envoy.extensions.upstreams.http.v3.HttpProtocolOptions: @@ -22,3 +39,6 @@ http2ProtocolOptions: initialConnectionWindowSize: 1048576 initialStreamWindowSize: 65536 + upstreamConnectionOptions: + tcpKeepalive: + keepaliveProbes: 7 diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.clusters.yaml new file mode 100644 index 00000000000..880f77a06f0 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.clusters.yaml @@ -0,0 +1,112 @@ +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-1/rule/0 + lbPolicy: LEAST_REQUEST + name: httproute/default/httproute-1/rule/0 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-1/rule/1 + lbPolicy: LEAST_REQUEST + name: httproute/default/httproute-1/rule/1 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-2/rule/0 + lbPolicy: LEAST_REQUEST + name: httproute/default/httproute-2/rule/0 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + dnsRefreshRate: 30s + lbPolicy: LEAST_REQUEST + loadAssignment: + clusterName: securitypolicy/default/policy-for-http-route-1/default/grpc-backend + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: primary.foo.com + portValue: 9000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: securitypolicy/default/policy-for-http-route-1/default/grpc-backend/backend/0 + name: securitypolicy/default/policy-for-http-route-1/default/grpc-backend + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + respectDnsTtl: true + type: STRICT_DNS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + dnsRefreshRate: 30s + lbPolicy: LEAST_REQUEST + loadAssignment: + clusterName: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: primary.foo.com + portValue: 80 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend/backend/0 + name: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + respectDnsTtl: true + type: STRICT_DNS diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.endpoints.yaml new file mode 100644 index 00000000000..bf9f0023789 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.endpoints.yaml @@ -0,0 +1,36 @@ +- clusterName: httproute/default/httproute-1/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-1/rule/0/backend/0 +- clusterName: httproute/default/httproute-1/rule/1 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-1/rule/1/backend/0 +- clusterName: httproute/default/httproute-2/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-2/rule/0/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.listeners.yaml new file mode 100644 index 00000000000..c60348a3b91 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.listeners.yaml @@ -0,0 +1,70 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - disabled: true + name: envoy.filters.http.ext_authz/securitypolicy/default/policy-for-http-route-1 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz + allowedHeaders: + patterns: + - exact: header1 + ignoreCase: true + - exact: header2 + ignoreCase: true + grpcService: + envoyGrpc: + authority: primary.foo.com + clusterName: securitypolicy/default/policy-for-http-route-1/default/grpc-backend + timeout: 10s + transportApiVersion: V3 + - disabled: true + name: envoy.filters.http.ext_authz/securitypolicy/default/policy-for-gateway-1 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz + failureModeAllow: true + httpService: + authorizationResponse: + allowedUpstreamHeaders: + patterns: + - exact: header1 + ignoreCase: true + - exact: header2 + ignoreCase: true + pathPrefix: /auth + serverUri: + cluster: securitypolicy/default/policy-for-gateway-1/envoy-gateway/http-backend + timeout: 10s + uri: http://primary.foo.com/auth + transportApiVersion: V3 + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: default/gateway-1/http + serverHeaderTransformation: PASS_THROUGH + statPrefix: http-10080 + useRemoteAddress: true + name: default/gateway-1/http + drainType: MODIFY_ONLY + name: default/gateway-1/http + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.routes.yaml new file mode 100644 index 00000000000..08edfc3c406 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ext-auth-backend.routes.yaml @@ -0,0 +1,44 @@ +- ignorePortInHostMatching: true + name: default/gateway-1/http + virtualHosts: + - domains: + - www.foo.com + name: default/gateway-1/http/www_foo_com + routes: + - match: + pathSeparatedPrefix: /foo1 + name: httproute/default/httproute-1/rule/0/match/0/www_foo_com + route: + cluster: httproute/default/httproute-1/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.ext_authz/securitypolicy/default/policy-for-http-route-1: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + - match: + pathSeparatedPrefix: /foo2 + name: httproute/default/httproute-1/rule/1/match/0/www_foo_com + route: + cluster: httproute/default/httproute-1/rule/1 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.ext_authz/securitypolicy/default/policy-for-http-route-1: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + - domains: + - www.bar.com + name: default/gateway-1/http/www_bar_com + routes: + - match: + pathSeparatedPrefix: /bar + name: httproute/default/httproute-2/rule/0/match/0/www_bar_com + route: + cluster: httproute/default/httproute-2/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.ext_authz/securitypolicy/default/policy-for-gateway-1: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.clusters.yaml new file mode 100644 index 00000000000..4e73328fa8e --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.clusters.yaml @@ -0,0 +1,135 @@ +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-1/rule/0 + lbPolicy: LEAST_REQUEST + name: httproute/default/httproute-1/rule/0 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: httproute/default/httproute-2/rule/0 + lbPolicy: LEAST_REQUEST + name: httproute/default/httproute-2/rule/0 + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS +- circuitBreakers: + thresholds: + - maxConnections: 2048 + maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 15s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: envoyextensionpolicy/default/policy-for-http-route/0 + name: envoyextensionpolicy/default/policy-for-http-route/0 + outlierDetection: + baseEjectionTime: 30s + consecutive5xx: 5 + consecutiveGatewayFailure: 4 + consecutiveLocalOriginFailure: 5 + interval: 5s + maxEjectionPercent: 10 + perConnectionBufferLimitBytes: 20971520 + roundRobinLbConfig: + slowStartConfig: + slowStartWindow: 5s + transportSocket: + name: envoy.transport_sockets.upstream_proxy_protocol + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.proxy_protocol.v3.ProxyProtocolUpstreamTransport + config: + version: V2 + transportSocket: + name: envoy.transport_sockets.raw_buffer + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.raw_buffer.v3.RawBuffer + transportSocketMatches: + - match: + name: envoyextensionpolicy/default/policy-for-http-route/0/tls/0 + name: envoyextensionpolicy/default/policy-for-http-route/0/tls/0 + transportSocket: + name: envoy.transport_sockets.upstream_proxy_protocol + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.proxy_protocol.v3.ProxyProtocolUpstreamTransport + config: + version: V2 + transportSocket: + name: envoy.transport_sockets.tls + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + commonTlsContext: + combinedValidationContext: + defaultValidationContext: + matchTypedSubjectAltNames: + - matcher: + exact: grpc-backend + sanType: DNS + validationContextSdsSecretConfig: + name: policy-btls-grpc/envoy-gateway-ca + sdsConfig: + ads: {} + resourceApiVersion: V3 + sni: grpc-backend + - match: + name: envoyextensionpolicy/default/policy-for-http-route/0/tls/3 + name: envoyextensionpolicy/default/policy-for-http-route/0/tls/3 + transportSocket: + name: envoy.transport_sockets.upstream_proxy_protocol + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.proxy_protocol.v3.ProxyProtocolUpstreamTransport + config: + version: V2 + transportSocket: + name: envoy.transport_sockets.tls + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext + commonTlsContext: + combinedValidationContext: + defaultValidationContext: + matchTypedSubjectAltNames: + - matcher: + exact: ip-backend + sanType: DNS + validationContextSdsSecretConfig: + name: policy-btls-backend-ip/envoy-gateway-ca + sdsConfig: + ads: {} + resourceApiVersion: V3 + sni: ip-backend + type: EDS + typedExtensionProtocolOptions: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicitHttpConfig: + http2ProtocolOptions: + initialConnectionWindowSize: 2097152 + initialStreamWindowSize: 131072 + maxConcurrentStreams: 200 + overrideStreamErrorOnInvalidHttpMessage: true + upstreamConnectionOptions: + tcpKeepalive: + keepaliveProbes: 7 diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.endpoints.yaml new file mode 100644 index 00000000000..a3d4fd4dc11 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.endpoints.yaml @@ -0,0 +1,63 @@ +- clusterName: httproute/default/httproute-1/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-1/rule/0/backend/0 +- clusterName: httproute/default/httproute-2/rule/0 + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 7.7.7.7 + portValue: 8080 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: httproute/default/httproute-2/rule/0/backend/0 +- clusterName: envoyextensionpolicy/default/policy-for-http-route/0 + endpoints: + - loadBalancingWeight: 1 + locality: + region: envoyextensionpolicy/default/policy-for-http-route/0/backend/0 + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 8.8.8.8 + portValue: 9000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: envoyextensionpolicy/default/policy-for-http-route/0/backend/1 + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.1.1.1 + portValue: 3001 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: envoyextensionpolicy/default/policy-for-http-route/0/backend/2 + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 2.2.2.2 + portValue: 3443 + loadBalancingWeight: 1 + metadata: + filterMetadata: + envoy.transport_socket_match: + name: envoyextensionpolicy/default/policy-for-http-route/0/tls/3 + loadBalancingWeight: 1 + locality: + region: envoyextensionpolicy/default/policy-for-http-route/0/backend/3 diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.listeners.yaml new file mode 100644 index 00000000000..7ed44e9e2bf --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.listeners.yaml @@ -0,0 +1,49 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - disabled: true + name: envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0 + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + grpcService: + envoyGrpc: + authority: grpc-backend.envoy-gateway:8000 + clusterName: envoyextensionpolicy/default/policy-for-http-route/0 + timeout: 10s + processingMode: + requestHeaderMode: SKIP + requestTrailerMode: SKIP + responseHeaderMode: SKIP + responseTrailerMode: SKIP + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: default/gateway-1/http + serverHeaderTransformation: PASS_THROUGH + statPrefix: http-10080 + useRemoteAddress: true + name: default/gateway-1/http + drainType: MODIFY_ONLY + name: default/gateway-1/http + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.routes.yaml new file mode 100644 index 00000000000..e5e50ccde27 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.routes.yaml @@ -0,0 +1,59 @@ +- ignorePortInHostMatching: true + name: default/gateway-1/http + virtualHosts: + - domains: + - www.foo.com + metadata: + filterMetadata: + envoy-gateway: + resources: + - kind: Gateway + name: gateway-1 + namespace: default + sectionName: http + name: default/gateway-1/http/www_foo_com + routes: + - match: + pathSeparatedPrefix: /foo + metadata: + filterMetadata: + envoy-gateway: + resources: + - kind: HTTPRoute + name: httproute-1 + namespace: default + name: httproute/default/httproute-1/rule/0/match/0/www_foo_com + route: + cluster: httproute/default/httproute-1/rule/0 + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.ext_proc/envoyextensionpolicy/default/policy-for-http-route/extproc/0: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + - domains: + - www.bar.com + metadata: + filterMetadata: + envoy-gateway: + resources: + - kind: Gateway + name: gateway-1 + namespace: default + sectionName: http + name: default/gateway-1/http/www_bar_com + routes: + - match: + pathSeparatedPrefix: /bar + metadata: + filterMetadata: + envoy-gateway: + resources: + - kind: HTTPRoute + name: httproute-2 + namespace: default + name: httproute/default/httproute-2/rule/0/match/0/www_bar_com + route: + cluster: httproute/default/httproute-2/rule/0 + upgradeConfigs: + - upgradeType: websocket diff --git a/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.secrets.yaml b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.secrets.yaml new file mode 100644 index 00000000000..387926a79f3 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/ext-proc-with-traffic-settings.secrets.yaml @@ -0,0 +1,8 @@ +- name: policy-btls-grpc/envoy-gateway-ca + validationContext: + trustedCa: + inlineBytes: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K +- name: policy-btls-backend-ip/envoy-gateway-ca + validationContext: + trustedCa: + inlineBytes: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKekNDQWcrZ0F3SUJBZ0lVQWw2VUtJdUttenRlODFjbGx6NVBmZE4ySWxJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHQTFVRUNnd0dhM1ZpWldSaU1CNFhEVEl6TVRBdwpNakExTkRFMU4xb1hEVEkwTVRBd01UQTFOREUxTjFvd0l6RVFNQTRHQTFVRUF3d0hiWGxqYVdWdWRERVBNQTBHCkExVUVDZ3dHYTNWaVpXUmlNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdTVGMKMXlqOEhXNjJueW5rRmJYbzRWWEt2MmpDMFBNN2RQVmt5ODdGd2VaY1RLTG9XUVZQUUUycDJrTERLNk9Fc3ptTQp5eXIreHhXdHlpdmVyZW1yV3FuS2tOVFloTGZZUGhnUWtjemliN2VVYWxtRmpVYmhXZEx2SGFrYkVnQ29kbjNiCmt6NTdtSW5YMlZwaURPS2c0a3lIZml1WFdwaUJxckN4MEtOTHB4bzNERVFjRmNzUVRlVEh6aDQ3NTJHVjA0UlUKVGkvR0VXeXpJc2w0Umc3dEd0QXdtY0lQZ1VOVWZZMlEzOTBGR3FkSDRhaG4rbXcvNmFGYlczMVc2M2Q5WUpWcQppb3lPVmNhTUlwTTVCL2M3UWM4U3VoQ0kxWUdoVXlnNGNSSExFdzVWdGlraW95RTNYMDRrbmEzalFBajU0WWJSCmJwRWhjMzVhcEtMQjIxSE9VUUlEQVFBQm8xTXdVVEFkQmdOVkhRNEVGZ1FVeXZsMFZJNXZKVlN1WUZYdTdCNDgKNlBiTUVBb3dId1lEVlIwakJCZ3dGb0FVeXZsMFZJNXZKVlN1WUZYdTdCNDg2UGJNRUFvd0R3WURWUjBUQVFILwpCQVV3QXdFQi96QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFNTHhyZ0ZWTXVOUnEyd0F3Y0J0N1NuTlI1Q2Z6CjJNdlhxNUVVbXVhd0lVaTlrYVlqd2RWaURSRUdTams3SlcxN3ZsNTc2SGpEa2RmUndpNEUyOFN5ZFJJblpmNkoKaThIWmNaN2NhSDZEeFIzMzVmZ0hWekxpNU5pVGNlL09qTkJRelEyTUpYVkRkOERCbUc1ZnlhdEppT0pRNGJXRQpBN0ZsUDBSZFAzQ08zR1dFME01aVhPQjJtMXFXa0UyZXlPNFVIdndUcU5RTGRyZEFYZ0RRbGJhbTllNEJHM0dnCmQvNnRoQWtXRGJ0L1FOVCtFSkhEQ3ZoRFJLaDFSdUdIeWcrWSsvbmViVFdXckZXc2t0UnJiT29IQ1ppQ3BYSTEKM2VYRTZudDBZa2d0RHhHMjJLcW5ocEFnOWdVU3MyaGxob3h5dmt6eUYwbXU2TmhQbHdBZ25xNysvUT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.clusters.yaml new file mode 100644 index 00000000000..0f75e67e278 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.clusters.yaml @@ -0,0 +1,17 @@ +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: + localityWeightedLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_ONLY + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: regex-route-dest + lbPolicy: LEAST_REQUEST + name: regex-route-dest + outlierDetection: {} + perConnectionBufferLimitBytes: 32768 + type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.endpoints.yaml new file mode 100644 index 00000000000..b36ee450059 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.endpoints.yaml @@ -0,0 +1,12 @@ +- clusterName: regex-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: regex-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.listeners.yaml new file mode 100644 index 00000000000..f29e11a27a4 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.listeners.yaml @@ -0,0 +1,80 @@ +- address: + socketAddress: + address: 0.0.0.0 + portValue: 10080 + defaultFilterChain: + filters: + - name: envoy.filters.network.http_connection_manager + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + commonHttpProtocolOptions: + headersWithUnderscoresAction: REJECT_REQUEST + http2ProtocolOptions: + initialConnectionWindowSize: 1048576 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 100 + httpFilters: + - disabled: true + name: envoy.filters.http.stateful_session/header-based-session-persistence-route + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSession + sessionState: + name: envoy.http.stateful_session.header + typedConfig: + '@type': type.googleapis.com/envoy.extensions.http.stateful_session.header.v3.HeaderBasedSessionState + name: session-header + - disabled: true + name: envoy.filters.http.stateful_session/cookie-based-session-persistence-route-regex + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSession + sessionState: + name: envoy.http.stateful_session.cookie + typedConfig: + '@type': type.googleapis.com/envoy.extensions.http.stateful_session.cookie.v3.CookieBasedSessionState + cookie: + name: session-header + path: /v1 + ttl: 3600s + - disabled: true + name: envoy.filters.http.stateful_session/cookie-based-session-persistence-route-prefix + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSession + sessionState: + name: envoy.http.stateful_session.cookie + typedConfig: + '@type': type.googleapis.com/envoy.extensions.http.stateful_session.cookie.v3.CookieBasedSessionState + cookie: + name: session-header + path: /v2/ + ttl: 3600s + - disabled: true + name: envoy.filters.http.stateful_session/cookie-based-session-persistence-route-exact + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSession + sessionState: + name: envoy.http.stateful_session.cookie + typedConfig: + '@type': type.googleapis.com/envoy.extensions.http.stateful_session.cookie.v3.CookieBasedSessionState + cookie: + name: session-cookie + path: /v3/user + ttl: 3600s + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: first-listener + serverHeaderTransformation: PASS_THROUGH + statPrefix: http-10080 + useRemoteAddress: true + name: first-listener + drainType: MODIFY_ONLY + name: first-listener + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.routes.yaml new file mode 100644 index 00000000000..c5450601be4 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.routes.yaml @@ -0,0 +1,53 @@ +- ignorePortInHostMatching: true + name: first-listener + virtualHosts: + - domains: + - '*' + name: first-listener/* + routes: + - match: + safeRegex: + regex: /v1/.* + name: header-based-session-persistence-route + route: + cluster: regex-route-dest + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.stateful_session/header-based-session-persistence-route: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + - match: + safeRegex: + regex: /v1/.*/hoge + name: cookie-based-session-persistence-route-regex + route: + cluster: regex-route-dest + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.stateful_session/cookie-based-session-persistence-route-regex: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + - match: + pathSeparatedPrefix: /v2 + name: cookie-based-session-persistence-route-prefix + route: + cluster: regex-route-dest + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.stateful_session/cookie-based-session-persistence-route-prefix: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} + - match: + path: /v3/user + name: cookie-based-session-persistence-route-exact + route: + cluster: regex-route-dest + upgradeConfigs: + - upgradeType: websocket + typedPerFilterConfig: + envoy.filters.http.stateful_session/cookie-based-session-persistence-route-exact: + '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig + config: {} diff --git a/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml index dce48b2c083..4d419611516 100644 --- a/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/tracing.clusters.yaml @@ -17,10 +17,11 @@ type: EDS - circuitBreakers: thresholds: - - maxRetries: 1024 + - maxConnections: 2048 + maxRetries: 1024 commonLbConfig: localityWeightedLbConfig: {} - connectTimeout: 10s + connectTimeout: 15s dnsLookupFamily: V4_ONLY dnsRefreshRate: 30s lbPolicy: LEAST_REQUEST @@ -38,9 +39,25 @@ locality: region: tracing-0/backend/0 name: tracing-0 - outlierDetection: {} - perConnectionBufferLimitBytes: 32768 + outlierDetection: + baseEjectionTime: 30s + consecutive5xx: 5 + consecutiveGatewayFailure: 4 + consecutiveLocalOriginFailure: 5 + interval: 5s + maxEjectionPercent: 10 + perConnectionBufferLimitBytes: 20971520 respectDnsTtl: true + transportSocket: + name: envoy.transport_sockets.upstream_proxy_protocol + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.proxy_protocol.v3.ProxyProtocolUpstreamTransport + config: + version: V2 + transportSocket: + name: envoy.transport_sockets.raw_buffer + typedConfig: + '@type': type.googleapis.com/envoy.extensions.transport_sockets.raw_buffer.v3.RawBuffer type: STRICT_DNS typedExtensionProtocolOptions: envoy.extensions.upstreams.http.v3.HttpProtocolOptions: @@ -49,3 +66,6 @@ http2ProtocolOptions: initialConnectionWindowSize: 1048576 initialStreamWindowSize: 65536 + upstreamConnectionOptions: + tcpKeepalive: + keepaliveProbes: 7 diff --git a/internal/xds/translator/tracing.go b/internal/xds/translator/tracing.go index b2a52ec6a18..ad9a3ecc0e1 100644 --- a/internal/xds/translator/tracing.go +++ b/internal/xds/translator/tracing.go @@ -160,12 +160,26 @@ func processClusterForTracing(tCtx *types.ResourceVersionTable, tracing *ir.Trac return nil } + traffic := tracing.Traffic + // Make sure that there are safe defaults for the traffic + if traffic == nil { + traffic = &ir.TrafficFeatures{} + } if err := addXdsCluster(tCtx, &xdsClusterArgs{ - name: tracing.Destination.Name, - settings: tracing.Destination.Settings, - tSocket: nil, - endpointType: EndpointTypeDNS, - metrics: metrics, + name: tracing.Destination.Name, + settings: tracing.Destination.Settings, + tSocket: nil, + endpointType: EndpointTypeDNS, + metrics: metrics, + loadBalancer: traffic.LoadBalancer, + proxyProtocol: traffic.ProxyProtocol, + circuitBreaker: traffic.CircuitBreaker, + healthCheck: traffic.HealthCheck, + timeout: traffic.Timeout, + tcpkeepalive: traffic.TCPKeepalive, + backendConnection: traffic.BackendConnection, + dns: traffic.DNS, + http2Settings: traffic.HTTP2, }); err != nil && !errors.Is(err, ErrXdsClusterExists) { return err } diff --git a/internal/xds/translator/translator_test.go b/internal/xds/translator/translator_test.go index 44d6d127bca..f5918b4bc8c 100644 --- a/internal/xds/translator/translator_test.go +++ b/internal/xds/translator/translator_test.go @@ -127,7 +127,6 @@ func TestTranslateXds(t *testing.T) { }, FilterOrder: x.FilterOrder, } - tCtx, err := tr.Translate(x) if !strings.HasSuffix(inputFileName, "partial-invalid") && len(cfg.errMsg) == 0 { t.Logf(inputFileName) diff --git a/internal/xds/translator/utils.go b/internal/xds/translator/utils.go index 10148150865..23d455edd9c 100644 --- a/internal/xds/translator/utils.go +++ b/internal/xds/translator/utils.go @@ -129,13 +129,17 @@ func hcmContainsFilter(mgr *hcmv3.HttpConnectionManager, filterName string) bool return false } -func createExtServiceXDSCluster(rd *ir.RouteDestination, tCtx *types.ResourceVersionTable) error { +func createExtServiceXDSCluster(rd *ir.RouteDestination, traffic *ir.TrafficFeatures, tCtx *types.ResourceVersionTable) error { var ( endpointType EndpointType tSocket *corev3.TransportSocket err error ) + // Make sure that there are safe defaults for the traffic + if traffic == nil { + traffic = &ir.TrafficFeatures{} + } // Get the address type from the first setting. // This is safe because no mixed address types in the settings. addrTypeState := rd.Settings[0].AddressType @@ -144,12 +148,20 @@ func createExtServiceXDSCluster(rd *ir.RouteDestination, tCtx *types.ResourceVer } else { endpointType = EndpointTypeStatic } - if err = addXdsCluster(tCtx, &xdsClusterArgs{ - name: rd.Name, - settings: rd.Settings, - tSocket: tSocket, - endpointType: endpointType, + name: rd.Name, + settings: rd.Settings, + tSocket: tSocket, + loadBalancer: traffic.LoadBalancer, + proxyProtocol: traffic.ProxyProtocol, + circuitBreaker: traffic.CircuitBreaker, + healthCheck: traffic.HealthCheck, + timeout: traffic.Timeout, + tcpkeepalive: traffic.TCPKeepalive, + backendConnection: traffic.BackendConnection, + endpointType: endpointType, + dns: traffic.DNS, + http2Settings: traffic.HTTP2, }); err != nil && !errors.Is(err, ErrXdsClusterExists) { return err } diff --git a/site/content/en/docs/boilerplates/prerequisites.md b/site/content/en/docs/boilerplates/prerequisites.md new file mode 100644 index 00000000000..064238e4d13 --- /dev/null +++ b/site/content/en/docs/boilerplates/prerequisites.md @@ -0,0 +1,24 @@ +--- +--- + +Follow the steps from the [Quickstart](../tasks/quickstart) task to install Envoy Gateway and the example manifest. +Before proceeding, you should be able to query the example backend using HTTP. + +Verify the Gateway status: + +{{< tabpane text=true >}} +{{% tab header="kubectl" %}} + +```shell +kubectl get gateway/eg -o yaml +``` + +{{% /tab %}} +{{% tab header="egctl (experimental)" %}} + +```shell +egctl x status gateway -v +``` + +{{% /tab %}} +{{< /tabpane >}} diff --git a/site/content/en/docs/install/install-yaml.md b/site/content/en/docs/install/install-yaml.md index e675f15fbec..c0a8d1caa72 100644 --- a/site/content/en/docs/install/install-yaml.md +++ b/site/content/en/docs/install/install-yaml.md @@ -13,7 +13,7 @@ installation, it is recommended that you use helm. Envoy Gateway is designed to run in Kubernetes for production. The most essential requirements are: -* Kubernetes 1.25 or later +* Kubernetes 1.27 or later * The `kubectl` command-line tool {{% alert title="Compatibility Matrix" color="warning" %}} @@ -37,3 +37,31 @@ Refer to the [Developer Guide](../../contributions/develop) to learn more. 2. Next Steps Envoy Gateway should now be successfully installed and running, but in order to experience more abilities of Envoy Gateway, you can refer to [Tasks](/latest/tasks). + +## Upgrading from v1.0 + +Due to breaking changes in Gateway API v1.1, some manual migration steps are required to upgrade Envoy Gateway to v1.1. + +1. Delete `BackendTLSPolicy` CRD (and resources): + +```shell +kubectl delete crd backendtlspolicies.gateway.networking.k8s.io +``` + +2. Update Gateway-API and Envoy Gateway CRDs: + +```shell +helm pull oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} --untar +kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/gatewayapi-crds.yaml +kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/generated +``` + +3. Update your `BackendTLSPolicy` and `GRPCRoute` resources according to Gateway-API [v1.1 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v11-upgrade-notes) + +4. Update your Envoy Gateway xPolicy resources: remove the namespace section from targetRef. + +5. Install Envoy Gateway {{< yaml-version >}}: + +```shell +helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} -n envoy-gateway-system +``` diff --git a/site/content/en/docs/tasks/operations/customize-envoyproxy.md b/site/content/en/docs/tasks/operations/customize-envoyproxy.md index 562237bfc43..892c3496ff0 100644 --- a/site/content/en/docs/tasks/operations/customize-envoyproxy.md +++ b/site/content/en/docs/tasks/operations/customize-envoyproxy.md @@ -3,15 +3,68 @@ title: "Customize EnvoyProxy" --- Envoy Gateway provides an [EnvoyProxy][] CRD that can be linked to the ParametersRef -in GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and +in a Gateway and GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and Service. To learn more about GatewayClass and ParametersRef, please refer to [Gateway API documentation][]. ## Prerequisites -Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest. -Before proceeding, you should be able to query the example backend using HTTP. +{{< boilerplate prerequisites >}} -Before you start, you need to add `ParametersRef` in GatewayClass, and refer to EnvoyProxy Config: +Before you start, you need to add `Infrastructure.ParametersRef` in Gateway, and refer to EnvoyProxy Config: +**Note**: `MergeGateways` cannot be set to `true` in your EnvoyProxy config if attaching to the Gateway. + +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + +```shell +cat <}} + +You can also attach the EnvoyProxy resource to the GatewayClass using the `parametersRef` field. +This configuration is discouraged if you plan on creating multiple Gateways linking to the same +GatewayClass and would like different infrastructure configurations for each of them. {{< tabpane text=true >}} {{% tab header="Apply from stdin" %}} @@ -28,7 +81,7 @@ spec: group: gateway.envoyproxy.io kind: EnvoyProxy name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default EOF ``` @@ -48,7 +101,7 @@ spec: group: gateway.envoyproxy.io kind: EnvoyProxy name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default ``` {{% /tab %}} @@ -67,7 +120,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -87,7 +140,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -119,7 +172,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -140,7 +193,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -168,7 +221,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -191,7 +244,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -221,7 +274,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -248,7 +301,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -280,7 +333,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -305,7 +358,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -339,7 +392,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -368,7 +421,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -404,7 +457,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -426,7 +479,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -459,7 +512,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: bootstrap: type: Replace @@ -547,7 +600,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: bootstrap: type: Replace @@ -649,7 +702,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -677,7 +730,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -713,7 +766,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: extraArgs: - --disable-extensions envoy.access_loggers/envoy.access_loggers.wasm @@ -730,7 +783,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: extraArgs: - --disable-extensions envoy.access_loggers/envoy.access_loggers.wasm @@ -756,7 +809,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: eg - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -792,7 +845,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: eg - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -835,7 +888,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: eg - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -860,7 +913,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: eg - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -918,7 +971,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: filterOrder: - name: envoy.filters.http.wasm @@ -938,7 +991,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: filterOrder: - name: envoy.filters.http.wasm diff --git a/site/content/en/docs/tasks/quickstart.md b/site/content/en/docs/tasks/quickstart.md index 03d7b6de842..802b7989a88 100644 --- a/site/content/en/docs/tasks/quickstart.md +++ b/site/content/en/docs/tasks/quickstart.md @@ -92,34 +92,6 @@ curl --verbose --header "Host: www.example.com" http://localhost:8888/get {{% /tab %}} {{< /tabpane >}} -## v1.1 Upgrade Notes - -Due to breaking changes in the Gateway API v1.1, some manual migration steps are required to upgrade Envoy Gateway to v1.1. - -Delete `BackendTLSPolicy` CRD (and resources): - -```shell -kubectl delete crd backendtlspolicies.gateway.networking.k8s.io -``` - -Update Gateway-API and Envoy Gateway CRDs: - -```shell -helm pull oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 --untar -kubectl apply -f ./gateway-helm/crds/gatewayapi-crds.yaml -kubectl apply -f ./gateway-helm/crds/generated -``` - -Update your `BackendTLSPolicy` and `GRPCRoute` resources according to Gateway-API [v1.1 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v11-upgrade-notes) - -Update your Envoy Gateway xPolicy resources: remove the namespace section from targetRef. - -Install Envoy Gateway v1.1.0: - -```shell -helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 -n envoy-gateway-system -``` - ## What to explore next? In this quickstart, you have: diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 255c84a77af..2d2b75a3da3 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -68,7 +68,9 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `backendRefs` | _[BackendRef](#backendref) array_ | true | BackendRefs references a Kubernetes object that represents the gRPC service to which
the access logs will be sent. Currently only Service is supported. | +| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.

Deprecated: Use BackendRefs instead. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent. | +| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection
to the backend. | | `logName` | _string_ | false | LogName defines the friendly name of the access log to be returned in
StreamAccessLogsMessage.Identifier. This allows the access log server
to differentiate between different access logs coming from the same Envoy. | | `type` | _[ALSEnvoyProxyAccessLogType](#alsenvoyproxyaccesslogtype)_ | true | Type defines the type of accesslog. Supported types are "HTTP" and "TCP". | | `http` | _[ALSEnvoyProxyHTTPAccessLogConfig](#alsenvoyproxyhttpaccesslogconfig)_ | false | HTTP defines additional configuration specific to HTTP access logs. | @@ -273,22 +275,34 @@ _Appears in:_ | `status` | _[BackendStatus](#backendstatus)_ | true | Status defines the current status of Backend. | +#### BackendCluster +BackendCluster contains all the configuration required for configuring access +to a backend. This can include multiple endpoints, and settings that apply for +managing the connection to all these endpoints. + +_Appears in:_ +- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog) +- [ExtProc](#extproc) +- [GRPCExtAuthService](#grpcextauthservice) +- [HTTPExtAuthService](#httpextauthservice) +- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog) +- [ProxyOpenTelemetrySink](#proxyopentelemetrysink) +- [TracingProvider](#tracingprovider) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.

Deprecated: Use BackendRefs instead. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent. | +| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection
to the backend. | -#### BackendConnection -BackendConnection allows users to configure connection-level settings of backend -_Appears in:_ -- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `bufferLimit` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
If unspecified, an implementation defined default is applied (32768 bytes).
For example, 20Mi, 1Gi, 256Ki etc.
Note: that when the suffix is not provided, the value is interpreted as bytes. | #### BackendEndpoint @@ -333,6 +347,7 @@ BackendRef defines how an ObjectReference that is specific to BackendRef. _Appears in:_ - [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog) +- [BackendCluster](#backendcluster) - [ExtProc](#extproc) - [GRPCExtAuthService](#grpcextauthservice) - [HTTPExtAuthService](#httpextauthservice) @@ -449,19 +464,19 @@ _Appears in:_ | `targetRef` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the resource this policy is being attached to.
This policy and the TargetRef MUST be in the same namespace for this
Policy to have effect

Deprecated: use targetRefs/targetSelectors instead | | `targetRefs` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName) array_ | true | TargetRefs are the names of the Gateway resources this policy
is being attached to. | | `targetSelectors` | _[TargetSelector](#targetselector) array_ | true | TargetSelectors allow targeting resources for this policy based on labels | -| `rateLimit` | _[RateLimitSpec](#ratelimitspec)_ | false | RateLimit allows the user to limit the number of incoming requests
to a predefined value based on attributes within the traffic flow. | | `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to
the backend endpoints | | `proxyProtocol` | _[ProxyProtocol](#proxyprotocol)_ | false | ProxyProtocol enables the Proxy Protocol when communicating with the backend. | | `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the upstream client connection.
Disabled by default. | | `healthCheck` | _[HealthCheck](#healthcheck)_ | false | HealthCheck allows gateway to perform active health checking on backends. | -| `faultInjection` | _[FaultInjection](#faultinjection)_ | false | FaultInjection defines the fault injection policy to be applied. This configuration can be used to
inject delays and abort requests to mimic failure scenarios such as service failures and overloads | | `circuitBreaker` | _[CircuitBreaker](#circuitbreaker)_ | false | Circuit Breaker settings for the upstream connections and requests.
If not set, circuit breakers will be enabled with the default thresholds | -| `retry` | _[Retry](#retry)_ | false | Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
If not set, retry will be disabled. | -| `useClientProtocol` | _boolean_ | false | UseClientProtocol configures Envoy to prefer sending requests to backends using
the same HTTP protocol that the incoming request used. Defaults to false, which means
that Envoy will use the protocol indicated by the attached BackendRef. | | `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. | | `connection` | _[BackendConnection](#backendconnection)_ | false | Connection includes backend connection settings. | | `dns` | _[DNS](#dns)_ | false | DNS includes dns resolution settings. | | `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration for backend connections. | +| `rateLimit` | _[RateLimitSpec](#ratelimitspec)_ | false | RateLimit allows the user to limit the number of incoming requests
to a predefined value based on attributes within the traffic flow. | +| `faultInjection` | _[FaultInjection](#faultinjection)_ | false | FaultInjection defines the fault injection policy to be applied. This configuration can be used to
inject delays and abort requests to mimic failure scenarios such as service failures and overloads | +| `retry` | _[Retry](#retry)_ | false | Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
If not set, retry will be disabled. | +| `useClientProtocol` | _boolean_ | false | UseClientProtocol configures Envoy to prefer sending requests to backends using
the same HTTP protocol that the incoming request used. Defaults to false, which means
that Envoy will use the protocol indicated by the attached BackendRef. | #### BasicAuth @@ -524,22 +539,6 @@ _Appears in:_ | `allowCredentials` | _boolean_ | true | AllowCredentials indicates whether a request can include user credentials
like cookies, authentication headers, or TLS client certificates. | -#### CircuitBreaker - - - -CircuitBreaker defines the Circuit Breaker configuration. - -_Appears in:_ -- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) - -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `maxConnections` | _integer_ | false | The maximum number of connections that Envoy will establish to the referenced backend defined within a xRoute rule. | -| `maxPendingRequests` | _integer_ | false | The maximum number of pending requests that Envoy will queue to the referenced backend defined within a xRoute rule. | -| `maxParallelRequests` | _integer_ | false | The maximum number of parallel requests that Envoy will make to the referenced backend defined within a xRoute rule. | -| `maxParallelRetries` | _integer_ | false | The maximum number of parallel retries that Envoy will make to the referenced backend defined within a xRoute rule. | -| `maxRequestsPerConnection` | _integer_ | false | The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
Default: unlimited. | #### ClaimToHeader @@ -702,6 +701,37 @@ _Appears in:_ | `caCertificateRefs` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference) array_ | false | CACertificateRefs contains one or more references to
Kubernetes objects that contain TLS certificates of
the Certificate Authorities that can be used
as a trust anchor to validate the certificates presented by the client.

A single reference to a Kubernetes ConfigMap or a Kubernetes Secret,
with the CA certificate in a key named `ca.crt` is currently supported.

References to a resource in different namespace are invalid UNLESS there
is a ReferenceGrant in the target namespace that allows the certificate
to be attached. | +#### ClusterSettings + + + +ClusterSettings provides the various knobs that can be set to control how traffic to a given +backend will be configured. + +_Appears in:_ +- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog) +- [BackendCluster](#backendcluster) +- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) +- [ExtProc](#extproc) +- [GRPCExtAuthService](#grpcextauthservice) +- [HTTPExtAuthService](#httpextauthservice) +- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog) +- [ProxyOpenTelemetrySink](#proxyopentelemetrysink) +- [TracingProvider](#tracingprovider) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to
the backend endpoints | +| `proxyProtocol` | _[ProxyProtocol](#proxyprotocol)_ | false | ProxyProtocol enables the Proxy Protocol when communicating with the backend. | +| `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the upstream client connection.
Disabled by default. | +| `healthCheck` | _[HealthCheck](#healthcheck)_ | false | HealthCheck allows gateway to perform active health checking on backends. | +| `circuitBreaker` | _[CircuitBreaker](#circuitbreaker)_ | false | Circuit Breaker settings for the upstream connections and requests.
If not set, circuit breakers will be enabled with the default thresholds | +| `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. | +| `connection` | _[BackendConnection](#backendconnection)_ | false | Connection includes backend connection settings. | +| `dns` | _[DNS](#dns)_ | false | DNS includes dns resolution settings. | +| `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration for backend connections. | + + #### Compression @@ -847,19 +877,6 @@ _Appears in:_ | `RequestHeader` | CustomTagTypeRequestHeader adds value from request header to each span.
| -#### DNS - - - - - -_Appears in:_ -- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) - -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `dnsRefreshRate` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds. | -| `respectDnsTtl` | _boolean_ | true | RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
Defaults to true. | #### EnvironmentCustomTag @@ -947,6 +964,7 @@ _Appears in:_ | `envoy.filters.http.basic_auth` | EnvoyFilterBasicAuth defines the Envoy HTTP basic authentication filter.
| | `envoy.filters.http.oauth2` | EnvoyFilterOAuth2 defines the Envoy HTTP OAuth2 filter.
| | `envoy.filters.http.jwt_authn` | EnvoyFilterJWTAuthn defines the Envoy HTTP JWT authentication filter.
| +| `envoy.filters.http.stateful_session` | EnvoyFilterSessionPersistence defines the Envoy HTTP session persistence filter.
| | `envoy.filters.http.ext_proc` | EnvoyFilterExtProc defines the Envoy HTTP external process filter.
| | `envoy.filters.http.wasm` | EnvoyFilterWasm defines the Envoy HTTP WebAssembly filter.
| | `envoy.filters.http.rbac` | EnvoyFilterRBAC defines the Envoy RBAC filter.
| @@ -1405,7 +1423,7 @@ _Appears in:_ | `extraArgs` | _string array_ | false | ExtraArgs defines additional command line options that are provided to Envoy.
More info: https://www.envoyproxy.io/docs/envoy/latest/operations/cli#command-line-options
Note: some command line options are used internally(e.g. --log-level) so they cannot be provided here. | | `mergeGateways` | _boolean_ | false | MergeGateways defines if Gateway resources should be merged onto the same Envoy Proxy Infrastructure.
Setting this field to true would merge all Gateway Listeners under the parent Gateway Class.
This means that the port, protocol and hostname tuple must be unique for every listener.
If a duplicate listener is detected, the newer listener (based on timestamp) will be rejected and its status will be updated with a "Accepted=False" condition. | | `shutdown` | _[ShutdownConfig](#shutdownconfig)_ | false | Shutdown defines configuration for graceful envoy shutdown process. | -| `filterOrder` | _[FilterPosition](#filterposition) array_ | false | FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain.
The FilterPosition in the list will be applied in the order they are defined.
If unspecified, the default filter order is applied.
Default filter order is:

- envoy.filters.http.health_check

- envoy.filters.http.fault

- envoy.filters.http.cors

- envoy.filters.http.ext_authz

- envoy.filters.http.basic_auth

- envoy.filters.http.oauth2

- envoy.filters.http.jwt_authn

- envoy.filters.http.ext_proc

- envoy.filters.http.wasm

- envoy.filters.http.rbac

- envoy.filters.http.local_ratelimit

- envoy.filters.http.ratelimit

- envoy.filters.http.router

Note: "envoy.filters.http.router" cannot be reordered, it's always the last filter in the chain. | +| `filterOrder` | _[FilterPosition](#filterposition) array_ | false | FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain.
The FilterPosition in the list will be applied in the order they are defined.
If unspecified, the default filter order is applied.
Default filter order is:

- envoy.filters.http.health_check

- envoy.filters.http.fault

- envoy.filters.http.cors

- envoy.filters.http.ext_authz

- envoy.filters.http.basic_auth

- envoy.filters.http.oauth2

- envoy.filters.http.jwt_authn

- envoy.filters.http.stateful_session

- envoy.filters.http.ext_proc

- envoy.filters.http.wasm

- envoy.filters.http.rbac

- envoy.filters.http.local_ratelimit

- envoy.filters.http.ratelimit

- envoy.filters.http.router

Note: "envoy.filters.http.router" cannot be reordered, it's always the last filter in the chain. | | `backendTLS` | _[BackendTLSConfig](#backendtlsconfig)_ | false | BackendTLS is the TLS configuration for the Envoy proxy to use when connecting to backends.
These settings are applied on backends for which TLS policies are specified. | @@ -1466,7 +1484,9 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `backendRefs` | _[BackendRef](#backendref) array_ | true | BackendRefs defines the configuration of the external processing service | +| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.

Deprecated: Use BackendRefs instead. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent. | +| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection
to the backend. | | `messageTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | MessageTimeout is the timeout for a response to be returned from the external processor
Default: 200ms | | `failOpen` | _boolean_ | false | FailOpen defines if requests or responses that cannot be processed due to connectivity to the
external processor are terminated or passed-through.
Default: false | | `processingMode` | _[ExtProcProcessingMode](#extprocprocessingmode)_ | false | ProcessingMode defines how request and response body is processed
Default: header and body are not sent to the external processor | @@ -1693,8 +1713,9 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
Only Service kind is supported for now.

Deprecated: Use BackendRefs instead. | -| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
Only Service kind is supported for now. | +| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.

Deprecated: Use BackendRefs instead. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent. | +| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection
to the backend. | #### Gateway @@ -1786,22 +1807,6 @@ _Appears in:_ | `http10` | _[HTTP10Settings](#http10settings)_ | false | HTTP10 turns on support for HTTP/1.0 and HTTP/0.9 requests. | -#### HTTP2Settings - - - -HTTP2Settings provides HTTP/2 configuration for listeners and backends. - -_Appears in:_ -- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) -- [ClientTrafficPolicySpec](#clienttrafficpolicyspec) - -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `initialStreamWindowSize` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
If not set, the default value is 64 KiB(64*1024). | -| `initialConnectionWindowSize` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
If not set, the default value is 1 MiB. | -| `maxConcurrentStreams` | _integer_ | false | MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
If not set, the default value is 100. | -| `onInvalidMessage` | _[InvalidMessageAction](#invalidmessageaction)_ | false | OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
It's recommended for L2 Envoy deployments to set this value to TerminateStream.
https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
Default: TerminateConnection | #### HTTP3Settings @@ -1858,8 +1863,9 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
Only Service kind is supported for now.

Deprecated: Use BackendRefs instead. | -| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
Only Service kind is supported for now. | +| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.

Deprecated: Use BackendRefs instead. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent. | +| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection
to the backend. | | `path` | _string_ | true | Path is the path of the HTTP External Authorization service.
If path is specified, the authorization request will be sent to that path,
or else the authorization request will be sent to the root path. | | `headersToBackend` | _string array_ | false | HeadersToBackend are the authorization response headers that will be added
to the original client request before sending it to the backend server.
Note that coexisting headers will be overridden.
If not specified, no authorization response headers will be added to the
original client request. | @@ -1958,20 +1964,6 @@ _Appears in:_ | `preserveXRequestID` | _boolean_ | false | PreserveXRequestID configures Envoy to keep the X-Request-ID header if passed for a request that is edge
(Edge request is the request from external clients to front Envoy) and not reset it, which is the current Envoy behaviour.
It defaults to false. | -#### HealthCheck - - - -HealthCheck configuration to decide which endpoints -are healthy and can be used for routing. - -_Appears in:_ -- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) - -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `active` | _[ActiveHealthCheck](#activehealthcheck)_ | false | Active health check configuration | -| `passive` | _[PassiveHealthCheck](#passivehealthcheck)_ | false | Passive passive check configuration | #### HealthCheckSettings @@ -2386,20 +2378,6 @@ _Appears in:_ | `value` | _string_ | true | Value defines the hard-coded value to add to each span. | -#### LoadBalancer - - - -LoadBalancer defines the load balancer policy to be applied. - -_Appears in:_ -- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) - -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `type` | _[LoadBalancerType](#loadbalancertype)_ | true | Type decides the type of Load Balancer policy.
Valid LoadBalancerType values are
"ConsistentHash",
"LeastRequest",
"Random",
"RoundRobin". | -| `consistentHash` | _[ConsistentHash](#consistenthash)_ | false | ConsistentHash defines the configuration when the load balancer type is
set to ConsistentHash | -| `slowStart` | _[SlowStart](#slowstart)_ | false | SlowStart defines the configuration related to the slow start load balancer policy.
If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
Currently this is only supported for RoundRobin and LeastRequest load balancers | #### LoadBalancerType @@ -2535,9 +2513,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | +| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.

Deprecated: Use BackendRefs instead. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent. | +| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection
to the backend. | | `host` | _string_ | false | Host define the extension service hostname.
Deprecated: Use BackendRefs instead. | | `port` | _integer_ | false | Port defines the port the extension service is exposed on.
Deprecated: Use BackendRefs instead. | -| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the access log will be sent.
Only Service kind is supported for now. | | `resources` | _object (keys:string, values:string)_ | false | Resources is a set of labels that describe the source of a log entry, including envoy node info.
It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). | @@ -2892,9 +2872,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | +| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.

Deprecated: Use BackendRefs instead. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent. | +| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection
to the backend. | | `host` | _string_ | false | Host define the service hostname.
Deprecated: Use BackendRefs instead. | | `port` | _integer_ | false | Port defines the port the service is exposed on.
Deprecated: Use BackendRefs instead. | -| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the metric will be sent.
Only Service kind is supported for now. | #### ProxyPrometheusProvider @@ -2912,19 +2894,6 @@ _Appears in:_ | `compression` | _[Compression](#compression)_ | false | Configure the compression on Prometheus endpoint. Compression is useful in situations when bandwidth is scarce and large payloads can be effectively compressed at the expense of higher CPU load. | -#### ProxyProtocol - - - -ProxyProtocol defines the configuration related to the proxy protocol -when communicating with the backend. - -_Appears in:_ -- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) - -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `version` | _[ProxyProtocolVersion](#proxyprotocolversion)_ | true | Version of ProxyProtol
Valid ProxyProtocolVersion values are
"V1"
"V2" | #### ProxyProtocolVersion @@ -3530,21 +3499,6 @@ _Appears in:_ | `idleTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | IdleTimeout for a TCP connection. Idle time is defined as a period in which there are no
bytes sent or received on either the upstream or downstream connection.
Default: 1 hour. | -#### TCPKeepalive - - - -TCPKeepalive define the TCP Keepalive configuration. - -_Appears in:_ -- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) -- [ClientTrafficPolicySpec](#clienttrafficpolicyspec) - -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `probes` | _integer_ | false | The total number of unacknowledged probes to send before deciding
the connection is dead.
Defaults to 9. | -| `idleTime` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | The duration a connection needs to be idle before keep-alive
probes start being sent.
The duration format is
Defaults to `7200s`. | -| `interval` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | The duration between keep-alive probes.
Defaults to `75s`. | #### TCPTimeout @@ -3621,19 +3575,6 @@ _Appears in:_ | `matchLabels` | _object (keys:string, values:string)_ | true | MatchLabels are the set of label selectors for identifying the targeted resource | -#### Timeout - - - -Timeout defines configuration for timeouts related to connections. - -_Appears in:_ -- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) - -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `tcp` | _[TCPTimeout](#tcptimeout)_ | false | Timeout settings for TCP. | -| `http` | _[HTTPTimeout](#httptimeout)_ | false | Timeout settings for HTTP. | #### TracingProvider @@ -3647,10 +3588,12 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | +| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.

Deprecated: Use BackendRefs instead. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent. | +| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection
to the backend. | | `type` | _[TracingProviderType](#tracingprovidertype)_ | true | Type defines the tracing provider type. | | `host` | _string_ | false | Host define the provider service hostname.
Deprecated: Use BackendRefs instead. | | `port` | _integer_ | false | Port defines the port the provider service is exposed on.
Deprecated: Use BackendRefs instead. | -| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the trace will be sent.
Only Service kind is supported for now. | | `zipkin` | _[ZipkinTracingProvider](#zipkintracingprovider)_ | false | Zipkin defines the Zipkin tracing provider configuration | diff --git a/site/content/en/latest/install/install-yaml.md b/site/content/en/latest/install/install-yaml.md index e675f15fbec..c0a8d1caa72 100644 --- a/site/content/en/latest/install/install-yaml.md +++ b/site/content/en/latest/install/install-yaml.md @@ -13,7 +13,7 @@ installation, it is recommended that you use helm. Envoy Gateway is designed to run in Kubernetes for production. The most essential requirements are: -* Kubernetes 1.25 or later +* Kubernetes 1.27 or later * The `kubectl` command-line tool {{% alert title="Compatibility Matrix" color="warning" %}} @@ -37,3 +37,31 @@ Refer to the [Developer Guide](../../contributions/develop) to learn more. 2. Next Steps Envoy Gateway should now be successfully installed and running, but in order to experience more abilities of Envoy Gateway, you can refer to [Tasks](/latest/tasks). + +## Upgrading from v1.0 + +Due to breaking changes in Gateway API v1.1, some manual migration steps are required to upgrade Envoy Gateway to v1.1. + +1. Delete `BackendTLSPolicy` CRD (and resources): + +```shell +kubectl delete crd backendtlspolicies.gateway.networking.k8s.io +``` + +2. Update Gateway-API and Envoy Gateway CRDs: + +```shell +helm pull oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} --untar +kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/gatewayapi-crds.yaml +kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/generated +``` + +3. Update your `BackendTLSPolicy` and `GRPCRoute` resources according to Gateway-API [v1.1 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v11-upgrade-notes) + +4. Update your Envoy Gateway xPolicy resources: remove the namespace section from targetRef. + +5. Install Envoy Gateway {{< yaml-version >}}: + +```shell +helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} -n envoy-gateway-system +``` diff --git a/site/content/en/latest/tasks/operations/customize-envoyproxy.md b/site/content/en/latest/tasks/operations/customize-envoyproxy.md index bfcc3d6e07a..892c3496ff0 100644 --- a/site/content/en/latest/tasks/operations/customize-envoyproxy.md +++ b/site/content/en/latest/tasks/operations/customize-envoyproxy.md @@ -3,14 +3,68 @@ title: "Customize EnvoyProxy" --- Envoy Gateway provides an [EnvoyProxy][] CRD that can be linked to the ParametersRef -in GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and +in a Gateway and GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and Service. To learn more about GatewayClass and ParametersRef, please refer to [Gateway API documentation][]. ## Prerequisites {{< boilerplate prerequisites >}} -Before you start, you need to add `ParametersRef` in GatewayClass, and refer to EnvoyProxy Config: +Before you start, you need to add `Infrastructure.ParametersRef` in Gateway, and refer to EnvoyProxy Config: +**Note**: `MergeGateways` cannot be set to `true` in your EnvoyProxy config if attaching to the Gateway. + +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + +```shell +cat <}} + +You can also attach the EnvoyProxy resource to the GatewayClass using the `parametersRef` field. +This configuration is discouraged if you plan on creating multiple Gateways linking to the same +GatewayClass and would like different infrastructure configurations for each of them. {{< tabpane text=true >}} {{% tab header="Apply from stdin" %}} @@ -27,7 +81,7 @@ spec: group: gateway.envoyproxy.io kind: EnvoyProxy name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default EOF ``` @@ -47,7 +101,7 @@ spec: group: gateway.envoyproxy.io kind: EnvoyProxy name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default ``` {{% /tab %}} @@ -66,7 +120,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -86,7 +140,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -118,7 +172,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -139,7 +193,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -167,7 +221,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -190,7 +244,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -220,7 +274,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -247,7 +301,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -279,7 +333,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -304,7 +358,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -338,7 +392,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -367,7 +421,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -403,7 +457,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -425,7 +479,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -458,7 +512,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: bootstrap: type: Replace @@ -546,7 +600,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: bootstrap: type: Replace @@ -648,7 +702,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -676,7 +730,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -712,7 +766,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: extraArgs: - --disable-extensions envoy.access_loggers/envoy.access_loggers.wasm @@ -729,7 +783,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: extraArgs: - --disable-extensions envoy.access_loggers/envoy.access_loggers.wasm @@ -755,7 +809,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: eg - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -791,7 +845,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: eg - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -834,7 +888,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: eg - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -859,7 +913,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: eg - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -917,7 +971,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: filterOrder: - name: envoy.filters.http.wasm @@ -937,7 +991,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: filterOrder: - name: envoy.filters.http.wasm diff --git a/site/content/en/latest/tasks/quickstart.md b/site/content/en/latest/tasks/quickstart.md index 03d7b6de842..802b7989a88 100644 --- a/site/content/en/latest/tasks/quickstart.md +++ b/site/content/en/latest/tasks/quickstart.md @@ -92,34 +92,6 @@ curl --verbose --header "Host: www.example.com" http://localhost:8888/get {{% /tab %}} {{< /tabpane >}} -## v1.1 Upgrade Notes - -Due to breaking changes in the Gateway API v1.1, some manual migration steps are required to upgrade Envoy Gateway to v1.1. - -Delete `BackendTLSPolicy` CRD (and resources): - -```shell -kubectl delete crd backendtlspolicies.gateway.networking.k8s.io -``` - -Update Gateway-API and Envoy Gateway CRDs: - -```shell -helm pull oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 --untar -kubectl apply -f ./gateway-helm/crds/gatewayapi-crds.yaml -kubectl apply -f ./gateway-helm/crds/generated -``` - -Update your `BackendTLSPolicy` and `GRPCRoute` resources according to Gateway-API [v1.1 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v11-upgrade-notes) - -Update your Envoy Gateway xPolicy resources: remove the namespace section from targetRef. - -Install Envoy Gateway v1.1.0: - -```shell -helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 -n envoy-gateway-system -``` - ## What to explore next? In this quickstart, you have: diff --git a/site/content/en/v1.1/boilerplates/prerequisites.md b/site/content/en/v1.1/boilerplates/prerequisites.md new file mode 100644 index 00000000000..064238e4d13 --- /dev/null +++ b/site/content/en/v1.1/boilerplates/prerequisites.md @@ -0,0 +1,24 @@ +--- +--- + +Follow the steps from the [Quickstart](../tasks/quickstart) task to install Envoy Gateway and the example manifest. +Before proceeding, you should be able to query the example backend using HTTP. + +Verify the Gateway status: + +{{< tabpane text=true >}} +{{% tab header="kubectl" %}} + +```shell +kubectl get gateway/eg -o yaml +``` + +{{% /tab %}} +{{% tab header="egctl (experimental)" %}} + +```shell +egctl x status gateway -v +``` + +{{% /tab %}} +{{< /tabpane >}} diff --git a/site/content/en/v1.1/install/install-yaml.md b/site/content/en/v1.1/install/install-yaml.md index e675f15fbec..c0a8d1caa72 100644 --- a/site/content/en/v1.1/install/install-yaml.md +++ b/site/content/en/v1.1/install/install-yaml.md @@ -13,7 +13,7 @@ installation, it is recommended that you use helm. Envoy Gateway is designed to run in Kubernetes for production. The most essential requirements are: -* Kubernetes 1.25 or later +* Kubernetes 1.27 or later * The `kubectl` command-line tool {{% alert title="Compatibility Matrix" color="warning" %}} @@ -37,3 +37,31 @@ Refer to the [Developer Guide](../../contributions/develop) to learn more. 2. Next Steps Envoy Gateway should now be successfully installed and running, but in order to experience more abilities of Envoy Gateway, you can refer to [Tasks](/latest/tasks). + +## Upgrading from v1.0 + +Due to breaking changes in Gateway API v1.1, some manual migration steps are required to upgrade Envoy Gateway to v1.1. + +1. Delete `BackendTLSPolicy` CRD (and resources): + +```shell +kubectl delete crd backendtlspolicies.gateway.networking.k8s.io +``` + +2. Update Gateway-API and Envoy Gateway CRDs: + +```shell +helm pull oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} --untar +kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/gatewayapi-crds.yaml +kubectl apply --force-conflicts --server-side -f ./gateway-helm/crds/generated +``` + +3. Update your `BackendTLSPolicy` and `GRPCRoute` resources according to Gateway-API [v1.1 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v11-upgrade-notes) + +4. Update your Envoy Gateway xPolicy resources: remove the namespace section from targetRef. + +5. Install Envoy Gateway {{< yaml-version >}}: + +```shell +helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version {{< yaml-version >}} -n envoy-gateway-system +``` diff --git a/site/content/en/v1.1/tasks/operations/customize-envoyproxy.md b/site/content/en/v1.1/tasks/operations/customize-envoyproxy.md index 562237bfc43..892c3496ff0 100644 --- a/site/content/en/v1.1/tasks/operations/customize-envoyproxy.md +++ b/site/content/en/v1.1/tasks/operations/customize-envoyproxy.md @@ -3,15 +3,68 @@ title: "Customize EnvoyProxy" --- Envoy Gateway provides an [EnvoyProxy][] CRD that can be linked to the ParametersRef -in GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and +in a Gateway and GatewayClass, allowing cluster admins to customize the managed EnvoyProxy Deployment and Service. To learn more about GatewayClass and ParametersRef, please refer to [Gateway API documentation][]. ## Prerequisites -Follow the steps from the [Quickstart](../../quickstart) to install Envoy Gateway and the example manifest. -Before proceeding, you should be able to query the example backend using HTTP. +{{< boilerplate prerequisites >}} -Before you start, you need to add `ParametersRef` in GatewayClass, and refer to EnvoyProxy Config: +Before you start, you need to add `Infrastructure.ParametersRef` in Gateway, and refer to EnvoyProxy Config: +**Note**: `MergeGateways` cannot be set to `true` in your EnvoyProxy config if attaching to the Gateway. + +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + +```shell +cat <}} + +You can also attach the EnvoyProxy resource to the GatewayClass using the `parametersRef` field. +This configuration is discouraged if you plan on creating multiple Gateways linking to the same +GatewayClass and would like different infrastructure configurations for each of them. {{< tabpane text=true >}} {{% tab header="Apply from stdin" %}} @@ -28,7 +81,7 @@ spec: group: gateway.envoyproxy.io kind: EnvoyProxy name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default EOF ``` @@ -48,7 +101,7 @@ spec: group: gateway.envoyproxy.io kind: EnvoyProxy name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default ``` {{% /tab %}} @@ -67,7 +120,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -87,7 +140,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -119,7 +172,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -140,7 +193,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -168,7 +221,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -191,7 +244,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -221,7 +274,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -248,7 +301,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -280,7 +333,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -305,7 +358,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -339,7 +392,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -368,7 +421,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -404,7 +457,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -426,7 +479,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -459,7 +512,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: bootstrap: type: Replace @@ -547,7 +600,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: bootstrap: type: Replace @@ -649,7 +702,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -677,7 +730,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -713,7 +766,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: extraArgs: - --disable-extensions envoy.access_loggers/envoy.access_loggers.wasm @@ -730,7 +783,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: extraArgs: - --disable-extensions envoy.access_loggers/envoy.access_loggers.wasm @@ -756,7 +809,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: eg - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -792,7 +845,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: eg - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -835,7 +888,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: eg - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -860,7 +913,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: eg - namespace: envoy-gateway-system + namespace: default spec: provider: type: Kubernetes @@ -918,7 +971,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: filterOrder: - name: envoy.filters.http.wasm @@ -938,7 +991,7 @@ apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: custom-proxy-config - namespace: envoy-gateway-system + namespace: default spec: filterOrder: - name: envoy.filters.http.wasm diff --git a/site/content/en/v1.1/tasks/quickstart.md b/site/content/en/v1.1/tasks/quickstart.md index 03d7b6de842..802b7989a88 100644 --- a/site/content/en/v1.1/tasks/quickstart.md +++ b/site/content/en/v1.1/tasks/quickstart.md @@ -92,34 +92,6 @@ curl --verbose --header "Host: www.example.com" http://localhost:8888/get {{% /tab %}} {{< /tabpane >}} -## v1.1 Upgrade Notes - -Due to breaking changes in the Gateway API v1.1, some manual migration steps are required to upgrade Envoy Gateway to v1.1. - -Delete `BackendTLSPolicy` CRD (and resources): - -```shell -kubectl delete crd backendtlspolicies.gateway.networking.k8s.io -``` - -Update Gateway-API and Envoy Gateway CRDs: - -```shell -helm pull oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 --untar -kubectl apply -f ./gateway-helm/crds/gatewayapi-crds.yaml -kubectl apply -f ./gateway-helm/crds/generated -``` - -Update your `BackendTLSPolicy` and `GRPCRoute` resources according to Gateway-API [v1.1 Upgrade Notes](https://gateway-api.sigs.k8s.io/guides/#v11-upgrade-notes) - -Update your Envoy Gateway xPolicy resources: remove the namespace section from targetRef. - -Install Envoy Gateway v1.1.0: - -```shell -helm upgrade eg oci://docker.io/envoyproxy/gateway-helm --version v1.1.0 -n envoy-gateway-system -``` - ## What to explore next? In this quickstart, you have: diff --git a/site/content/zh/latest/api/extension_types.md b/site/content/zh/latest/api/extension_types.md index 255c84a77af..2d2b75a3da3 100644 --- a/site/content/zh/latest/api/extension_types.md +++ b/site/content/zh/latest/api/extension_types.md @@ -68,7 +68,9 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `backendRefs` | _[BackendRef](#backendref) array_ | true | BackendRefs references a Kubernetes object that represents the gRPC service to which
the access logs will be sent. Currently only Service is supported. | +| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.

Deprecated: Use BackendRefs instead. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent. | +| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection
to the backend. | | `logName` | _string_ | false | LogName defines the friendly name of the access log to be returned in
StreamAccessLogsMessage.Identifier. This allows the access log server
to differentiate between different access logs coming from the same Envoy. | | `type` | _[ALSEnvoyProxyAccessLogType](#alsenvoyproxyaccesslogtype)_ | true | Type defines the type of accesslog. Supported types are "HTTP" and "TCP". | | `http` | _[ALSEnvoyProxyHTTPAccessLogConfig](#alsenvoyproxyhttpaccesslogconfig)_ | false | HTTP defines additional configuration specific to HTTP access logs. | @@ -273,22 +275,34 @@ _Appears in:_ | `status` | _[BackendStatus](#backendstatus)_ | true | Status defines the current status of Backend. | +#### BackendCluster +BackendCluster contains all the configuration required for configuring access +to a backend. This can include multiple endpoints, and settings that apply for +managing the connection to all these endpoints. + +_Appears in:_ +- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog) +- [ExtProc](#extproc) +- [GRPCExtAuthService](#grpcextauthservice) +- [HTTPExtAuthService](#httpextauthservice) +- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog) +- [ProxyOpenTelemetrySink](#proxyopentelemetrysink) +- [TracingProvider](#tracingprovider) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.

Deprecated: Use BackendRefs instead. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent. | +| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection
to the backend. | -#### BackendConnection -BackendConnection allows users to configure connection-level settings of backend -_Appears in:_ -- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `bufferLimit` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | BufferLimit Soft limit on size of the cluster’s connections read and write buffers.
BufferLimit applies to connection streaming (maybe non-streaming) channel between processes, it's in user space.
If unspecified, an implementation defined default is applied (32768 bytes).
For example, 20Mi, 1Gi, 256Ki etc.
Note: that when the suffix is not provided, the value is interpreted as bytes. | #### BackendEndpoint @@ -333,6 +347,7 @@ BackendRef defines how an ObjectReference that is specific to BackendRef. _Appears in:_ - [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog) +- [BackendCluster](#backendcluster) - [ExtProc](#extproc) - [GRPCExtAuthService](#grpcextauthservice) - [HTTPExtAuthService](#httpextauthservice) @@ -449,19 +464,19 @@ _Appears in:_ | `targetRef` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName)_ | true | TargetRef is the name of the resource this policy is being attached to.
This policy and the TargetRef MUST be in the same namespace for this
Policy to have effect

Deprecated: use targetRefs/targetSelectors instead | | `targetRefs` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName) array_ | true | TargetRefs are the names of the Gateway resources this policy
is being attached to. | | `targetSelectors` | _[TargetSelector](#targetselector) array_ | true | TargetSelectors allow targeting resources for this policy based on labels | -| `rateLimit` | _[RateLimitSpec](#ratelimitspec)_ | false | RateLimit allows the user to limit the number of incoming requests
to a predefined value based on attributes within the traffic flow. | | `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to
the backend endpoints | | `proxyProtocol` | _[ProxyProtocol](#proxyprotocol)_ | false | ProxyProtocol enables the Proxy Protocol when communicating with the backend. | | `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the upstream client connection.
Disabled by default. | | `healthCheck` | _[HealthCheck](#healthcheck)_ | false | HealthCheck allows gateway to perform active health checking on backends. | -| `faultInjection` | _[FaultInjection](#faultinjection)_ | false | FaultInjection defines the fault injection policy to be applied. This configuration can be used to
inject delays and abort requests to mimic failure scenarios such as service failures and overloads | | `circuitBreaker` | _[CircuitBreaker](#circuitbreaker)_ | false | Circuit Breaker settings for the upstream connections and requests.
If not set, circuit breakers will be enabled with the default thresholds | -| `retry` | _[Retry](#retry)_ | false | Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
If not set, retry will be disabled. | -| `useClientProtocol` | _boolean_ | false | UseClientProtocol configures Envoy to prefer sending requests to backends using
the same HTTP protocol that the incoming request used. Defaults to false, which means
that Envoy will use the protocol indicated by the attached BackendRef. | | `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. | | `connection` | _[BackendConnection](#backendconnection)_ | false | Connection includes backend connection settings. | | `dns` | _[DNS](#dns)_ | false | DNS includes dns resolution settings. | | `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration for backend connections. | +| `rateLimit` | _[RateLimitSpec](#ratelimitspec)_ | false | RateLimit allows the user to limit the number of incoming requests
to a predefined value based on attributes within the traffic flow. | +| `faultInjection` | _[FaultInjection](#faultinjection)_ | false | FaultInjection defines the fault injection policy to be applied. This configuration can be used to
inject delays and abort requests to mimic failure scenarios such as service failures and overloads | +| `retry` | _[Retry](#retry)_ | false | Retry provides more advanced usage, allowing users to customize the number of retries, retry fallback strategy, and retry triggering conditions.
If not set, retry will be disabled. | +| `useClientProtocol` | _boolean_ | false | UseClientProtocol configures Envoy to prefer sending requests to backends using
the same HTTP protocol that the incoming request used. Defaults to false, which means
that Envoy will use the protocol indicated by the attached BackendRef. | #### BasicAuth @@ -524,22 +539,6 @@ _Appears in:_ | `allowCredentials` | _boolean_ | true | AllowCredentials indicates whether a request can include user credentials
like cookies, authentication headers, or TLS client certificates. | -#### CircuitBreaker - - - -CircuitBreaker defines the Circuit Breaker configuration. - -_Appears in:_ -- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) - -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `maxConnections` | _integer_ | false | The maximum number of connections that Envoy will establish to the referenced backend defined within a xRoute rule. | -| `maxPendingRequests` | _integer_ | false | The maximum number of pending requests that Envoy will queue to the referenced backend defined within a xRoute rule. | -| `maxParallelRequests` | _integer_ | false | The maximum number of parallel requests that Envoy will make to the referenced backend defined within a xRoute rule. | -| `maxParallelRetries` | _integer_ | false | The maximum number of parallel retries that Envoy will make to the referenced backend defined within a xRoute rule. | -| `maxRequestsPerConnection` | _integer_ | false | The maximum number of requests that Envoy will make over a single connection to the referenced backend defined within a xRoute rule.
Default: unlimited. | #### ClaimToHeader @@ -702,6 +701,37 @@ _Appears in:_ | `caCertificateRefs` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference) array_ | false | CACertificateRefs contains one or more references to
Kubernetes objects that contain TLS certificates of
the Certificate Authorities that can be used
as a trust anchor to validate the certificates presented by the client.

A single reference to a Kubernetes ConfigMap or a Kubernetes Secret,
with the CA certificate in a key named `ca.crt` is currently supported.

References to a resource in different namespace are invalid UNLESS there
is a ReferenceGrant in the target namespace that allows the certificate
to be attached. | +#### ClusterSettings + + + +ClusterSettings provides the various knobs that can be set to control how traffic to a given +backend will be configured. + +_Appears in:_ +- [ALSEnvoyProxyAccessLog](#alsenvoyproxyaccesslog) +- [BackendCluster](#backendcluster) +- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) +- [ExtProc](#extproc) +- [GRPCExtAuthService](#grpcextauthservice) +- [HTTPExtAuthService](#httpextauthservice) +- [OpenTelemetryEnvoyProxyAccessLog](#opentelemetryenvoyproxyaccesslog) +- [ProxyOpenTelemetrySink](#proxyopentelemetrysink) +- [TracingProvider](#tracingprovider) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `loadBalancer` | _[LoadBalancer](#loadbalancer)_ | false | LoadBalancer policy to apply when routing traffic from the gateway to
the backend endpoints | +| `proxyProtocol` | _[ProxyProtocol](#proxyprotocol)_ | false | ProxyProtocol enables the Proxy Protocol when communicating with the backend. | +| `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ | false | TcpKeepalive settings associated with the upstream client connection.
Disabled by default. | +| `healthCheck` | _[HealthCheck](#healthcheck)_ | false | HealthCheck allows gateway to perform active health checking on backends. | +| `circuitBreaker` | _[CircuitBreaker](#circuitbreaker)_ | false | Circuit Breaker settings for the upstream connections and requests.
If not set, circuit breakers will be enabled with the default thresholds | +| `timeout` | _[Timeout](#timeout)_ | false | Timeout settings for the backend connections. | +| `connection` | _[BackendConnection](#backendconnection)_ | false | Connection includes backend connection settings. | +| `dns` | _[DNS](#dns)_ | false | DNS includes dns resolution settings. | +| `http2` | _[HTTP2Settings](#http2settings)_ | false | HTTP2 provides HTTP/2 configuration for backend connections. | + + #### Compression @@ -847,19 +877,6 @@ _Appears in:_ | `RequestHeader` | CustomTagTypeRequestHeader adds value from request header to each span.
| -#### DNS - - - - - -_Appears in:_ -- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) - -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `dnsRefreshRate` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | DNSRefreshRate specifies the rate at which DNS records should be refreshed.
Defaults to 30 seconds. | -| `respectDnsTtl` | _boolean_ | true | RespectDNSTTL indicates whether the DNS Time-To-Live (TTL) should be respected.
If the value is set to true, the DNS refresh rate will be set to the resource record’s TTL.
Defaults to true. | #### EnvironmentCustomTag @@ -947,6 +964,7 @@ _Appears in:_ | `envoy.filters.http.basic_auth` | EnvoyFilterBasicAuth defines the Envoy HTTP basic authentication filter.
| | `envoy.filters.http.oauth2` | EnvoyFilterOAuth2 defines the Envoy HTTP OAuth2 filter.
| | `envoy.filters.http.jwt_authn` | EnvoyFilterJWTAuthn defines the Envoy HTTP JWT authentication filter.
| +| `envoy.filters.http.stateful_session` | EnvoyFilterSessionPersistence defines the Envoy HTTP session persistence filter.
| | `envoy.filters.http.ext_proc` | EnvoyFilterExtProc defines the Envoy HTTP external process filter.
| | `envoy.filters.http.wasm` | EnvoyFilterWasm defines the Envoy HTTP WebAssembly filter.
| | `envoy.filters.http.rbac` | EnvoyFilterRBAC defines the Envoy RBAC filter.
| @@ -1405,7 +1423,7 @@ _Appears in:_ | `extraArgs` | _string array_ | false | ExtraArgs defines additional command line options that are provided to Envoy.
More info: https://www.envoyproxy.io/docs/envoy/latest/operations/cli#command-line-options
Note: some command line options are used internally(e.g. --log-level) so they cannot be provided here. | | `mergeGateways` | _boolean_ | false | MergeGateways defines if Gateway resources should be merged onto the same Envoy Proxy Infrastructure.
Setting this field to true would merge all Gateway Listeners under the parent Gateway Class.
This means that the port, protocol and hostname tuple must be unique for every listener.
If a duplicate listener is detected, the newer listener (based on timestamp) will be rejected and its status will be updated with a "Accepted=False" condition. | | `shutdown` | _[ShutdownConfig](#shutdownconfig)_ | false | Shutdown defines configuration for graceful envoy shutdown process. | -| `filterOrder` | _[FilterPosition](#filterposition) array_ | false | FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain.
The FilterPosition in the list will be applied in the order they are defined.
If unspecified, the default filter order is applied.
Default filter order is:

- envoy.filters.http.health_check

- envoy.filters.http.fault

- envoy.filters.http.cors

- envoy.filters.http.ext_authz

- envoy.filters.http.basic_auth

- envoy.filters.http.oauth2

- envoy.filters.http.jwt_authn

- envoy.filters.http.ext_proc

- envoy.filters.http.wasm

- envoy.filters.http.rbac

- envoy.filters.http.local_ratelimit

- envoy.filters.http.ratelimit

- envoy.filters.http.router

Note: "envoy.filters.http.router" cannot be reordered, it's always the last filter in the chain. | +| `filterOrder` | _[FilterPosition](#filterposition) array_ | false | FilterOrder defines the order of filters in the Envoy proxy's HTTP filter chain.
The FilterPosition in the list will be applied in the order they are defined.
If unspecified, the default filter order is applied.
Default filter order is:

- envoy.filters.http.health_check

- envoy.filters.http.fault

- envoy.filters.http.cors

- envoy.filters.http.ext_authz

- envoy.filters.http.basic_auth

- envoy.filters.http.oauth2

- envoy.filters.http.jwt_authn

- envoy.filters.http.stateful_session

- envoy.filters.http.ext_proc

- envoy.filters.http.wasm

- envoy.filters.http.rbac

- envoy.filters.http.local_ratelimit

- envoy.filters.http.ratelimit

- envoy.filters.http.router

Note: "envoy.filters.http.router" cannot be reordered, it's always the last filter in the chain. | | `backendTLS` | _[BackendTLSConfig](#backendtlsconfig)_ | false | BackendTLS is the TLS configuration for the Envoy proxy to use when connecting to backends.
These settings are applied on backends for which TLS policies are specified. | @@ -1466,7 +1484,9 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `backendRefs` | _[BackendRef](#backendref) array_ | true | BackendRefs defines the configuration of the external processing service | +| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.

Deprecated: Use BackendRefs instead. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent. | +| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection
to the backend. | | `messageTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | MessageTimeout is the timeout for a response to be returned from the external processor
Default: 200ms | | `failOpen` | _boolean_ | false | FailOpen defines if requests or responses that cannot be processed due to connectivity to the
external processor are terminated or passed-through.
Default: false | | `processingMode` | _[ExtProcProcessingMode](#extprocprocessingmode)_ | false | ProcessingMode defines how request and response body is processed
Default: header and body are not sent to the external processor | @@ -1693,8 +1713,9 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
Only Service kind is supported for now.

Deprecated: Use BackendRefs instead. | -| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
Only Service kind is supported for now. | +| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.

Deprecated: Use BackendRefs instead. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent. | +| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection
to the backend. | #### Gateway @@ -1786,22 +1807,6 @@ _Appears in:_ | `http10` | _[HTTP10Settings](#http10settings)_ | false | HTTP10 turns on support for HTTP/1.0 and HTTP/0.9 requests. | -#### HTTP2Settings - - - -HTTP2Settings provides HTTP/2 configuration for listeners and backends. - -_Appears in:_ -- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) -- [ClientTrafficPolicySpec](#clienttrafficpolicyspec) - -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `initialStreamWindowSize` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | InitialStreamWindowSize sets the initial window size for HTTP/2 streams.
If not set, the default value is 64 KiB(64*1024). | -| `initialConnectionWindowSize` | _[Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-api)_ | false | InitialConnectionWindowSize sets the initial window size for HTTP/2 connections.
If not set, the default value is 1 MiB. | -| `maxConcurrentStreams` | _integer_ | false | MaxConcurrentStreams sets the maximum number of concurrent streams allowed per connection.
If not set, the default value is 100. | -| `onInvalidMessage` | _[InvalidMessageAction](#invalidmessageaction)_ | false | OnInvalidMessage determines if Envoy will terminate the connection or just the offending stream in the event of HTTP messaging error
It's recommended for L2 Envoy deployments to set this value to TerminateStream.
https://www.envoyproxy.io/docs/envoy/latest/configuration/best_practices/level_two
Default: TerminateConnection | #### HTTP3Settings @@ -1858,8 +1863,9 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | -| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
Only Service kind is supported for now.

Deprecated: Use BackendRefs instead. | -| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent.
Only Service kind is supported for now. | +| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.

Deprecated: Use BackendRefs instead. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent. | +| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection
to the backend. | | `path` | _string_ | true | Path is the path of the HTTP External Authorization service.
If path is specified, the authorization request will be sent to that path,
or else the authorization request will be sent to the root path. | | `headersToBackend` | _string array_ | false | HeadersToBackend are the authorization response headers that will be added
to the original client request before sending it to the backend server.
Note that coexisting headers will be overridden.
If not specified, no authorization response headers will be added to the
original client request. | @@ -1958,20 +1964,6 @@ _Appears in:_ | `preserveXRequestID` | _boolean_ | false | PreserveXRequestID configures Envoy to keep the X-Request-ID header if passed for a request that is edge
(Edge request is the request from external clients to front Envoy) and not reset it, which is the current Envoy behaviour.
It defaults to false. | -#### HealthCheck - - - -HealthCheck configuration to decide which endpoints -are healthy and can be used for routing. - -_Appears in:_ -- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) - -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `active` | _[ActiveHealthCheck](#activehealthcheck)_ | false | Active health check configuration | -| `passive` | _[PassiveHealthCheck](#passivehealthcheck)_ | false | Passive passive check configuration | #### HealthCheckSettings @@ -2386,20 +2378,6 @@ _Appears in:_ | `value` | _string_ | true | Value defines the hard-coded value to add to each span. | -#### LoadBalancer - - - -LoadBalancer defines the load balancer policy to be applied. - -_Appears in:_ -- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) - -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `type` | _[LoadBalancerType](#loadbalancertype)_ | true | Type decides the type of Load Balancer policy.
Valid LoadBalancerType values are
"ConsistentHash",
"LeastRequest",
"Random",
"RoundRobin". | -| `consistentHash` | _[ConsistentHash](#consistenthash)_ | false | ConsistentHash defines the configuration when the load balancer type is
set to ConsistentHash | -| `slowStart` | _[SlowStart](#slowstart)_ | false | SlowStart defines the configuration related to the slow start load balancer policy.
If set, during slow start window, traffic sent to the newly added hosts will gradually increase.
Currently this is only supported for RoundRobin and LeastRequest load balancers | #### LoadBalancerType @@ -2535,9 +2513,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | +| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.

Deprecated: Use BackendRefs instead. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent. | +| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection
to the backend. | | `host` | _string_ | false | Host define the extension service hostname.
Deprecated: Use BackendRefs instead. | | `port` | _integer_ | false | Port defines the port the extension service is exposed on.
Deprecated: Use BackendRefs instead. | -| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the access log will be sent.
Only Service kind is supported for now. | | `resources` | _object (keys:string, values:string)_ | false | Resources is a set of labels that describe the source of a log entry, including envoy node info.
It's recommended to follow [semantic conventions](https://opentelemetry.io/docs/reference/specification/resource/semantic_conventions/). | @@ -2892,9 +2872,11 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | +| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.

Deprecated: Use BackendRefs instead. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent. | +| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection
to the backend. | | `host` | _string_ | false | Host define the service hostname.
Deprecated: Use BackendRefs instead. | | `port` | _integer_ | false | Port defines the port the service is exposed on.
Deprecated: Use BackendRefs instead. | -| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the metric will be sent.
Only Service kind is supported for now. | #### ProxyPrometheusProvider @@ -2912,19 +2894,6 @@ _Appears in:_ | `compression` | _[Compression](#compression)_ | false | Configure the compression on Prometheus endpoint. Compression is useful in situations when bandwidth is scarce and large payloads can be effectively compressed at the expense of higher CPU load. | -#### ProxyProtocol - - - -ProxyProtocol defines the configuration related to the proxy protocol -when communicating with the backend. - -_Appears in:_ -- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) - -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `version` | _[ProxyProtocolVersion](#proxyprotocolversion)_ | true | Version of ProxyProtol
Valid ProxyProtocolVersion values are
"V1"
"V2" | #### ProxyProtocolVersion @@ -3530,21 +3499,6 @@ _Appears in:_ | `idleTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | IdleTimeout for a TCP connection. Idle time is defined as a period in which there are no
bytes sent or received on either the upstream or downstream connection.
Default: 1 hour. | -#### TCPKeepalive - - - -TCPKeepalive define the TCP Keepalive configuration. - -_Appears in:_ -- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) -- [ClientTrafficPolicySpec](#clienttrafficpolicyspec) - -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `probes` | _integer_ | false | The total number of unacknowledged probes to send before deciding
the connection is dead.
Defaults to 9. | -| `idleTime` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | The duration a connection needs to be idle before keep-alive
probes start being sent.
The duration format is
Defaults to `7200s`. | -| `interval` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ | false | The duration between keep-alive probes.
Defaults to `75s`. | #### TCPTimeout @@ -3621,19 +3575,6 @@ _Appears in:_ | `matchLabels` | _object (keys:string, values:string)_ | true | MatchLabels are the set of label selectors for identifying the targeted resource | -#### Timeout - - - -Timeout defines configuration for timeouts related to connections. - -_Appears in:_ -- [BackendTrafficPolicySpec](#backendtrafficpolicyspec) - -| Field | Type | Required | Description | -| --- | --- | --- | --- | -| `tcp` | _[TCPTimeout](#tcptimeout)_ | false | Timeout settings for TCP. | -| `http` | _[HTTPTimeout](#httptimeout)_ | false | Timeout settings for HTTP. | #### TracingProvider @@ -3647,10 +3588,12 @@ _Appears in:_ | Field | Type | Required | Description | | --- | --- | --- | --- | +| `backendRef` | _[BackendObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.BackendObjectReference)_ | true | BackendRef references a Kubernetes object that represents the
backend server to which the authorization request will be sent.

Deprecated: Use BackendRefs instead. | +| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the authorization request will be sent. | +| `backendSettings` | _[ClusterSettings](#clustersettings)_ | false | BackendSettings holds configuration for managing the connection
to the backend. | | `type` | _[TracingProviderType](#tracingprovidertype)_ | true | Type defines the tracing provider type. | | `host` | _string_ | false | Host define the provider service hostname.
Deprecated: Use BackendRefs instead. | | `port` | _integer_ | false | Port defines the port the provider service is exposed on.
Deprecated: Use BackendRefs instead. | -| `backendRefs` | _[BackendRef](#backendref) array_ | false | BackendRefs references a Kubernetes object that represents the
backend server to which the trace will be sent.
Only Service kind is supported for now. | | `zipkin` | _[ZipkinTracingProvider](#zipkintracingprovider)_ | false | Zipkin defines the Zipkin tracing provider configuration | diff --git a/test/cel-validation/backendtrafficpolicy_test.go b/test/cel-validation/backendtrafficpolicy_test.go index 903d3fa19f1..90ea4c3f473 100644 --- a/test/cel-validation/backendtrafficpolicy_test.go +++ b/test/cel-validation/backendtrafficpolicy_test.go @@ -197,10 +197,12 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - LoadBalancer: &egv1a1.LoadBalancer{ - Type: egv1a1.ConsistentHashLoadBalancerType, - ConsistentHash: &egv1a1.ConsistentHash{ - Type: "SourceIP", + ClusterSettings: egv1a1.ClusterSettings{ + LoadBalancer: &egv1a1.LoadBalancer{ + Type: egv1a1.ConsistentHashLoadBalancerType, + ConsistentHash: &egv1a1.ConsistentHash{ + Type: "SourceIP", + }, }, }, } @@ -220,8 +222,10 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - LoadBalancer: &egv1a1.LoadBalancer{ - Type: egv1a1.ConsistentHashLoadBalancerType, + ClusterSettings: egv1a1.ClusterSettings{ + LoadBalancer: &egv1a1.LoadBalancer{ + Type: egv1a1.ConsistentHashLoadBalancerType, + }, }, } }, @@ -242,12 +246,14 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - LoadBalancer: &egv1a1.LoadBalancer{ - Type: egv1a1.ConsistentHashLoadBalancerType, - ConsistentHash: &egv1a1.ConsistentHash{ - Type: "Header", - Header: &egv1a1.Header{ - Name: "name", + ClusterSettings: egv1a1.ClusterSettings{ + LoadBalancer: &egv1a1.LoadBalancer{ + Type: egv1a1.ConsistentHashLoadBalancerType, + ConsistentHash: &egv1a1.ConsistentHash{ + Type: "Header", + Header: &egv1a1.Header{ + Name: "name", + }, }, }, }, @@ -268,10 +274,12 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - LoadBalancer: &egv1a1.LoadBalancer{ - Type: egv1a1.ConsistentHashLoadBalancerType, - ConsistentHash: &egv1a1.ConsistentHash{ - Type: "Header", + ClusterSettings: egv1a1.ClusterSettings{ + LoadBalancer: &egv1a1.LoadBalancer{ + Type: egv1a1.ConsistentHashLoadBalancerType, + ConsistentHash: &egv1a1.ConsistentHash{ + Type: "Header", + }, }, }, } @@ -293,12 +301,14 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - LoadBalancer: &egv1a1.LoadBalancer{ - Type: egv1a1.ConsistentHashLoadBalancerType, - ConsistentHash: &egv1a1.ConsistentHash{ - Type: "Cookie", - Cookie: &egv1a1.Cookie{ - Name: "name", + ClusterSettings: egv1a1.ClusterSettings{ + LoadBalancer: &egv1a1.LoadBalancer{ + Type: egv1a1.ConsistentHashLoadBalancerType, + ConsistentHash: &egv1a1.ConsistentHash{ + Type: "Cookie", + Cookie: &egv1a1.Cookie{ + Name: "name", + }, }, }, }, @@ -319,10 +329,12 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - LoadBalancer: &egv1a1.LoadBalancer{ - Type: egv1a1.ConsistentHashLoadBalancerType, - ConsistentHash: &egv1a1.ConsistentHash{ - Type: "Cookie", + ClusterSettings: egv1a1.ClusterSettings{ + LoadBalancer: &egv1a1.LoadBalancer{ + Type: egv1a1.ConsistentHashLoadBalancerType, + ConsistentHash: &egv1a1.ConsistentHash{ + Type: "Cookie", + }, }, }, } @@ -345,8 +357,10 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - LoadBalancer: &egv1a1.LoadBalancer{ - Type: egv1a1.LeastRequestLoadBalancerType, + ClusterSettings: egv1a1.ClusterSettings{ + LoadBalancer: &egv1a1.LoadBalancer{ + Type: egv1a1.LeastRequestLoadBalancerType, + }, }, } }, @@ -365,11 +379,13 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - LoadBalancer: &egv1a1.LoadBalancer{ - Type: egv1a1.LeastRequestLoadBalancerType, - SlowStart: &egv1a1.SlowStart{ - Window: &metav1.Duration{ - Duration: 10000000, + ClusterSettings: egv1a1.ClusterSettings{ + LoadBalancer: &egv1a1.LoadBalancer{ + Type: egv1a1.LeastRequestLoadBalancerType, + SlowStart: &egv1a1.SlowStart{ + Window: &metav1.Duration{ + Duration: 10000000, + }, }, }, }, @@ -390,11 +406,13 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - LoadBalancer: &egv1a1.LoadBalancer{ - Type: egv1a1.RoundRobinLoadBalancerType, - SlowStart: &egv1a1.SlowStart{ - Window: &metav1.Duration{ - Duration: 10000000, + ClusterSettings: egv1a1.ClusterSettings{ + LoadBalancer: &egv1a1.LoadBalancer{ + Type: egv1a1.RoundRobinLoadBalancerType, + SlowStart: &egv1a1.SlowStart{ + Window: &metav1.Duration{ + Duration: 10000000, + }, }, }, }, @@ -415,11 +433,13 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - LoadBalancer: &egv1a1.LoadBalancer{ - Type: egv1a1.RandomLoadBalancerType, - SlowStart: &egv1a1.SlowStart{ - Window: &metav1.Duration{ - Duration: 10000000, + ClusterSettings: egv1a1.ClusterSettings{ + LoadBalancer: &egv1a1.LoadBalancer{ + Type: egv1a1.RandomLoadBalancerType, + SlowStart: &egv1a1.SlowStart{ + Window: &metav1.Duration{ + Duration: 10000000, + }, }, }, }, @@ -442,11 +462,13 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - LoadBalancer: &egv1a1.LoadBalancer{ - Type: egv1a1.ConsistentHashLoadBalancerType, - SlowStart: &egv1a1.SlowStart{ - Window: &metav1.Duration{ - Duration: 10000000, + ClusterSettings: egv1a1.ClusterSettings{ + LoadBalancer: &egv1a1.LoadBalancer{ + Type: egv1a1.ConsistentHashLoadBalancerType, + SlowStart: &egv1a1.SlowStart{ + Window: &metav1.Duration{ + Duration: 10000000, + }, }, }, }, @@ -606,11 +628,13 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - CircuitBreaker: &egv1a1.CircuitBreaker{ - MaxConnections: valMax, - MaxPendingRequests: valMin, - MaxParallelRequests: nil, - MaxParallelRetries: nil, + ClusterSettings: egv1a1.ClusterSettings{ + CircuitBreaker: &egv1a1.CircuitBreaker{ + MaxConnections: valMax, + MaxPendingRequests: valMin, + MaxParallelRequests: nil, + MaxParallelRetries: nil, + }, }, } }, @@ -631,12 +655,14 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - CircuitBreaker: &egv1a1.CircuitBreaker{ - MaxConnections: valOverMax, - MaxPendingRequests: valUnderMin, - MaxParallelRequests: valOverMax, - MaxRequestsPerConnection: valUnderMin, - MaxParallelRetries: valOverMax, + ClusterSettings: egv1a1.ClusterSettings{ + CircuitBreaker: &egv1a1.CircuitBreaker{ + MaxConnections: valOverMax, + MaxPendingRequests: valUnderMin, + MaxParallelRequests: valOverMax, + MaxRequestsPerConnection: valUnderMin, + MaxParallelRetries: valOverMax, + }, }, } }, @@ -661,11 +687,13 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - HealthCheck: &egv1a1.HealthCheck{ - Active: &egv1a1.ActiveHealthCheck{ - Type: egv1a1.ActiveHealthCheckerTypeHTTP, - HTTP: &egv1a1.HTTPActiveHealthChecker{ - Path: "", + ClusterSettings: egv1a1.ClusterSettings{ + HealthCheck: &egv1a1.HealthCheck{ + Active: &egv1a1.ActiveHealthCheck{ + Type: egv1a1.ActiveHealthCheckerTypeHTTP, + HTTP: &egv1a1.HTTPActiveHealthChecker{ + Path: "", + }, }, }, }, @@ -688,12 +716,14 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - HealthCheck: &egv1a1.HealthCheck{ - Active: &egv1a1.ActiveHealthCheck{ - UnhealthyThreshold: ptr.To[uint32](0), - Type: egv1a1.ActiveHealthCheckerTypeHTTP, - HTTP: &egv1a1.HTTPActiveHealthChecker{ - Path: "/healthz", + ClusterSettings: egv1a1.ClusterSettings{ + HealthCheck: &egv1a1.HealthCheck{ + Active: &egv1a1.ActiveHealthCheck{ + UnhealthyThreshold: ptr.To[uint32](0), + Type: egv1a1.ActiveHealthCheckerTypeHTTP, + HTTP: &egv1a1.HTTPActiveHealthChecker{ + Path: "/healthz", + }, }, }, }, @@ -716,12 +746,14 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - HealthCheck: &egv1a1.HealthCheck{ - Active: &egv1a1.ActiveHealthCheck{ - HealthyThreshold: ptr.To[uint32](0), - Type: egv1a1.ActiveHealthCheckerTypeHTTP, - HTTP: &egv1a1.HTTPActiveHealthChecker{ - Path: "/healthz", + ClusterSettings: egv1a1.ClusterSettings{ + HealthCheck: &egv1a1.HealthCheck{ + Active: &egv1a1.ActiveHealthCheck{ + HealthyThreshold: ptr.To[uint32](0), + Type: egv1a1.ActiveHealthCheckerTypeHTTP, + HTTP: &egv1a1.HTTPActiveHealthChecker{ + Path: "/healthz", + }, }, }, }, @@ -744,10 +776,12 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - HealthCheck: &egv1a1.HealthCheck{ - Active: &egv1a1.ActiveHealthCheck{ - Type: egv1a1.ActiveHealthCheckerTypeHTTP, - TCP: &egv1a1.TCPActiveHealthChecker{}, + ClusterSettings: egv1a1.ClusterSettings{ + HealthCheck: &egv1a1.HealthCheck{ + Active: &egv1a1.ActiveHealthCheck{ + Type: egv1a1.ActiveHealthCheckerTypeHTTP, + TCP: &egv1a1.TCPActiveHealthChecker{}, + }, }, }, } @@ -769,12 +803,14 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - HealthCheck: &egv1a1.HealthCheck{ - Active: &egv1a1.ActiveHealthCheck{ - Type: egv1a1.ActiveHealthCheckerTypeHTTP, - HTTP: &egv1a1.HTTPActiveHealthChecker{ - Path: "/healthz", - ExpectedStatuses: []egv1a1.HTTPStatus{99, 200}, + ClusterSettings: egv1a1.ClusterSettings{ + HealthCheck: &egv1a1.HealthCheck{ + Active: &egv1a1.ActiveHealthCheck{ + Type: egv1a1.ActiveHealthCheckerTypeHTTP, + HTTP: &egv1a1.HTTPActiveHealthChecker{ + Path: "/healthz", + ExpectedStatuses: []egv1a1.HTTPStatus{99, 200}, + }, }, }, }, @@ -797,12 +833,14 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - HealthCheck: &egv1a1.HealthCheck{ - Active: &egv1a1.ActiveHealthCheck{ - Type: egv1a1.ActiveHealthCheckerTypeHTTP, - HTTP: &egv1a1.HTTPActiveHealthChecker{ - Path: "/healthz", - ExpectedStatuses: []egv1a1.HTTPStatus{100, 200, 201}, + ClusterSettings: egv1a1.ClusterSettings{ + HealthCheck: &egv1a1.HealthCheck{ + Active: &egv1a1.ActiveHealthCheck{ + Type: egv1a1.ActiveHealthCheckerTypeHTTP, + HTTP: &egv1a1.HTTPActiveHealthChecker{ + Path: "/healthz", + ExpectedStatuses: []egv1a1.HTTPStatus{100, 200, 201}, + }, }, }, }, @@ -823,12 +861,14 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - HealthCheck: &egv1a1.HealthCheck{ - Active: &egv1a1.ActiveHealthCheck{ - Type: egv1a1.ActiveHealthCheckerTypeHTTP, - HTTP: &egv1a1.HTTPActiveHealthChecker{ - Path: "/healthz", - ExpectedStatuses: []egv1a1.HTTPStatus{200, 300, 601}, + ClusterSettings: egv1a1.ClusterSettings{ + HealthCheck: &egv1a1.HealthCheck{ + Active: &egv1a1.ActiveHealthCheck{ + Type: egv1a1.ActiveHealthCheckerTypeHTTP, + HTTP: &egv1a1.HTTPActiveHealthChecker{ + Path: "/healthz", + ExpectedStatuses: []egv1a1.HTTPStatus{200, 300, 601}, + }, }, }, }, @@ -851,14 +891,16 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - HealthCheck: &egv1a1.HealthCheck{ - Active: &egv1a1.ActiveHealthCheck{ - Type: egv1a1.ActiveHealthCheckerTypeHTTP, - HTTP: &egv1a1.HTTPActiveHealthChecker{ - Path: "/healthz", - ExpectedResponse: &egv1a1.ActiveHealthCheckPayload{ - Type: egv1a1.ActiveHealthCheckPayloadTypeText, - Binary: []byte{'f', 'o', 'o'}, + ClusterSettings: egv1a1.ClusterSettings{ + HealthCheck: &egv1a1.HealthCheck{ + Active: &egv1a1.ActiveHealthCheck{ + Type: egv1a1.ActiveHealthCheckerTypeHTTP, + HTTP: &egv1a1.HTTPActiveHealthChecker{ + Path: "/healthz", + ExpectedResponse: &egv1a1.ActiveHealthCheckPayload{ + Type: egv1a1.ActiveHealthCheckPayloadTypeText, + Binary: []byte{'f', 'o', 'o'}, + }, }, }, }, @@ -882,14 +924,16 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - HealthCheck: &egv1a1.HealthCheck{ - Active: &egv1a1.ActiveHealthCheck{ - Type: egv1a1.ActiveHealthCheckerTypeHTTP, - HTTP: &egv1a1.HTTPActiveHealthChecker{ - Path: "/healthz", - ExpectedResponse: &egv1a1.ActiveHealthCheckPayload{ - Type: egv1a1.ActiveHealthCheckPayloadTypeBinary, - Text: ptr.To("foo"), + ClusterSettings: egv1a1.ClusterSettings{ + HealthCheck: &egv1a1.HealthCheck{ + Active: &egv1a1.ActiveHealthCheck{ + Type: egv1a1.ActiveHealthCheckerTypeHTTP, + HTTP: &egv1a1.HTTPActiveHealthChecker{ + Path: "/healthz", + ExpectedResponse: &egv1a1.ActiveHealthCheckPayload{ + Type: egv1a1.ActiveHealthCheckPayloadTypeBinary, + Text: ptr.To("foo"), + }, }, }, }, @@ -913,17 +957,19 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - HealthCheck: &egv1a1.HealthCheck{ - Active: &egv1a1.ActiveHealthCheck{ - Type: egv1a1.ActiveHealthCheckerTypeTCP, - TCP: &egv1a1.TCPActiveHealthChecker{ - Send: &egv1a1.ActiveHealthCheckPayload{ - Type: egv1a1.ActiveHealthCheckPayloadTypeText, - Binary: []byte{'f', 'o', 'o'}, - }, - Receive: &egv1a1.ActiveHealthCheckPayload{ - Type: egv1a1.ActiveHealthCheckPayloadTypeText, - Text: ptr.To("foo"), + ClusterSettings: egv1a1.ClusterSettings{ + HealthCheck: &egv1a1.HealthCheck{ + Active: &egv1a1.ActiveHealthCheck{ + Type: egv1a1.ActiveHealthCheckerTypeTCP, + TCP: &egv1a1.TCPActiveHealthChecker{ + Send: &egv1a1.ActiveHealthCheckPayload{ + Type: egv1a1.ActiveHealthCheckPayloadTypeText, + Binary: []byte{'f', 'o', 'o'}, + }, + Receive: &egv1a1.ActiveHealthCheckPayload{ + Type: egv1a1.ActiveHealthCheckPayloadTypeText, + Text: ptr.To("foo"), + }, }, }, }, @@ -947,17 +993,19 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - HealthCheck: &egv1a1.HealthCheck{ - Active: &egv1a1.ActiveHealthCheck{ - Type: egv1a1.ActiveHealthCheckerTypeTCP, - TCP: &egv1a1.TCPActiveHealthChecker{ - Send: &egv1a1.ActiveHealthCheckPayload{ - Type: egv1a1.ActiveHealthCheckPayloadTypeText, - Text: ptr.To("foo"), - }, - Receive: &egv1a1.ActiveHealthCheckPayload{ - Type: egv1a1.ActiveHealthCheckPayloadTypeText, - Binary: []byte{'f', 'o', 'o'}, + ClusterSettings: egv1a1.ClusterSettings{ + HealthCheck: &egv1a1.HealthCheck{ + Active: &egv1a1.ActiveHealthCheck{ + Type: egv1a1.ActiveHealthCheckerTypeTCP, + TCP: &egv1a1.TCPActiveHealthChecker{ + Send: &egv1a1.ActiveHealthCheckPayload{ + Type: egv1a1.ActiveHealthCheckPayloadTypeText, + Text: ptr.To("foo"), + }, + Receive: &egv1a1.ActiveHealthCheckPayload{ + Type: egv1a1.ActiveHealthCheckPayloadTypeText, + Binary: []byte{'f', 'o', 'o'}, + }, }, }, }, @@ -982,13 +1030,15 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - Timeout: &egv1a1.Timeout{ - TCP: &egv1a1.TCPTimeout{ - ConnectTimeout: &d, - }, - HTTP: &egv1a1.HTTPTimeout{ - ConnectionIdleTimeout: &d, - MaxConnectionDuration: &d, + ClusterSettings: egv1a1.ClusterSettings{ + Timeout: &egv1a1.Timeout{ + TCP: &egv1a1.TCPTimeout{ + ConnectTimeout: &d, + }, + HTTP: &egv1a1.HTTPTimeout{ + ConnectionIdleTimeout: &d, + MaxConnectionDuration: &d, + }, }, }, } @@ -1078,11 +1128,35 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - Connection: &egv1a1.BackendConnection{ - BufferLimit: ptr.To(resource.MustParse("1Mi")), + ClusterSettings: egv1a1.ClusterSettings{ + Connection: &egv1a1.BackendConnection{ + BufferLimit: ptr.To(resource.MustParse("1Mi")), + }, + }, + } + }, + }, + { + desc: "connectionBufferLimitBytes given as a number", + mutate: func(btp *egv1a1.BackendTrafficPolicy) { + btp.Spec = egv1a1.BackendTrafficPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetRef: &gwapiv1a2.LocalPolicyTargetReferenceWithSectionName{ + LocalPolicyTargetReference: gwapiv1a2.LocalPolicyTargetReference{ + Group: gwapiv1a2.Group("gateway.networking.k8s.io"), + Kind: gwapiv1a2.Kind("Gateway"), + Name: gwapiv1a2.ObjectName("eg"), + }, + }, + }, + ClusterSettings: egv1a1.ClusterSettings{ + Connection: &egv1a1.BackendConnection{ + BufferLimit: ptr.To(resource.MustParse("12345678")), + }, }, } }, + wantErrors: []string{}, }, { desc: "invalid connectionBufferLimitBytes format", @@ -1097,13 +1171,15 @@ func TestBackendTrafficPolicyTarget(t *testing.T) { }, }, }, - Connection: &egv1a1.BackendConnection{ - BufferLimit: ptr.To(resource.MustParse("1m")), + ClusterSettings: egv1a1.ClusterSettings{ + Connection: &egv1a1.BackendConnection{ + BufferLimit: ptr.To(resource.MustParse("1m")), + }, }, } }, wantErrors: []string{ - "spec.connection.bufferLimit: Invalid value: \"\": BufferLimit must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"", + "spec.connection.bufferLimit: Invalid value: \"1m\": spec.connection.bufferLimit in body should match '^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$', : Invalid value: \"\"", }, }, { diff --git a/test/cel-validation/clienttrafficpolicy_test.go b/test/cel-validation/clienttrafficpolicy_test.go index 4d98efd0aa2..b57adf7d025 100644 --- a/test/cel-validation/clienttrafficpolicy_test.go +++ b/test/cel-validation/clienttrafficpolicy_test.go @@ -312,7 +312,7 @@ func TestClientTrafficPolicyTarget(t *testing.T) { } }, wantErrors: []string{ - "spec.connection.bufferLimit: Invalid value: \"\": bufferLimit must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"", + "spec.connection.bufferLimit: Invalid value: \"15m\": spec.connection.bufferLimit in body should match '^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$', : Invalid value: \"\"", }, }, { @@ -334,7 +334,7 @@ func TestClientTrafficPolicyTarget(t *testing.T) { } }, wantErrors: []string{ - "spec.http2.initialStreamWindowSize: Invalid value: \"\": initialStreamWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"", + "spec.http2.initialStreamWindowSize: Invalid value: \"15m\": spec.http2.initialStreamWindowSize in body should match '^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$'", }, }, { @@ -356,7 +356,7 @@ func TestClientTrafficPolicyTarget(t *testing.T) { } }, wantErrors: []string{ - "spec.http2.InitialConnectionWindowSize: Invalid value: \"\": initialConnectionWindowSize must be of the format \"^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$\"", + "spec.http2.initialConnectionWindowSize: Invalid value: \"15m\": spec.http2.initialConnectionWindowSize in body should match '^[1-9]+[0-9]*([EPTGMK]i|[EPTGMk])?$'", }, }, { diff --git a/test/cel-validation/envoyextensionpolicy_test.go b/test/cel-validation/envoyextensionpolicy_test.go index b199ed49d72..5e0e1f37ad9 100644 --- a/test/cel-validation/envoyextensionpolicy_test.go +++ b/test/cel-validation/envoyextensionpolicy_test.go @@ -284,11 +284,13 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { sp.Spec = egv1a1.EnvoyExtensionPolicySpec{ ExtProc: []egv1a1.ExtProc{ { - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "grpc-proc-service", - Port: ptr.To(gwapiv1.PortNumber(80)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "grpc-proc-service", + Port: ptr.To(gwapiv1.PortNumber(80)), + }, }, }, }, @@ -313,12 +315,14 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { sp.Spec = egv1a1.EnvoyExtensionPolicySpec{ ExtProc: []egv1a1.ExtProc{ { - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Group: ptr.To(gwapiv1.Group("unsupported")), - Name: "grpc-proc-service", - Port: ptr.To(gwapiv1.PortNumber(80)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Group: ptr.To(gwapiv1.Group("unsupported")), + Name: "grpc-proc-service", + Port: ptr.To(gwapiv1.PortNumber(80)), + }, }, }, }, @@ -335,7 +339,7 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { }, } }, - wantErrors: []string{"spec.extProc[0].backendRefs: Invalid value: \"array\": BackendRefs only supports Core and gateway.envoyproxy.io group"}, + wantErrors: []string{"spec.extProc[0]: Invalid value: \"object\": BackendRefs only supports Core and gateway.envoyproxy.io group"}, }, { desc: "ExtProc with invalid BackendRef Kind", @@ -343,12 +347,14 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { sp.Spec = egv1a1.EnvoyExtensionPolicySpec{ ExtProc: []egv1a1.ExtProc{ { - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Kind: ptr.To(gwapiv1.Kind("unsupported")), - Name: "grpc-proc-service", - Port: ptr.To(gwapiv1.PortNumber(80)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Kind: ptr.To(gwapiv1.Kind("unsupported")), + Name: "grpc-proc-service", + Port: ptr.To(gwapiv1.PortNumber(80)), + }, }, }, }, @@ -365,7 +371,7 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { }, } }, - wantErrors: []string{"spec.extProc[0].backendRefs: Invalid value: \"array\": BackendRefs only supports Service and Backend kind"}, + wantErrors: []string{"spec.extProc[0]: Invalid value: \"object\": BackendRefs only supports Service and Backend kind"}, }, { desc: "ExtProc with invalid fields", @@ -373,11 +379,13 @@ func TestEnvoyExtensionPolicyTarget(t *testing.T) { sp.Spec = egv1a1.EnvoyExtensionPolicySpec{ ExtProc: []egv1a1.ExtProc{ { - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "grpc-proc-service", - Port: ptr.To(gwapiv1.PortNumber(80)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "grpc-proc-service", + Port: ptr.To(gwapiv1.PortNumber(80)), + }, }, }, }, diff --git a/test/cel-validation/envoyproxy_test.go b/test/cel-validation/envoyproxy_test.go index 4d914a7e9a6..76ba7434048 100644 --- a/test/cel-validation/envoyproxy_test.go +++ b/test/cel-validation/envoyproxy_test.go @@ -488,11 +488,13 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.ProxyAccessLogSinkTypeALS, ALS: &egv1a1.ALSEnvoyProxyAccessLog{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Port: ptr.To(gwapiv1.PortNumber(9000)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(9000)), + }, }, }, }, @@ -519,11 +521,13 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.ProxyAccessLogSinkTypeALS, ALS: &egv1a1.ALSEnvoyProxyAccessLog{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Port: ptr.To(gwapiv1.PortNumber(9000)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(9000)), + }, }, }, }, @@ -552,11 +556,13 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.ProxyAccessLogSinkTypeALS, ALS: &egv1a1.ALSEnvoyProxyAccessLog{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("foo")), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("foo")), + }, }, }, }, @@ -584,11 +590,13 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.ProxyAccessLogSinkTypeALS, ALS: &egv1a1.ALSEnvoyProxyAccessLog{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Group: ptr.To(gwapiv1.Group("foo")), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Group: ptr.To(gwapiv1.Group("foo")), + }, }, }, }, @@ -626,7 +634,7 @@ func TestEnvoyProxyProvider(t *testing.T) { }, } }, - wantErrors: []string{"Invalid value: \"null\""}, + wantErrors: []string{"Invalid value: \"object\": must have at least one backend in backendRefs"}, }, { desc: "invalid-accesslog-ALS-empty-backendrefs", @@ -640,44 +648,8 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.ProxyAccessLogSinkTypeALS, ALS: &egv1a1.ALSEnvoyProxyAccessLog{ - BackendRefs: []egv1a1.BackendRef{}, - Type: egv1a1.ALSEnvoyProxyAccessLogTypeHTTP, - }, - }, - }, - }, - }, - }, - }, - } - }, - wantErrors: []string{"should have at least 1 items"}, - }, - { - desc: "invalid-accesslog-ALS-multi-backendrefs", - mutate: func(envoy *egv1a1.EnvoyProxy) { - envoy.Spec = egv1a1.EnvoyProxySpec{ - Telemetry: &egv1a1.ProxyTelemetry{ - AccessLog: &egv1a1.ProxyAccessLog{ - Settings: []egv1a1.ProxyAccessLogSetting{ - { - Sinks: []egv1a1.ProxyAccessLogSink{ - { - Type: egv1a1.ProxyAccessLogSinkTypeALS, - ALS: &egv1a1.ALSEnvoyProxyAccessLog{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Port: ptr.To(gwapiv1.PortNumber(8080)), - }, - }, - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Port: ptr.To(gwapiv1.PortNumber(8080)), - }, - }, + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{}, }, Type: egv1a1.ALSEnvoyProxyAccessLogTypeHTTP, }, @@ -689,7 +661,7 @@ func TestEnvoyProxyProvider(t *testing.T) { }, } }, - wantErrors: []string{"must have at most 1 items"}, + wantErrors: []string{"must have at least one backend in backendRefs"}, }, { desc: "accesslog-OpenTelemetry", @@ -735,11 +707,13 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("foo")), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("foo")), + }, }, }, }, @@ -752,7 +726,7 @@ func TestEnvoyProxyProvider(t *testing.T) { }, } }, - wantErrors: []string{"only support Service Kind."}, + wantErrors: []string{"Invalid value: \"object\": BackendRefs only supports Service kind."}, }, { desc: "invalid-accesslog-backendref-group", @@ -770,11 +744,13 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Group: ptr.To(gwapiv1.Group("foo")), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Group: ptr.To(gwapiv1.Group("foo")), + }, }, }, }, @@ -805,12 +781,14 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("Service")), - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("Service")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, }, }, }, @@ -824,49 +802,6 @@ func TestEnvoyProxyProvider(t *testing.T) { } }, }, - { - desc: "multi-accesslog-backendref", - mutate: func(envoy *egv1a1.EnvoyProxy) { - envoy.Spec = egv1a1.EnvoyProxySpec{ - Telemetry: &egv1a1.ProxyTelemetry{ - AccessLog: &egv1a1.ProxyAccessLog{ - Settings: []egv1a1.ProxyAccessLogSetting{ - { - Format: &egv1a1.ProxyAccessLogFormat{ - Type: "Text", - Text: ptr.To("[%START_TIME%]"), - }, - Sinks: []egv1a1.ProxyAccessLogSink{ - { - Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry, - OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("Service")), - Port: ptr.To(gwapiv1.PortNumber(8080)), - }, - }, - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("Service")), - Port: ptr.To(gwapiv1.PortNumber(8080)), - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - } - }, - wantErrors: []string{"must have at most 1 items"}, - }, { desc: "accesslog-backendref-empty-kind", mutate: func(envoy *egv1a1.EnvoyProxy) { @@ -883,11 +818,13 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.ProxyAccessLogSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.OpenTelemetryEnvoyProxyAccessLog{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, }, }, }, @@ -993,11 +930,13 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.MetricSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, }, }, }, @@ -1010,39 +949,6 @@ func TestEnvoyProxyProvider(t *testing.T) { }, wantErrors: []string{}, }, - { - desc: "ProxyMetrics-sinks-multi-backendref", - mutate: func(envoy *egv1a1.EnvoyProxy) { - envoy.Spec = egv1a1.EnvoyProxySpec{ - Telemetry: &egv1a1.ProxyTelemetry{ - Metrics: &egv1a1.ProxyMetrics{ - Sinks: []egv1a1.ProxyMetricSink{ - { - Type: egv1a1.MetricSinkTypeOpenTelemetry, - OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Port: ptr.To(gwapiv1.PortNumber(8080)), - }, - }, - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Port: ptr.To(gwapiv1.PortNumber(8080)), - }, - }, - }, - }, - }, - }, - }, - }, - } - }, - wantErrors: []string{"must have at most 1 items"}, - }, { desc: "ProxyMetrics-sinks-backendref-empty-kind", mutate: func(envoy *egv1a1.EnvoyProxy) { @@ -1053,11 +959,13 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.MetricSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, }, }, }, @@ -1080,12 +988,14 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.MetricSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("foo")), - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("foo")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, }, }, }, @@ -1096,7 +1006,7 @@ func TestEnvoyProxyProvider(t *testing.T) { }, } }, - wantErrors: []string{"only support Service Kind."}, + wantErrors: []string{"only supports Service Kind."}, }, { desc: "ProxyMetrics-sinks-invalid-backendref-group", @@ -1108,12 +1018,14 @@ func TestEnvoyProxyProvider(t *testing.T) { { Type: egv1a1.MetricSinkTypeOpenTelemetry, OpenTelemetry: &egv1a1.ProxyOpenTelemetrySink{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Group: ptr.To(gwapiv1.Group("foo")), - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Group: ptr.To(gwapiv1.Group("foo")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, }, }, }, @@ -1134,11 +1046,13 @@ func TestEnvoyProxyProvider(t *testing.T) { Tracing: &egv1a1.ProxyTracing{ Provider: egv1a1.TracingProvider{ Type: egv1a1.TracingProviderTypeOpenTelemetry, - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("foo")), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("foo")), + }, }, }, }, @@ -1147,7 +1061,7 @@ func TestEnvoyProxyProvider(t *testing.T) { }, } }, - wantErrors: []string{"only support Service Kind."}, + wantErrors: []string{"only supports Service Kind."}, }, { desc: "tracing-backendref-empty-kind", @@ -1157,11 +1071,13 @@ func TestEnvoyProxyProvider(t *testing.T) { Tracing: &egv1a1.ProxyTracing{ Provider: egv1a1.TracingProvider{ Type: egv1a1.TracingProviderTypeOpenTelemetry, - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, }, }, }, @@ -1179,42 +1095,14 @@ func TestEnvoyProxyProvider(t *testing.T) { Tracing: &egv1a1.ProxyTracing{ Provider: egv1a1.TracingProvider{ Type: egv1a1.TracingProviderTypeOpenTelemetry, - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("Service")), - Port: ptr.To(gwapiv1.PortNumber(8080)), - }, - }, - }, - }, - }, - }, - } - }, - }, - { - desc: "tracing-multi-backendref", - mutate: func(envoy *egv1a1.EnvoyProxy) { - envoy.Spec = egv1a1.EnvoyProxySpec{ - Telemetry: &egv1a1.ProxyTelemetry{ - Tracing: &egv1a1.ProxyTracing{ - Provider: egv1a1.TracingProvider{ - Type: egv1a1.TracingProviderTypeOpenTelemetry, - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("Service")), - Port: ptr.To(gwapiv1.PortNumber(8080)), - }, - }, - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "fake-service", - Kind: ptr.To(gwapiv1.Kind("Service")), - Port: ptr.To(gwapiv1.PortNumber(8080)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "fake-service", + Kind: ptr.To(gwapiv1.Kind("Service")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + }, }, }, }, @@ -1223,7 +1111,6 @@ func TestEnvoyProxyProvider(t *testing.T) { }, } }, - wantErrors: []string{"must have at most 1 items"}, }, { desc: "tracing-empty-backend", diff --git a/test/cel-validation/securitypolicy_test.go b/test/cel-validation/securitypolicy_test.go index 24f229dd6f1..2ca001cd0c2 100644 --- a/test/cel-validation/securitypolicy_test.go +++ b/test/cel-validation/securitypolicy_test.go @@ -426,9 +426,15 @@ func TestSecurityPolicyTarget(t *testing.T) { sp.Spec = egv1a1.SecurityPolicySpec{ ExtAuth: &egv1a1.ExtAuth{ GRPC: &egv1a1.GRPCExtAuthService{ - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "grpc-auth-service", - Port: ptr.To(gwapiv1.PortNumber(80)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "grpc-auth-service", + Port: ptr.To(gwapiv1.PortNumber(15001)), + }, + }, + }, }, }, }, @@ -451,12 +457,14 @@ func TestSecurityPolicyTarget(t *testing.T) { sp.Spec = egv1a1.SecurityPolicySpec{ ExtAuth: &egv1a1.ExtAuth{ GRPC: &egv1a1.GRPCExtAuthService{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "grpc-auth-service", - Kind: ptr.To(gwapiv1a2.Kind("Service")), - Port: ptr.To(gwapiv1.PortNumber(80)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "grpc-auth-service", + Kind: ptr.To(gwapiv1a2.Kind("Service")), + Port: ptr.To(gwapiv1.PortNumber(80)), + }, }, }, }, @@ -501,9 +509,15 @@ func TestSecurityPolicyTarget(t *testing.T) { sp.Spec = egv1a1.SecurityPolicySpec{ ExtAuth: &egv1a1.ExtAuth{ HTTP: &egv1a1.HTTPExtAuthService{ - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "http-auth-service", - Port: ptr.To(gwapiv1.PortNumber(15001)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "http-auth-service", + Port: ptr.To(gwapiv1.PortNumber(15001)), + }, + }, + }, }, }, }, @@ -526,12 +540,14 @@ func TestSecurityPolicyTarget(t *testing.T) { sp.Spec = egv1a1.SecurityPolicySpec{ ExtAuth: &egv1a1.ExtAuth{ HTTP: &egv1a1.HTTPExtAuthService{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "grpc-auth-service", - Kind: ptr.To(gwapiv1a2.Kind("Service")), - Port: ptr.To(gwapiv1.PortNumber(80)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "grpc-auth-service", + Kind: ptr.To(gwapiv1a2.Kind("Service")), + Port: ptr.To(gwapiv1.PortNumber(80)), + }, }, }, }, @@ -576,15 +592,19 @@ func TestSecurityPolicyTarget(t *testing.T) { sp.Spec = egv1a1.SecurityPolicySpec{ ExtAuth: &egv1a1.ExtAuth{ GRPC: &egv1a1.GRPCExtAuthService{ - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "grpc-auth-service", - Port: ptr.To(gwapiv1.PortNumber(80)), + BackendCluster: egv1a1.BackendCluster{ + BackendRef: &gwapiv1.BackendObjectReference{ + Name: "grpc-auth-service", + Port: ptr.To(gwapiv1.PortNumber(80)), + }, }, }, HTTP: &egv1a1.HTTPExtAuthService{ - BackendRef: &gwapiv1.BackendObjectReference{ - Name: "http-auth-service", - Port: ptr.To(gwapiv1.PortNumber(15001)), + BackendCluster: egv1a1.BackendCluster{ + BackendRef: &gwapiv1.BackendObjectReference{ + Name: "http-auth-service", + Port: ptr.To(gwapiv1.PortNumber(15001)), + }, }, }, }, @@ -609,10 +629,16 @@ func TestSecurityPolicyTarget(t *testing.T) { sp.Spec = egv1a1.SecurityPolicySpec{ ExtAuth: &egv1a1.ExtAuth{ HTTP: &egv1a1.HTTPExtAuthService{ - BackendRef: &gwapiv1.BackendObjectReference{ - Group: ptr.To(gwapiv1.Group("unsupported")), - Name: "http-auth-service", - Port: ptr.To(gwapiv1.PortNumber(15001)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Group: ptr.To(gwapiv1.Group("unsupported")), + Name: "http-auth-service", + Port: ptr.To(gwapiv1.PortNumber(15001)), + }, + }, + }, }, }, }, @@ -628,7 +654,7 @@ func TestSecurityPolicyTarget(t *testing.T) { } }, wantErrors: []string{ - "spec.extAuth: Invalid value: \"object\": group is invalid, only the core API group (specified by omitting the group field or setting it to an empty string) is supported", + " BackendRefs only supports Core and gateway.envoyproxy.io group.", }, }, { @@ -637,10 +663,12 @@ func TestSecurityPolicyTarget(t *testing.T) { sp.Spec = egv1a1.SecurityPolicySpec{ ExtAuth: &egv1a1.ExtAuth{ HTTP: &egv1a1.HTTPExtAuthService{ - BackendRef: &gwapiv1.BackendObjectReference{ - Kind: ptr.To(gwapiv1.Kind("unsupported")), - Name: "http-auth-service", - Port: ptr.To(gwapiv1.PortNumber(15001)), + BackendCluster: egv1a1.BackendCluster{ + BackendRef: &gwapiv1.BackendObjectReference{ + Kind: ptr.To(gwapiv1.Kind("unsupported")), + Name: "http-auth-service", + Port: ptr.To(gwapiv1.PortNumber(15001)), + }, }, }, }, @@ -656,7 +684,8 @@ func TestSecurityPolicyTarget(t *testing.T) { } }, wantErrors: []string{ - "spec.extAuth: Invalid value: \"object\": kind is invalid, only Service (specified by omitting the kind field or setting it to 'Service') is supported", + "BackendRefs must be used, backendRef is not supported.", + "Exactly one backendRef can be specified in backendRefs.", }, }, { @@ -665,12 +694,14 @@ func TestSecurityPolicyTarget(t *testing.T) { sp.Spec = egv1a1.SecurityPolicySpec{ ExtAuth: &egv1a1.ExtAuth{ HTTP: &egv1a1.HTTPExtAuthService{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "grpc-auth-service", - Kind: ptr.To(gwapiv1a2.Kind("unsupported")), - Port: ptr.To(gwapiv1.PortNumber(80)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "grpc-auth-service", + Kind: ptr.To(gwapiv1a2.Kind("unsupported")), + Port: ptr.To(gwapiv1.PortNumber(80)), + }, }, }, }, @@ -687,7 +718,7 @@ func TestSecurityPolicyTarget(t *testing.T) { }, } }, - wantErrors: []string{" only support Service kind"}, + wantErrors: []string{"BackendRefs only supports Service and Backend kind."}, }, { desc: "grpc extAuth service invalid Group", @@ -695,10 +726,16 @@ func TestSecurityPolicyTarget(t *testing.T) { sp.Spec = egv1a1.SecurityPolicySpec{ ExtAuth: &egv1a1.ExtAuth{ GRPC: &egv1a1.GRPCExtAuthService{ - BackendRef: &gwapiv1.BackendObjectReference{ - Group: ptr.To(gwapiv1.Group("unsupported")), - Name: "http-auth-service", - Port: ptr.To(gwapiv1.PortNumber(15001)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Group: ptr.To(gwapiv1.Group("unsupported")), + Name: "http-auth-service", + Port: ptr.To(gwapiv1.PortNumber(15001)), + }, + }, + }, }, }, }, @@ -714,7 +751,7 @@ func TestSecurityPolicyTarget(t *testing.T) { } }, wantErrors: []string{ - "spec.extAuth: Invalid value: \"object\": group is invalid, only the core API group (specified by omitting the group field or setting it to an empty string) is supported", + "BackendRefs only supports Core and gateway.envoyproxy.io group.", }, }, { @@ -723,10 +760,12 @@ func TestSecurityPolicyTarget(t *testing.T) { sp.Spec = egv1a1.SecurityPolicySpec{ ExtAuth: &egv1a1.ExtAuth{ GRPC: &egv1a1.GRPCExtAuthService{ - BackendRef: &gwapiv1.BackendObjectReference{ - Kind: ptr.To(gwapiv1.Kind("unsupported")), - Name: "http-auth-service", - Port: ptr.To(gwapiv1.PortNumber(15001)), + BackendCluster: egv1a1.BackendCluster{ + BackendRef: &gwapiv1.BackendObjectReference{ + Kind: ptr.To(gwapiv1.Kind("unsupported")), + Name: "http-auth-service", + Port: ptr.To(gwapiv1.PortNumber(15001)), + }, }, }, }, @@ -742,7 +781,8 @@ func TestSecurityPolicyTarget(t *testing.T) { } }, wantErrors: []string{ - "spec.extAuth: Invalid value: \"object\": kind is invalid, only Service (specified by omitting the kind field or setting it to 'Service') is supported", + "BackendRefs must be used, backendRef is not supported.", + "Exactly one backendRef can be specified in backendRefs.", }, }, { @@ -751,12 +791,14 @@ func TestSecurityPolicyTarget(t *testing.T) { sp.Spec = egv1a1.SecurityPolicySpec{ ExtAuth: &egv1a1.ExtAuth{ GRPC: &egv1a1.GRPCExtAuthService{ - BackendRefs: []egv1a1.BackendRef{ - { - BackendObjectReference: gwapiv1.BackendObjectReference{ - Name: "grpc-auth-service", - Kind: ptr.To(gwapiv1a2.Kind("unsupported")), - Port: ptr.To(gwapiv1.PortNumber(80)), + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "grpc-auth-service", + Kind: ptr.To(gwapiv1a2.Kind("unsupported")), + Port: ptr.To(gwapiv1.PortNumber(80)), + }, }, }, }, @@ -773,7 +815,9 @@ func TestSecurityPolicyTarget(t *testing.T) { }, } }, - wantErrors: []string{" only support Service kind"}, + wantErrors: []string{ + "spec.extAuth.grpc: Invalid value: \"object\": BackendRefs only supports Service and Backend kind.", + }, }, // JWT @@ -918,6 +962,76 @@ func TestSecurityPolicyTarget(t *testing.T) { }, wantErrors: []string{}, }, + { + desc: "ext-auth-grpc-backend", + mutate: func(sp *egv1a1.SecurityPolicy) { + sp.Spec = egv1a1.SecurityPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetSelectors: []egv1a1.TargetSelector{ + { + Group: ptr.To(gwapiv1a2.Group("gateway.networking.k8s.io")), + Kind: "HTTPRoute", + MatchLabels: map[string]string{ + "eg/namespace": "reference-apps", + }, + }, + }, + }, + ExtAuth: &egv1a1.ExtAuth{ + GRPC: &egv1a1.GRPCExtAuthService{ + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "grpc-auth-backend", + Kind: ptr.To(gwapiv1a2.Kind("Backend")), + Port: ptr.To(gwapiv1.PortNumber(8080)), + Group: ptr.To(gwapiv1a2.Group("gateway.envoyproxy.io")), + }, + }, + }, + }, + }, + }, + } + }, + wantErrors: []string{}, + }, + { + desc: "ext-auth-http-backend", + mutate: func(sp *egv1a1.SecurityPolicy) { + sp.Spec = egv1a1.SecurityPolicySpec{ + PolicyTargetReferences: egv1a1.PolicyTargetReferences{ + TargetSelectors: []egv1a1.TargetSelector{ + { + Group: ptr.To(gwapiv1a2.Group("gateway.networking.k8s.io")), + Kind: "HTTPRoute", + MatchLabels: map[string]string{ + "eg/namespace": "reference-apps", + }, + }, + }, + }, + ExtAuth: &egv1a1.ExtAuth{ + HTTP: &egv1a1.HTTPExtAuthService{ + BackendCluster: egv1a1.BackendCluster{ + BackendRefs: []egv1a1.BackendRef{ + { + BackendObjectReference: gwapiv1.BackendObjectReference{ + Name: "http-auth-backend", + Kind: ptr.To(gwapiv1a2.Kind("Backend")), + Port: ptr.To(gwapiv1.PortNumber(80)), + Group: ptr.To(gwapiv1a2.Group("gateway.envoyproxy.io")), + }, + }, + }, + }, + }, + }, + } + }, + wantErrors: []string{}, + }, } for _, tc := range cases { diff --git a/test/e2e/testdata/cookie-based-session-persistence.yaml b/test/e2e/testdata/cookie-based-session-persistence.yaml new file mode 100644 index 00000000000..60819e18098 --- /dev/null +++ b/test/e2e/testdata/cookie-based-session-persistence.yaml @@ -0,0 +1,29 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: cookie-based-session-persistence + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: same-namespace + rules: + - matches: + - path: + type: PathPrefix + value: /v1 + backendRefs: + - name: infra-backend-v1 + port: 8080 + - matches: + - path: + type: PathPrefix + value: /v2 + backendRefs: + - name: infra-backend-v1 + port: 8080 + sessionPersistence: + sessionName: Session-A + type: Cookie + absoluteTimeout: 10s + cookieConfig: + lifetimeType: Permanent diff --git a/test/e2e/testdata/ext-auth-http-backend-securitypolicy.yaml b/test/e2e/testdata/ext-auth-http-backend-securitypolicy.yaml new file mode 100644 index 00000000000..ebee7ce0c1e --- /dev/null +++ b/test/e2e/testdata/ext-auth-http-backend-securitypolicy.yaml @@ -0,0 +1,56 @@ +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: http-ext-auth-backend + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: same-namespace + hostnames: ["www.example.com"] + rules: + - matches: + - path: + type: PathPrefix + value: /myapp # This is the path that will be protected by ext auth + backendRefs: + - name: infra-backend-v1 + port: 8080 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: http-without-ext-auth-backend + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: same-namespace + hostnames: ["www.example.com"] + rules: + - matches: + - path: + type: PathPrefix + value: /public # This is the path that will be public + backendRefs: + - name: infra-backend-v1 + port: 8080 +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: SecurityPolicy +metadata: + name: ext-auth-backend + namespace: gateway-conformance-infra +spec: + targetRefs: + - group: gateway.networking.k8s.io + kind: HTTPRoute + name: http-ext-auth-backend + extAuth: + http: + backendRefs: + - name: backend-fqdn # should add namespace here because envoy will locate in envoy-gateway-system namespace + kind: Backend + group: gateway.envoyproxy.io + namespace: gateway-conformance-infra + port: 9002 + headersToBackend: ["x-current-user"] diff --git a/test/e2e/testdata/ext-auth-http-backend.yaml b/test/e2e/testdata/ext-auth-http-backend.yaml new file mode 100644 index 00000000000..fe5185a7e11 --- /dev/null +++ b/test/e2e/testdata/ext-auth-http-backend.yaml @@ -0,0 +1,103 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: http-ext-auth-backend + namespace: gateway-conformance-infra +data: + http-ext-auth.js: | + const Http = require("http"); + const path = require("path"); + + const tokens = { + "token1": "user1", + "token2": "user2", + "token3": "user3" + }; + + const server = new Http.Server((req, res) => { + const authorization = req.headers["authorization"] || ""; + const extracted = authorization.split(" "); + if (extracted.length === 2 && extracted[0] === "Bearer") { + const user = checkToken(extracted[1]); + console.log(`token: "${extracted[1]}" user: "${user}`); + if (user !== undefined) { + // The authorization server returns a response with "x-current-user" header for a successful + // request. + res.writeHead(200, { "x-current-user": user }); + return res.end(); + } + } + res.writeHead(403); + res.end(); + }); + + const port = process.env.PORT || 9002; + server.listen(port); + console.log(`starting HTTP server on: ${port}`); + + function checkToken(token) { + return tokens[token]; + } +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: http-ext-auth-backend + namespace: gateway-conformance-infra +spec: + replicas: 1 + selector: + matchLabels: + app: http-ext-auth-backend + template: + metadata: + labels: + app: http-ext-auth-backend + spec: + containers: + - name: http-ext-auth-backend + command: + - node + - /usr/src/app/http-ext-auth.js + image: node:19-bullseye + ports: + - containerPort: 9002 + volumeMounts: + - name: http-ext-auth-backend + mountPath: /usr/src/app + readinessProbe: + httpGet: + httpHeaders: + - name: authorization + value: "Bearer token1" + port: 9002 + volumes: + - name: http-ext-auth-backend + configMap: + name: http-ext-auth-backend +--- +apiVersion: v1 +kind: Service +metadata: + name: http-ext-auth-backend + namespace: gateway-conformance-infra +spec: + selector: + app: http-ext-auth-backend + ports: + - protocol: TCP + port: 9002 + targetPort: 9002 +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: Backend +metadata: + name: backend-fqdn + namespace: gateway-conformance-infra +spec: + endpoints: + - fqdn: + # should add namespace here because envoy will locate in envoy-gateway-system namespace + hostname: http-ext-auth-backend.gateway-conformance-infra + port: 9002 diff --git a/test/e2e/testdata/header-based-session-persistence.yaml b/test/e2e/testdata/header-based-session-persistence.yaml new file mode 100644 index 00000000000..4c6030a99df --- /dev/null +++ b/test/e2e/testdata/header-based-session-persistence.yaml @@ -0,0 +1,30 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: header-based-session-persistence + namespace: gateway-conformance-infra +spec: + parentRefs: + - name: same-namespace + rules: + - matches: + - path: + type: PathPrefix + value: /v1 + backendRefs: + - name: infra-backend-v1 + port: 8080 + - matches: + - path: + type: PathPrefix + value: /v2 + backendRefs: + - name: infra-backend-v1 + port: 8080 + sessionPersistence: + sessionName: Session-A + type: Header + # Actually, absoluteTimeout is not necessary for Header based session persistence. + # But, we have to add it, otherwise the gateway-api validation (mistakenly) rejects it. + # https://github.com/kubernetes-sigs/gateway-api/issues/3214 + absoluteTimeout: 10s diff --git a/test/e2e/testdata/multi-referencegrants-same-namespace-services.yaml b/test/e2e/testdata/multi-referencegrants-same-namespace-services.yaml new file mode 100644 index 00000000000..948503bea3d --- /dev/null +++ b/test/e2e/testdata/multi-referencegrants-same-namespace-services.yaml @@ -0,0 +1,148 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: multireferencegrants-ns +--- +apiVersion: v1 +kind: Service +metadata: + name: app-backend-v1 + namespace: multireferencegrants-ns +spec: + selector: + app: app-backend-v1 + ports: + - protocol: TCP + port: 8080 + targetPort: 3000 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: app-backend-v1 + namespace: multireferencegrants-ns + labels: + app: app-backend-v1 +spec: + replicas: 1 + selector: + matchLabels: + app: app-backend-v1 + template: + metadata: + labels: + app: app-backend-v1 + spec: + containers: + - name: app-backend-v1 + image: gcr.io/k8s-staging-gateway-api/echo-basic:v20231214-v1.0.0-140-gf544a46e + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: SERVICE_NAME + value: app-backend-v1 + resources: + requests: + cpu: 10m +--- +apiVersion: v1 +kind: Service +metadata: + name: app-backend-v2 + namespace: multireferencegrants-ns +spec: + selector: + app: app-backend-v2 + ports: + - protocol: TCP + port: 8080 + targetPort: 3000 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: app-backend-v2 + namespace: multireferencegrants-ns + labels: + app: app-backend-v2 +spec: + replicas: 1 + selector: + matchLabels: + app: app-backend-v2 + template: + metadata: + labels: + app: app-backend-v2 + spec: + containers: + - name: app-backend-v2 + image: gcr.io/k8s-staging-gateway-api/echo-basic:v20231214-v1.0.0-140-gf544a46e + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: SERVICE_NAME + value: app-backend-v2 + resources: + requests: + cpu: 10m +--- +apiVersion: v1 +kind: Service +metadata: + name: app-backend-v3 + namespace: multireferencegrants-ns +spec: + selector: + app: app-backend-v3 + ports: + - protocol: TCP + port: 8080 + targetPort: 3000 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: app-backend-v3 + namespace: multireferencegrants-ns + labels: + app: app-backend-v3 +spec: + replicas: 1 + selector: + matchLabels: + app: app-backend-v3 + template: + metadata: + labels: + app: app-backend-v3 + spec: + containers: + - name: app-backend-v3 + image: gcr.io/k8s-staging-gateway-api/echo-basic:v20231214-v1.0.0-140-gf544a46e + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: SERVICE_NAME + value: app-backend-v3 + resources: + requests: + cpu: 10m diff --git a/test/e2e/testdata/multi-referencegrants-same-namespace.yaml b/test/e2e/testdata/multi-referencegrants-same-namespace.yaml new file mode 100644 index 00000000000..f9940185e5c --- /dev/null +++ b/test/e2e/testdata/multi-referencegrants-same-namespace.yaml @@ -0,0 +1,92 @@ +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: multi-referencegrant-same-namespace + namespace: gateway-conformance-infra +spec: + hostnames: + - multireferencegrant.local + parentRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: same-namespace + namespace: gateway-conformance-infra + rules: + - backendRefs: + - group: "" + kind: Service + name: app-backend-v3 + namespace: multireferencegrants-ns + port: 8080 + weight: 1 + matches: + - path: + type: PathPrefix + value: /v3/echo + - backendRefs: + - group: "" + kind: Service + name: app-backend-v2 + namespace: multireferencegrants-ns + port: 8080 + weight: 1 + matches: + - path: + type: PathPrefix + value: /v2/echo + - backendRefs: + - group: "" + kind: Service + name: app-backend-v1 + namespace: multireferencegrants-ns + port: 8080 + weight: 1 + matches: + - path: + type: PathPrefix + value: /v1/echo +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: ReferenceGrant +metadata: + name: app-backend-v1-rg + namespace: multireferencegrants-ns +spec: + from: + - group: gateway.networking.k8s.io + kind: HTTPRoute + namespace: gateway-conformance-infra + to: + - group: "" + kind: Service + name: app-backend-v1 +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: ReferenceGrant +metadata: + name: app-backend-v2-rg + namespace: multireferencegrants-ns +spec: + from: + - group: gateway.networking.k8s.io + kind: HTTPRoute + namespace: gateway-conformance-infra + to: + - group: "" + kind: Service + name: app-backend-v2 +--- +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: ReferenceGrant +metadata: + name: app-backend-v3-rg + namespace: multireferencegrants-ns +spec: + from: + - group: gateway.networking.k8s.io + kind: HTTPRoute + namespace: gateway-conformance-infra + to: + - group: "" + kind: Service + name: app-backend-v3 diff --git a/test/e2e/testdata/wasm-http.yaml b/test/e2e/testdata/wasm-http.yaml index d251d5943e9..2bc1aae0ab3 100644 --- a/test/e2e/testdata/wasm-http.yaml +++ b/test/e2e/testdata/wasm-http.yaml @@ -51,5 +51,5 @@ spec: code: type: HTTP http: - url: https://raw.githubusercontent.com/envoyproxy/envoy/main/examples/wasm-cc/lib/envoy_filter_http_wasm_example.wasm + url: https://raw.githubusercontent.com/envoyproxy/examples/main/wasm-cc/lib/envoy_filter_http_wasm_example.wasm sha256: 79c9f85128bb0177b6511afa85d587224efded376ac0ef76df56595f1e6315c0 diff --git a/test/e2e/tests/ext_auth_http_backend.go b/test/e2e/tests/ext_auth_http_backend.go new file mode 100644 index 00000000000..7032bdc2ae0 --- /dev/null +++ b/test/e2e/tests/ext_auth_http_backend.go @@ -0,0 +1,155 @@ +// 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. + +//go:build e2e +// +build e2e + +package tests + +import ( + "testing" + + corev1 "k8s.io/api/core/v1" + "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/http" + "sigs.k8s.io/gateway-api/conformance/utils/kubernetes" + "sigs.k8s.io/gateway-api/conformance/utils/suite" + + "github.com/envoyproxy/gateway/internal/gatewayapi" +) + +func init() { + ConformanceTests = append(ConformanceTests, HTTPBackendExtAuthTest) +} + +// HTTPBackendExtAuthTest tests ExtAuth authentication for a http route with ExtAuth configured. +// Almost like HTTPExtAuthTest, but the security policy reference to the backend service. +var HTTPBackendExtAuthTest = suite.ConformanceTest{ + ShortName: "HTTPBackendExtAuth", + Description: "Test ExtAuth authentication with backend", + Manifests: []string{"testdata/ext-auth-http-backend.yaml", "testdata/ext-auth-http-backend-securitypolicy.yaml"}, + Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { + ns := "gateway-conformance-infra" + routeNN := types.NamespacedName{Name: "http-ext-auth-backend", Namespace: ns} + gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns} + gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN) + + ancestorRef := gwapiv1a2.ParentReference{ + Group: gatewayapi.GroupPtr(gwapiv1.GroupName), + Kind: gatewayapi.KindPtr(gatewayapi.KindGateway), + Namespace: gatewayapi.NamespacePtr(gwNN.Namespace), + Name: gwapiv1.ObjectName(gwNN.Name), + } + SecurityPolicyMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "ext-auth-backend", Namespace: ns}, suite.ControllerName, ancestorRef) + + podReady := corev1.PodCondition{Type: corev1.PodReady, Status: corev1.ConditionTrue} + + // Wait for the http ext auth service pod to be ready + WaitForPods(t, suite.Client, ns, map[string]string{"app": "http-ext-auth-backend"}, corev1.PodRunning, podReady) + + t.Run("http route with ext auth backend ref", func(t *testing.T) { + expectedResponse := http.ExpectedResponse{ + Request: http.Request{ + Host: "www.example.com", + Path: "/myapp", + Headers: map[string]string{ + "Authorization": "Bearer token2", + }, + }, + // Verify that the http headers returned by the ext auth service + // are added to the original request before sending it to the backend + ExpectedRequest: &http.ExpectedRequest{ + Request: http.Request{ + Host: "www.example.com", + Path: "/myapp", + Headers: map[string]string{ + "x-current-user": "user2", + }, + }, + }, + Response: http.Response{ + StatusCode: 200, + }, + Namespace: ns, + } + + http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse) + }) + + t.Run("without Authorization header", func(t *testing.T) { + expectedResponse := http.ExpectedResponse{ + Request: http.Request{ + Host: "www.example.com", + Path: "/myapp", + }, + Response: http.Response{ + StatusCode: 403, + }, + Namespace: ns, + } + + req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http") + cReq, cResp, err := suite.RoundTripper.CaptureRoundTrip(req) + if err != nil { + t.Errorf("failed to get expected response: %v", err) + } + + if err := http.CompareRequest(t, &req, cReq, cResp, expectedResponse); err != nil { + t.Errorf("failed to compare request and response: %v", err) + } + }) + + t.Run("invalid credential", func(t *testing.T) { + expectedResponse := http.ExpectedResponse{ + Request: http.Request{ + Host: "www.example.com", + Path: "/myapp", + Headers: map[string]string{ + "Authorization": "Bearer invalid-token", + }, + }, + Response: http.Response{ + StatusCode: 403, + }, + Namespace: ns, + } + + req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http") + cReq, cResp, err := suite.RoundTripper.CaptureRoundTrip(req) + if err != nil { + t.Errorf("failed to get expected response: %v", err) + } + + if err := http.CompareRequest(t, &req, cReq, cResp, expectedResponse); err != nil { + t.Errorf("failed to compare request and response: %v", err) + } + }) + + t.Run("http route without ext auth authentication", func(t *testing.T) { + expectedResponse := http.ExpectedResponse{ + Request: http.Request{ + Host: "www.example.com", + Path: "/public", + }, + Response: http.Response{ + StatusCode: 200, + }, + Namespace: ns, + } + + req := http.MakeRequest(t, &expectedResponse, gwAddr, "HTTP", "http") + cReq, cResp, err := suite.RoundTripper.CaptureRoundTrip(req) + if err != nil { + t.Errorf("failed to get expected response: %v", err) + } + + if err := http.CompareRequest(t, &req, cReq, cResp, expectedResponse); err != nil { + t.Errorf("failed to compare request and response: %v", err) + } + }) + }, +} diff --git a/test/e2e/tests/referencegrants.go b/test/e2e/tests/referencegrants.go new file mode 100644 index 00000000000..903e64598bc --- /dev/null +++ b/test/e2e/tests/referencegrants.go @@ -0,0 +1,79 @@ +// 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. + +//go:build e2e +// +build e2e + +package tests + +import ( + "testing" + + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/gateway-api/conformance/utils/http" + "sigs.k8s.io/gateway-api/conformance/utils/kubernetes" + "sigs.k8s.io/gateway-api/conformance/utils/suite" +) + +func init() { + ConformanceTests = append(ConformanceTests, MultiReferenceGrantsSameNamespaceTest) +} + +var MultiReferenceGrantsSameNamespaceTest = suite.ConformanceTest{ + ShortName: "MultiReferenceGrantsSameNamespace", + Description: "Test for multiple reference grants in the same namespace", + Manifests: []string{"testdata/multi-referencegrants-same-namespace-services.yaml", "testdata/multi-referencegrants-same-namespace.yaml"}, + Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { + resourceNS := "gateway-conformance-infra" + routeNN := types.NamespacedName{Name: "multi-referencegrant-same-namespace", Namespace: resourceNS} + gwNN := types.NamespacedName{Name: "same-namespace", Namespace: resourceNS} + gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN) + + targetHost := "multireferencegrant.local" + targetNS := "multireferencegrants-ns" + testcases := []http.ExpectedResponse{ + { + Request: http.Request{ + Host: targetHost, + Path: "/v1/echo", + }, + Response: http.Response{ + StatusCode: 200, + }, + Backend: "app-backend-v1", + Namespace: targetNS, + }, + { + Request: http.Request{ + Host: targetHost, + Path: "/v2/echo", + }, + Response: http.Response{ + StatusCode: 200, + }, + Backend: "app-backend-v2", + Namespace: targetNS, + }, + { + Request: http.Request{ + Host: targetHost, + Path: "/v3/echo", + }, + Response: http.Response{ + StatusCode: 200, + }, + Backend: "app-backend-v3", + Namespace: targetNS, + }, + } + + for i, tc := range testcases { + t.Run(tc.GetTestCaseName(i), func(t *testing.T) { + t.Parallel() + http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, tc) + }) + } + }, +} diff --git a/test/e2e/tests/session_persistence.go b/test/e2e/tests/session_persistence.go new file mode 100644 index 00000000000..7c1d90880ab --- /dev/null +++ b/test/e2e/tests/session_persistence.go @@ -0,0 +1,189 @@ +// 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. + +//go:build e2e +// +build e2e + +package tests + +import ( + "fmt" + "net/http" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "k8s.io/apimachinery/pkg/types" + httputils "sigs.k8s.io/gateway-api/conformance/utils/http" + "sigs.k8s.io/gateway-api/conformance/utils/kubernetes" + "sigs.k8s.io/gateway-api/conformance/utils/suite" +) + +func init() { + ConformanceTests = append(ConformanceTests, HeaderBasedSessionPersistenceTest) + ConformanceTests = append(ConformanceTests, CookieBasedSessionPersistenceTest) +} + +var HeaderBasedSessionPersistenceTest = suite.ConformanceTest{ + ShortName: "HeaderBasedSessionPersistence", + Description: "Test that the session persistence filter is correctly configured with header based session persistence", + Manifests: []string{"testdata/header-based-session-persistence.yaml"}, + Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { + t.Run("traffic is routed based on header based session persistence", func(t *testing.T) { + ns := "gateway-conformance-infra" + routeNN := types.NamespacedName{Name: "header-based-session-persistence", Namespace: ns} + gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns} + gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN) + req := httputils.MakeRequest(t, &httputils.ExpectedResponse{ + Request: httputils.Request{ + Path: "/v2", + }, + }, gwAddr, "HTTP", "http") + + pod := "" + // We make 10 requests to the gateway and expect them to be routed to the same pod. + for i := 0; i < 10; i++ { + captReq, res, err := suite.RoundTripper.CaptureRoundTrip(req) + if err != nil { + t.Fatalf("failed to make request: %v", err) + } + + if i == 0 { + // First request, capture the pod name and header. + sessionHeader, ok := res.Headers["Session-A"] + if !ok { + t.Fatalf("expected header Session-A to be set: %v", res.Headers) + } + + if captReq.Pod == "" { + t.Fatalf("expected pod to be set") + } + pod = captReq.Pod + req.Headers["Session-A"] = sessionHeader + continue + } + + t.Logf("request is received from pod %s", captReq.Pod) + + if captReq.Pod != pod { + t.Fatalf("expected pod to be the same as previous requests") + } + } + }) + t.Run("session persistence is configured per route", func(t *testing.T) { + ns := "gateway-conformance-infra" + routeNN := types.NamespacedName{Name: "header-based-session-persistence", Namespace: ns} + gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns} + gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN) + req := httputils.MakeRequest(t, &httputils.ExpectedResponse{ + Request: httputils.Request{ + // /v1 path does not have the session persistence. + Path: "/v1", + }, + }, gwAddr, "HTTP", "http") + + _, res, err := suite.RoundTripper.CaptureRoundTrip(req) + if err != nil { + t.Fatalf("failed to make request: %v", err) + } + + if h, ok := res.Headers["Session-A"]; ok { + t.Fatalf("expected header Session-A to not be set: %v", h) + } + }) + }, +} + +var CookieBasedSessionPersistenceTest = suite.ConformanceTest{ + ShortName: "CookieBasedSessionPersistence", + Description: "Test that the session persistence filter is correctly configured with cookie based session persistence", + Manifests: []string{"testdata/cookie-based-session-persistence.yaml"}, + Test: func(t *testing.T, suite *suite.ConformanceTestSuite) { + t.Run("traffic is routed based on cookie based session persistence", func(t *testing.T) { + ns := "gateway-conformance-infra" + routeNN := types.NamespacedName{Name: "cookie-based-session-persistence", Namespace: ns} + gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns} + gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN) + req := httputils.MakeRequest(t, &httputils.ExpectedResponse{ + Request: httputils.Request{ + Path: "/v2", + }, + }, gwAddr, "HTTP", "http") + + pod := "" + // We make 10 requests to the gateway and expect them to be routed to the same pod. + for i := 0; i < 10; i++ { + captReq, res, err := suite.RoundTripper.CaptureRoundTrip(req) + if err != nil { + t.Fatalf("failed to make request: %v", err) + } + + if i == 0 { + // First request, capture the pod name and cookie. + if captReq.Pod == "" { + t.Fatalf("expected pod to be set") + } + + cookie, err := parseCookie(res.Headers, "Session-A") + if err != nil { + t.Fatalf("failed to parse cookie: %v", err) + } + + // Check the cookie is set correctly. + if diff := cmp.Diff(cookie, &http.Cookie{ + Name: "Session-A", + MaxAge: 10, + Path: "/v2", + HttpOnly: true, + }, cmpopts.IgnoreFields(http.Cookie{}, "Value", "Raw"), // Ignore the value as it is random. + ); diff != "" { + t.Fatalf("unexpected cookie: %v", diff) + } + + pod = captReq.Pod + req.Headers["Cookie"] = []string{fmt.Sprintf("Session-A=%s", cookie.Value)} + continue + } + + t.Logf("request is received from pod %s", captReq.Pod) + + if captReq.Pod != pod { + t.Fatalf("expected pod to be the same as previous requests") + } + } + }) + t.Run("session persistence is configured per route", func(t *testing.T) { + ns := "gateway-conformance-infra" + routeNN := types.NamespacedName{Name: "cookie-based-session-persistence", Namespace: ns} + gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns} + gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN) + req := httputils.MakeRequest(t, &httputils.ExpectedResponse{ + Request: httputils.Request{ + // /v1 path does not have the session persistence. + Path: "/v1", + }, + }, gwAddr, "HTTP", "http") + + _, res, err := suite.RoundTripper.CaptureRoundTrip(req) + if err != nil { + t.Fatalf("failed to make request: %v", err) + } + + if _, ok := res.Headers["Set-Cookie"]; ok { + t.Fatal("expected the envoy not to response set-cookie back") + } + }) + }, +} + +func parseCookie(headers map[string][]string, cookieName string) (*http.Cookie, error) { + parser := &http.Response{Header: headers} + for _, c := range parser.Cookies() { + if c.Name == cookieName { + return c, nil + } + } + return nil, fmt.Errorf("cookie %s not found: headers: %v", cookieName, headers) +}