From fff4d057d0327d327c59539989c832f65892f17e Mon Sep 17 00:00:00 2001 From: Rajat Vig Date: Sun, 8 Feb 2026 23:51:40 +0000 Subject: [PATCH 1/8] feat(api): add HTTP/2 connection keepalive to ClientTrafficPolicy and BackendTrafficPolicy Signed-off-by: Rajat Vig --- api/v1alpha1/shared_types.go | 19 ++ api/v1alpha1/zz_generated.deepcopy.go | 35 +++ ....envoyproxy.io_backendtrafficpolicies.yaml | 20 ++ ...y.envoyproxy.io_clienttrafficpolicies.yaml | 20 ++ ....envoyproxy.io_envoyextensionpolicies.yaml | 22 ++ .../gateway.envoyproxy.io_envoyproxies.yaml | 101 ++++++++ ...ateway.envoyproxy.io_securitypolicies.yaml | 89 +++++++ ....envoyproxy.io_backendtrafficpolicies.yaml | 20 ++ ...y.envoyproxy.io_clienttrafficpolicies.yaml | 20 ++ ....envoyproxy.io_envoyextensionpolicies.yaml | 22 ++ .../gateway.envoyproxy.io_envoyproxies.yaml | 101 ++++++++ ...ateway.envoyproxy.io_securitypolicies.yaml | 89 +++++++ internal/gatewayapi/http.go | 30 +++ ...ckendtrafficpolicy-http2-keepalive.in.yaml | 51 ++++ ...kendtrafficpolicy-http2-keepalive.out.yaml | 222 ++++++++++++++++++ ...lienttrafficpolicy-http2-keepalive.in.yaml | 32 +++ ...ienttrafficpolicy-http2-keepalive.out.yaml | 144 ++++++++++++ internal/ir/xds.go | 13 + internal/ir/zz_generated.deepcopy.go | 35 +++ internal/xds/translator/listener.go | 15 ++ .../testdata/in/xds-ir/http2-keepalive.yaml | 27 +++ .../out/xds-ir/http2-keepalive.clusters.yaml | 24 ++ .../out/xds-ir/http2-keepalive.endpoints.yaml | 12 + .../out/xds-ir/http2-keepalive.listeners.yaml | 39 +++ .../out/xds-ir/http2-keepalive.routes.yaml | 14 ++ release-notes/current.yaml | 1 + site/content/en/latest/api/extension_types.md | 17 ++ 27 files changed, 1234 insertions(+) create mode 100644 internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.in.yaml create mode 100644 internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml create mode 100644 internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.in.yaml create mode 100644 internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml create mode 100644 internal/xds/translator/testdata/in/xds-ir/http2-keepalive.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/http2-keepalive.clusters.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/http2-keepalive.endpoints.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/http2-keepalive.listeners.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/http2-keepalive.routes.yaml diff --git a/api/v1alpha1/shared_types.go b/api/v1alpha1/shared_types.go index 343f1210c8..3be62f7adc 100644 --- a/api/v1alpha1/shared_types.go +++ b/api/v1alpha1/shared_types.go @@ -718,6 +718,25 @@ type HTTP2Settings struct { // Default: TerminateConnection // +optional OnInvalidMessage *InvalidMessageAction `json:"onInvalidMessage,omitempty"` + + // ConnectionKeepalive configures HTTP/2 connection keepalive using PING frames. + // +optional + ConnectionKeepalive *HTTP2ConnectionKeepalive `json:"connectionKeepalive,omitempty"` +} + +// HTTP2ConnectionKeepalive configures HTTP/2 PING-based keepalive settings. +type HTTP2ConnectionKeepalive struct { + // Interval specifies how often to send HTTP/2 PING frames to keep the connection alive. + // +optional + Interval *gwapiv1.Duration `json:"interval,omitempty"` + + // Timeout specifies how long to wait for a PING response before considering the connection dead. + // +optional + Timeout *gwapiv1.Duration `json:"timeout,omitempty"` + + // ConnectionIdleInterval specifies how long a connection must be idle before a PING is sent. + // +optional + ConnectionIdleInterval *gwapiv1.Duration `json:"connectionIdleInterval,omitempty"` } // ResponseOverride defines the configuration to override specific responses with a custom one. diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index fb1eedf645..12889345ec 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -3491,6 +3491,36 @@ func (in *HTTP1Settings) DeepCopy() *HTTP1Settings { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HTTP2ConnectionKeepalive) DeepCopyInto(out *HTTP2ConnectionKeepalive) { + *out = *in + if in.Interval != nil { + in, out := &in.Interval, &out.Interval + *out = new(v1.Duration) + **out = **in + } + if in.Timeout != nil { + in, out := &in.Timeout, &out.Timeout + *out = new(v1.Duration) + **out = **in + } + if in.ConnectionIdleInterval != nil { + in, out := &in.ConnectionIdleInterval, &out.ConnectionIdleInterval + *out = new(v1.Duration) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTP2ConnectionKeepalive. +func (in *HTTP2ConnectionKeepalive) DeepCopy() *HTTP2ConnectionKeepalive { + if in == nil { + return nil + } + out := new(HTTP2ConnectionKeepalive) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTP2Settings) DeepCopyInto(out *HTTP2Settings) { *out = *in @@ -3514,6 +3544,11 @@ func (in *HTTP2Settings) DeepCopyInto(out *HTTP2Settings) { *out = new(InvalidMessageAction) **out = **in } + if in.ConnectionKeepalive != nil { + in, out := &in.ConnectionKeepalive, &out.ConnectionKeepalive + *out = new(HTTP2ConnectionKeepalive) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTP2Settings. diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml index 93d46242e4..855372c155 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -649,6 +649,26 @@ spec: http2: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 connection + keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies how long a connection + must be idle before a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send HTTP/2 PING + frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait for a PING + response before considering the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml index f86e2c2eca..afa4e51fb9 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml @@ -799,6 +799,26 @@ spec: http2: description: HTTP2 provides HTTP/2 configuration on the listener. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 connection + keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies how long a connection + must be idle before a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send HTTP/2 PING + frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait for a PING + response before considering the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml index 996d26a91c..caefc9d913 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml @@ -710,6 +710,28 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 connection + keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies how + long a connection must be idle before a PING is + sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send + HTTP/2 PING frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait + for a PING response before considering the connection + dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml index f905780b1c..2bb89bb1bf 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml @@ -11783,6 +11783,33 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures + HTTP/2 connection keepalive using + PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval + specifies how long a connection + must be idle before a PING is + sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies + how often to send HTTP/2 PING + frames to keep the connection + alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies + how long to wait for a PING + response before considering + the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -13052,6 +13079,33 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures + HTTP/2 connection keepalive using + PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval + specifies how long a connection + must be idle before a PING is + sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies + how often to send HTTP/2 PING + frames to keep the connection + alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies + how long to wait for a PING + response before considering + the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -14477,6 +14531,30 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures + HTTP/2 connection keepalive using PING + frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval + specifies how long a connection must + be idle before a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how + often to send HTTP/2 PING frames to + keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long + to wait for a PING response before + considering the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -15820,6 +15898,29 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 + connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before + a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often + to send HTTP/2 PING frames to keep the connection + alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to + wait for a PING response before considering + the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml index 3bfde648f7..de8b24b7af 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -1330,6 +1330,28 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 + connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before a + PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send + HTTP/2 PING frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait + for a PING response before considering the connection + dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -2487,6 +2509,28 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 + connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before a + PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send + HTTP/2 PING frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait + for a PING response before considering the connection + dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -3855,6 +3899,29 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures + HTTP/2 connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before + a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often + to send HTTP/2 PING frames to keep the + connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long + to wait for a PING response before considering + the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -5281,6 +5348,28 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 + connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before a + PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send + HTTP/2 PING frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait + for a PING response before considering the connection + dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ 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 795271b526..77638552c1 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -648,6 +648,26 @@ spec: http2: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 connection + keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies how long a connection + must be idle before a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send HTTP/2 PING + frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait for a PING + response before considering the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ 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 0a83915dbe..4d5bad3bb3 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml @@ -798,6 +798,26 @@ spec: http2: description: HTTP2 provides HTTP/2 configuration on the listener. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 connection + keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies how long a connection + must be idle before a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send HTTP/2 PING + frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait for a PING + response before considering the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ 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 97aeacf69e..e99a1006ca 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml @@ -709,6 +709,28 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 connection + keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies how + long a connection must be idle before a PING is + sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send + HTTP/2 PING frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait + for a PING response before considering the connection + dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ 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 900b4e5fa0..1e39f98536 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml @@ -11782,6 +11782,33 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures + HTTP/2 connection keepalive using + PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval + specifies how long a connection + must be idle before a PING is + sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies + how often to send HTTP/2 PING + frames to keep the connection + alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies + how long to wait for a PING + response before considering + the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -13051,6 +13078,33 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures + HTTP/2 connection keepalive using + PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval + specifies how long a connection + must be idle before a PING is + sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies + how often to send HTTP/2 PING + frames to keep the connection + alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies + how long to wait for a PING + response before considering + the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -14476,6 +14530,30 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures + HTTP/2 connection keepalive using PING + frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval + specifies how long a connection must + be idle before a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how + often to send HTTP/2 PING frames to + keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long + to wait for a PING response before + considering the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -15819,6 +15897,29 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 + connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before + a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often + to send HTTP/2 PING frames to keep the connection + alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to + wait for a PING response before considering + the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ 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 8303f1b640..6c6c0c8e16 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -1329,6 +1329,28 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 + connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before a + PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send + HTTP/2 PING frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait + for a PING response before considering the connection + dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -2486,6 +2508,28 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 + connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before a + PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send + HTTP/2 PING frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait + for a PING response before considering the connection + dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -3854,6 +3898,29 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures + HTTP/2 connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before + a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often + to send HTTP/2 PING frames to keep the + connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long + to wait for a PING response before considering + the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -5280,6 +5347,28 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 + connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before a + PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send + HTTP/2 PING frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait + for a PING response before considering the connection + dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ diff --git a/internal/gatewayapi/http.go b/internal/gatewayapi/http.go index e54b3f761d..9eca1d41e8 100644 --- a/internal/gatewayapi/http.go +++ b/internal/gatewayapi/http.go @@ -8,6 +8,7 @@ package gatewayapi import ( "errors" "fmt" + "time" "k8s.io/utils/ptr" @@ -72,5 +73,34 @@ func buildIRHTTP2Settings(http2Settings *egv1a1.HTTP2Settings) (*ir.HTTP2Setting } } + if http2Settings.ConnectionKeepalive != nil { + keepalive := &ir.HTTP2ConnectionKeepalive{} + if http2Settings.ConnectionKeepalive.Interval != nil { + d, err := time.ParseDuration(string(*http2Settings.ConnectionKeepalive.Interval)) + if err != nil { + errs = errors.Join(errs, fmt.Errorf("invalid ConnectionKeepalive.Interval: %w", err)) + } else { + keepalive.Interval = ptr.To(uint32(d.Seconds())) + } + } + if http2Settings.ConnectionKeepalive.Timeout != nil { + d, err := time.ParseDuration(string(*http2Settings.ConnectionKeepalive.Timeout)) + if err != nil { + errs = errors.Join(errs, fmt.Errorf("invalid ConnectionKeepalive.Timeout: %w", err)) + } else { + keepalive.Timeout = ptr.To(uint32(d.Seconds())) + } + } + if http2Settings.ConnectionKeepalive.ConnectionIdleInterval != nil { + d, err := time.ParseDuration(string(*http2Settings.ConnectionKeepalive.ConnectionIdleInterval)) + if err != nil { + errs = errors.Join(errs, fmt.Errorf("invalid ConnectionKeepalive.ConnectionIdleInterval: %w", err)) + } else { + keepalive.ConnectionIdleInterval = ptr.To(uint32(d.Seconds())) + } + } + http2.ConnectionKeepalive = keepalive + } + return http2, errs } diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.in.yaml new file mode 100644 index 0000000000..c67d42416e --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.in.yaml @@ -0,0 +1,51 @@ +gateways: + - apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: All +httpRoutes: + - apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - namespace: envoy-gateway + name: gateway-1 + sectionName: http + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 +backendTrafficPolicies: + - apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + namespace: default + name: policy-for-route + spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + http2: + connectionKeepalive: + interval: 60s + timeout: 10s + connectionIdleInterval: 30s diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml new file mode 100644 index 0000000000..56689643b6 --- /dev/null +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml @@ -0,0 +1,222 @@ +backendTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: BackendTrafficPolicy + metadata: + name: policy-for-route + namespace: default + spec: + http2: + connectionKeepalive: + connectionIdleInterval: 30s + interval: 60s + timeout: 10s + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httproute-1 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http + conditions: + - lastTransitionTime: null + message: Policy has been accepted. + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: spec.targetRef is deprecated, use spec.targetRefs instead + reason: DeprecatedField + status: "True" + type: Warning + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: All + name: http + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 1 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +httpRoutes: +- apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httproute-1 + namespace: default + spec: + hostnames: + - gateway.envoyproxy.io + parentRefs: + - name: gateway-1 + namespace: envoy-gateway + sectionName: http + rules: + - backendRefs: + - name: service-1 + port: 8080 + matches: + - path: + value: / + status: + parents: + - conditions: + - lastTransitionTime: null + message: Route is accepted + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Resolved all the Object references for the Route + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parentRef: + name: gateway-1 + namespace: envoy-gateway + sectionName: http +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-1/http + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + ownerReference: + kind: GatewayClass + name: envoy-gateway-class + name: envoy-gateway/gateway-1 + namespace: envoy-gateway-system +xdsIR: + envoy-gateway/gateway-1: + accessLog: + json: + - path: /dev/stdout + globalResources: + proxyServiceCluster: + metadata: + kind: Service + name: envoy-envoy-gateway-gateway-1-196ae069 + namespace: envoy-gateway-system + sectionName: "8080" + name: envoy-gateway/gateway-1 + settings: + - addressType: IP + endpoints: + - host: 7.6.5.4 + port: 8080 + zone: zone1 + metadata: + kind: Service + name: envoy-envoy-gateway-gateway-1-196ae069 + namespace: envoy-gateway-system + sectionName: "8080" + name: envoy-gateway/gateway-1 + protocol: TCP + http: + - address: 0.0.0.0 + externalPort: 80 + hostnames: + - '*' + isHTTP2: false + metadata: + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http + name: envoy-gateway/gateway-1/http + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + routes: + - destination: + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + name: httproute/default/httproute-1/rule/0 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8080 + metadata: + kind: Service + name: service-1 + namespace: default + sectionName: "8080" + name: httproute/default/httproute-1/rule/0/backend/0 + protocol: HTTP + weight: 1 + hostname: gateway.envoyproxy.io + isHTTP2: false + metadata: + kind: HTTPRoute + name: httproute-1 + namespace: default + policies: + - kind: BackendTrafficPolicy + name: policy-for-route + namespace: default + name: httproute/default/httproute-1/rule/0/match/0/gateway_envoyproxy_io + pathMatch: + distinct: false + name: "" + prefix: / + traffic: + http2: + connectionKeepalive: + connectionIdleInterval: 30 + interval: 60 + timeout: 10 + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.in.yaml new file mode 100644 index 0000000000..81ae627b56 --- /dev/null +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.in.yaml @@ -0,0 +1,32 @@ +clientTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + namespace: envoy-gateway + name: target-gateway-1-section-http-1 + spec: + http2: + connectionKeepalive: + interval: 60s + timeout: 10s + connectionIdleInterval: 30s + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: http-1 +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http-1 + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: Same diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml new file mode 100644 index 0000000000..3767fd456e --- /dev/null +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml @@ -0,0 +1,144 @@ +clientTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + name: target-gateway-1-section-http-1 + namespace: envoy-gateway + spec: + http2: + connectionKeepalive: + connectionIdleInterval: 30s + interval: 60s + timeout: 10s + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: http-1 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http-1 + 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: + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: Same + name: http-1 + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 0 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-1 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-1/http-1 + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + ownerReference: + kind: GatewayClass + name: envoy-gateway-class + name: envoy-gateway/gateway-1 + namespace: envoy-gateway-system +xdsIR: + envoy-gateway/gateway-1: + accessLog: + json: + - path: /dev/stdout + globalResources: + proxyServiceCluster: + metadata: + kind: Service + name: envoy-envoy-gateway-gateway-1-196ae069 + namespace: envoy-gateway-system + sectionName: "8080" + name: envoy-gateway/gateway-1 + settings: + - addressType: IP + endpoints: + - host: 7.6.5.4 + port: 8080 + zone: zone1 + metadata: + kind: Service + name: envoy-envoy-gateway-gateway-1-196ae069 + namespace: envoy-gateway-system + sectionName: "8080" + name: envoy-gateway/gateway-1 + protocol: TCP + http: + - address: 0.0.0.0 + externalPort: 80 + hostnames: + - '*' + http2: + connectionKeepalive: + connectionIdleInterval: 30 + interval: 60 + timeout: 10 + isHTTP2: false + metadata: + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http-1 + name: envoy-gateway/gateway-1/http-1 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 7b8f10eb1f..587bb2900d 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -616,6 +616,19 @@ type HTTP2Settings struct { MaxConcurrentStreams *uint32 `json:"maxConcurrentStreams,omitempty" yaml:"maxConcurrentStreams,omitempty"` // ResetStreamOnError determines if a stream or connection is reset on messaging error. ResetStreamOnError *bool `json:"resetStreamOnError,omitempty" yaml:"resetStreamOnError,omitempty"` + // ConnectionKeepalive configures HTTP/2 PING-based keepalive settings. + ConnectionKeepalive *HTTP2ConnectionKeepalive `json:"connectionKeepalive,omitempty" yaml:"connectionKeepalive,omitempty"` +} + +// HTTP2ConnectionKeepalive configures HTTP/2 PING-based keepalive settings. +// +k8s:deepcopy-gen=true +type HTTP2ConnectionKeepalive struct { + // Interval specifies how often to send HTTP/2 PING frames (in seconds). + Interval *uint32 `json:"interval,omitempty" yaml:"interval,omitempty"` + // Timeout specifies how long to wait for a PING response (in seconds). + Timeout *uint32 `json:"timeout,omitempty" yaml:"timeout,omitempty"` + // ConnectionIdleInterval specifies idle time before sending a PING (in seconds). + ConnectionIdleInterval *uint32 `json:"connectionIdleInterval,omitempty" yaml:"connectionIdleInterval,omitempty"` } // ResponseOverride defines the configuration to override specific responses with a custom one. diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index dc2b458f0c..ca2bfd0eda 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -1702,6 +1702,36 @@ func (in *HTTP1Settings) DeepCopy() *HTTP1Settings { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HTTP2ConnectionKeepalive) DeepCopyInto(out *HTTP2ConnectionKeepalive) { + *out = *in + if in.Interval != nil { + in, out := &in.Interval, &out.Interval + *out = new(uint32) + **out = **in + } + if in.Timeout != nil { + in, out := &in.Timeout, &out.Timeout + *out = new(uint32) + **out = **in + } + if in.ConnectionIdleInterval != nil { + in, out := &in.ConnectionIdleInterval, &out.ConnectionIdleInterval + *out = new(uint32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTP2ConnectionKeepalive. +func (in *HTTP2ConnectionKeepalive) DeepCopy() *HTTP2ConnectionKeepalive { + if in == nil { + return nil + } + out := new(HTTP2ConnectionKeepalive) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTP2Settings) DeepCopyInto(out *HTTP2Settings) { *out = *in @@ -1725,6 +1755,11 @@ func (in *HTTP2Settings) DeepCopyInto(out *HTTP2Settings) { *out = new(bool) **out = **in } + if in.ConnectionKeepalive != nil { + in, out := &in.ConnectionKeepalive, &out.ConnectionKeepalive + *out = new(HTTP2ConnectionKeepalive) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTP2Settings. diff --git a/internal/xds/translator/listener.go b/internal/xds/translator/listener.go index 8e4be35e29..fa3dea7f66 100644 --- a/internal/xds/translator/listener.go +++ b/internal/xds/translator/listener.go @@ -11,6 +11,7 @@ import ( "net" "strconv" "strings" + "time" xdscore "github.com/cncf/xds/go/xds/core/v3" matcher "github.com/cncf/xds/go/xds/type/matcher/v3" @@ -110,6 +111,20 @@ func http2ProtocolOptions(opts *ir.HTTP2Settings) *corev3.Http2ProtocolOptions { } } + if opts.ConnectionKeepalive != nil { + keepalive := &corev3.KeepaliveSettings{} + if opts.ConnectionKeepalive.Interval != nil { + keepalive.Interval = durationpb.New(time.Duration(*opts.ConnectionKeepalive.Interval) * time.Second) + } + if opts.ConnectionKeepalive.Timeout != nil { + keepalive.Timeout = durationpb.New(time.Duration(*opts.ConnectionKeepalive.Timeout) * time.Second) + } + if opts.ConnectionKeepalive.ConnectionIdleInterval != nil { + keepalive.ConnectionIdleInterval = durationpb.New(time.Duration(*opts.ConnectionKeepalive.ConnectionIdleInterval) * time.Second) + } + out.ConnectionKeepalive = keepalive + } + return out } diff --git a/internal/xds/translator/testdata/in/xds-ir/http2-keepalive.yaml b/internal/xds/translator/testdata/in/xds-ir/http2-keepalive.yaml new file mode 100644 index 0000000000..b8a1d99182 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/http2-keepalive.yaml @@ -0,0 +1,27 @@ +http: +- name: "first-listener" + address: "::" + port: 10080 + hostnames: + - "foo.com" + path: + mergeSlashes: true + escapedSlashesAction: UnescapeAndRedirect + http2: + initialConnectionWindowSize: 65536 + initialStreamWindowSize: 33554432 + maxConcurrentStreams: 200 + connectionKeepalive: + interval: 60 + timeout: 10 + connectionIdleInterval: 30 + routes: + - name: "first-route" + hostname: "*" + destination: + name: "first-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + name: "first-route-dest/backend/0" diff --git a/internal/xds/translator/testdata/out/xds-ir/http2-keepalive.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http2-keepalive.clusters.yaml new file mode 100644 index 0000000000..054f90bb71 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http2-keepalive.clusters.yaml @@ -0,0 +1,24 @@ +- circuitBreakers: + thresholds: + - maxRetries: 1024 + commonLbConfig: {} + connectTimeout: 10s + dnsLookupFamily: V4_PREFERRED + edsClusterConfig: + edsConfig: + ads: {} + resourceApiVersion: V3 + serviceName: first-route-dest + ignoreHealthOnHostRemoval: true + lbPolicy: LEAST_REQUEST + loadBalancingPolicy: + policies: + - typedExtensionConfig: + name: envoy.load_balancing_policies.least_request + typedConfig: + '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest + localityLbConfig: + localityWeightedLbConfig: {} + name: first-route-dest + perConnectionBufferLimitBytes: 32768 + type: EDS diff --git a/internal/xds/translator/testdata/out/xds-ir/http2-keepalive.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http2-keepalive.endpoints.yaml new file mode 100644 index 0000000000..3b3f2d0907 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http2-keepalive.endpoints.yaml @@ -0,0 +1,12 @@ +- clusterName: first-route-dest + endpoints: + - lbEndpoints: + - endpoint: + address: + socketAddress: + address: 1.2.3.4 + portValue: 50000 + loadBalancingWeight: 1 + loadBalancingWeight: 1 + locality: + region: first-route-dest/backend/0 diff --git a/internal/xds/translator/testdata/out/xds-ir/http2-keepalive.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http2-keepalive.listeners.yaml new file mode 100644 index 0000000000..1970b887b1 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http2-keepalive.listeners.yaml @@ -0,0 +1,39 @@ +- address: + socketAddress: + address: '::' + 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: + connectionKeepalive: + connectionIdleInterval: 30s + interval: 60s + timeout: 10s + initialConnectionWindowSize: 33554432 + initialStreamWindowSize: 65536 + maxConcurrentStreams: 200 + httpFilters: + - name: envoy.filters.http.router + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + suppressEnvoyHeaders: true + mergeSlashes: true + normalizePath: true + pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT + rds: + configSource: + ads: {} + resourceApiVersion: V3 + routeConfigName: first-listener + serverHeaderTransformation: PASS_THROUGH + statPrefix: http-10080 + useRemoteAddress: true + name: first-listener + maxConnectionsToAcceptPerSocketEvent: 1 + name: first-listener + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/http2-keepalive.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http2-keepalive.routes.yaml new file mode 100644 index 0000000000..0b5b4bee7b --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/http2-keepalive.routes.yaml @@ -0,0 +1,14 @@ +- ignorePortInHostMatching: true + name: first-listener + virtualHosts: + - domains: + - '*' + name: first-listener/* + routes: + - match: + prefix: / + name: first-route + route: + cluster: first-route-dest + upgradeConfigs: + - upgradeType: websocket diff --git a/release-notes/current.yaml b/release-notes/current.yaml index 1faf4c4c4c..407039b0f9 100644 --- a/release-notes/current.yaml +++ b/release-notes/current.yaml @@ -9,6 +9,7 @@ security updates: | # New features or capabilities added in this release. new features: | Added support for configuring optional health check configuration. + Added HTTP/2 connection keepalive support to ClientTrafficPolicy and BackendTrafficPolicy. bug fixes: | Rejected ClientTrafficPolicy if invalid TLS cipher suites are configured. diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index b4e5822d70..4cccbddbfa 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -2386,6 +2386,22 @@ _Appears in:_ | `disableSafeMaxConnectionDuration` | _boolean_ | false | | DisableSafeMaxConnectionDuration controls the close behavior for HTTP/1 connections.
By default, connection closure is delayed until the next request arrives after maxConnectionDuration is exceeded.
It then adds a Connection: close header and gracefully closes the connection after the response completes.
When set to true (disabled), Envoy uses its default drain behavior, closing the connection shortly after maxConnectionDuration elapses.
Has no effect unless maxConnectionDuration is set. | +#### HTTP2ConnectionKeepalive + + + +HTTP2ConnectionKeepalive configures HTTP/2 PING-based keepalive settings. + +_Appears in:_ +- [HTTP2Settings](#http2settings) + +| Field | Type | Required | Default | Description | +| --- | --- | --- | --- | --- | +| `interval` | _[Duration](https://gateway-api.sigs.k8s.io/reference/1.4/spec/#duration)_ | false | | Interval specifies how often to send HTTP/2 PING frames to keep the connection alive. | +| `timeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/1.4/spec/#duration)_ | false | | Timeout specifies how long to wait for a PING response before considering the connection dead. | +| `connectionIdleInterval` | _[Duration](https://gateway-api.sigs.k8s.io/reference/1.4/spec/#duration)_ | false | | ConnectionIdleInterval specifies how long a connection must be idle before a PING is sent. | + + #### HTTP2Settings @@ -2403,6 +2419,7 @@ _Appears in:_ | `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 | +| `connectionKeepalive` | _[HTTP2ConnectionKeepalive](#http2connectionkeepalive)_ | false | | ConnectionKeepalive configures HTTP/2 connection keepalive using PING frames. | #### HTTP3Settings From b927fd8c9c09205d9a183dd342e93fa823f34f73 Mon Sep 17 00:00:00 2001 From: Rajat Vig Date: Mon, 9 Feb 2026 00:32:08 +0000 Subject: [PATCH 2/8] add intervalJitter Signed-off-by: Rajat Vig --- api/v1alpha1/shared_types.go | 7 + api/v1alpha1/zz_generated.deepcopy.go | 5 + ....envoyproxy.io_backendtrafficpolicies.yaml | 8 + ...y.envoyproxy.io_clienttrafficpolicies.yaml | 8 + ....envoyproxy.io_envoyextensionpolicies.yaml | 8 + .../gateway.envoyproxy.io_envoyproxies.yaml | 32 +++ ...ateway.envoyproxy.io_securitypolicies.yaml | 32 +++ ....envoyproxy.io_backendtrafficpolicies.yaml | 8 + ...y.envoyproxy.io_clienttrafficpolicies.yaml | 8 + ....envoyproxy.io_envoyextensionpolicies.yaml | 8 + .../gateway.envoyproxy.io_envoyproxies.yaml | 32 +++ ...ateway.envoyproxy.io_securitypolicies.yaml | 32 +++ internal/gatewayapi/http.go | 3 + ...ckendtrafficpolicy-http2-keepalive.in.yaml | 1 + ...kendtrafficpolicy-http2-keepalive.out.yaml | 2 + ...lienttrafficpolicy-http2-keepalive.in.yaml | 1 + ...ienttrafficpolicy-http2-keepalive.out.yaml | 2 + internal/ir/xds.go | 2 + internal/ir/zz_generated.deepcopy.go | 5 + internal/xds/translator/listener.go | 3 + .../testdata/in/xds-ir/http2-keepalive.yaml | 1 + .../out/xds-ir/http2-keepalive.listeners.yaml | 2 + site/content/en/latest/api/extension_types.md | 1 + test/helm/gateway-crds-helm/all.out.yaml | 252 ++++++++++++++++++ .../envoy-gateway-crds.out.yaml | 252 ++++++++++++++++++ 25 files changed, 715 insertions(+) diff --git a/api/v1alpha1/shared_types.go b/api/v1alpha1/shared_types.go index 3be62f7adc..fe1e9df220 100644 --- a/api/v1alpha1/shared_types.go +++ b/api/v1alpha1/shared_types.go @@ -734,6 +734,13 @@ type HTTP2ConnectionKeepalive struct { // +optional Timeout *gwapiv1.Duration `json:"timeout,omitempty"` + // IntervalJitter specifies a random jitter percentage added to each interval. + // Defaults to 15% if not specified. + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=100 + // +optional + IntervalJitter *uint32 `json:"intervalJitter,omitempty"` + // ConnectionIdleInterval specifies how long a connection must be idle before a PING is sent. // +optional ConnectionIdleInterval *gwapiv1.Duration `json:"connectionIdleInterval,omitempty"` diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 12889345ec..5dd47e15ea 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -3504,6 +3504,11 @@ func (in *HTTP2ConnectionKeepalive) DeepCopyInto(out *HTTP2ConnectionKeepalive) *out = new(v1.Duration) **out = **in } + if in.IntervalJitter != nil { + in, out := &in.IntervalJitter, &out.IntervalJitter + *out = new(uint32) + **out = **in + } if in.ConnectionIdleInterval != nil { in, out := &in.ConnectionIdleInterval, &out.ConnectionIdleInterval *out = new(v1.Duration) diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml index 855372c155..23266b095f 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -663,6 +663,14 @@ spec: frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection dead. diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml index afa4e51fb9..79a5ab7adc 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml @@ -813,6 +813,14 @@ spec: frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection dead. diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml index caefc9d913..542f8caff7 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml @@ -725,6 +725,14 @@ spec: HTTP/2 PING frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml index 2bb89bb1bf..9be5b6d257 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml @@ -11802,6 +11802,14 @@ spec: alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING @@ -13098,6 +13106,14 @@ spec: alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING @@ -14548,6 +14564,14 @@ spec: keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before @@ -15914,6 +15938,14 @@ spec: alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml index de8b24b7af..63db538e61 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -1345,6 +1345,14 @@ spec: HTTP/2 PING frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection @@ -2524,6 +2532,14 @@ spec: HTTP/2 PING frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection @@ -3915,6 +3931,14 @@ spec: connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering @@ -5363,6 +5387,14 @@ spec: HTTP/2 PING frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection 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 77638552c1..b7ff610cc7 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -662,6 +662,14 @@ spec: frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection dead. 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 4d5bad3bb3..c37bdf495a 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml @@ -812,6 +812,14 @@ spec: frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection dead. 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 e99a1006ca..4c8da9e79c 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml @@ -724,6 +724,14 @@ spec: HTTP/2 PING frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection 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 1e39f98536..ec138f70cf 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml @@ -11801,6 +11801,14 @@ spec: alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING @@ -13097,6 +13105,14 @@ spec: alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING @@ -14547,6 +14563,14 @@ spec: keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before @@ -15913,6 +15937,14 @@ spec: alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering 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 6c6c0c8e16..679644fd89 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -1344,6 +1344,14 @@ spec: HTTP/2 PING frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection @@ -2523,6 +2531,14 @@ spec: HTTP/2 PING frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection @@ -3914,6 +3930,14 @@ spec: connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering @@ -5362,6 +5386,14 @@ spec: HTTP/2 PING frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection diff --git a/internal/gatewayapi/http.go b/internal/gatewayapi/http.go index 9eca1d41e8..2d64b3b130 100644 --- a/internal/gatewayapi/http.go +++ b/internal/gatewayapi/http.go @@ -91,6 +91,9 @@ func buildIRHTTP2Settings(http2Settings *egv1a1.HTTP2Settings) (*ir.HTTP2Setting keepalive.Timeout = ptr.To(uint32(d.Seconds())) } } + if http2Settings.ConnectionKeepalive.IntervalJitter != nil { + keepalive.IntervalJitter = http2Settings.ConnectionKeepalive.IntervalJitter + } if http2Settings.ConnectionKeepalive.ConnectionIdleInterval != nil { d, err := time.ParseDuration(string(*http2Settings.ConnectionKeepalive.ConnectionIdleInterval)) if err != nil { diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.in.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.in.yaml index c67d42416e..bf6c0f8193 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.in.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.in.yaml @@ -48,4 +48,5 @@ backendTrafficPolicies: connectionKeepalive: interval: 60s timeout: 10s + intervalJitter: 20 connectionIdleInterval: 30s diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml index 56689643b6..4f74856aa4 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml @@ -9,6 +9,7 @@ backendTrafficPolicies: connectionKeepalive: connectionIdleInterval: 30s interval: 60s + intervalJitter: 20 timeout: 10s targetRef: group: gateway.networking.k8s.io @@ -214,6 +215,7 @@ xdsIR: connectionKeepalive: connectionIdleInterval: 30 interval: 60 + intervalJitter: 20 timeout: 10 readyListener: address: 0.0.0.0 diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.in.yaml index 81ae627b56..1fe936bce7 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.in.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.in.yaml @@ -9,6 +9,7 @@ clientTrafficPolicies: connectionKeepalive: interval: 60s timeout: 10s + intervalJitter: 20 connectionIdleInterval: 30s targetRef: group: gateway.networking.k8s.io diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml index 3767fd456e..4a7902d104 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml @@ -9,6 +9,7 @@ clientTrafficPolicies: connectionKeepalive: connectionIdleInterval: 30s interval: 60s + intervalJitter: 20 timeout: 10s targetRef: group: gateway.networking.k8s.io @@ -125,6 +126,7 @@ xdsIR: connectionKeepalive: connectionIdleInterval: 30 interval: 60 + intervalJitter: 20 timeout: 10 isHTTP2: false metadata: diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 587bb2900d..a902416923 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -627,6 +627,8 @@ type HTTP2ConnectionKeepalive struct { Interval *uint32 `json:"interval,omitempty" yaml:"interval,omitempty"` // Timeout specifies how long to wait for a PING response (in seconds). Timeout *uint32 `json:"timeout,omitempty" yaml:"timeout,omitempty"` + // IntervalJitter specifies a random jitter percentage added to each interval (0-100). + IntervalJitter *uint32 `json:"intervalJitter,omitempty" yaml:"intervalJitter,omitempty"` // ConnectionIdleInterval specifies idle time before sending a PING (in seconds). ConnectionIdleInterval *uint32 `json:"connectionIdleInterval,omitempty" yaml:"connectionIdleInterval,omitempty"` } diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index ca2bfd0eda..130ac7b8c2 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -1715,6 +1715,11 @@ func (in *HTTP2ConnectionKeepalive) DeepCopyInto(out *HTTP2ConnectionKeepalive) *out = new(uint32) **out = **in } + if in.IntervalJitter != nil { + in, out := &in.IntervalJitter, &out.IntervalJitter + *out = new(uint32) + **out = **in + } if in.ConnectionIdleInterval != nil { in, out := &in.ConnectionIdleInterval, &out.ConnectionIdleInterval *out = new(uint32) diff --git a/internal/xds/translator/listener.go b/internal/xds/translator/listener.go index fa3dea7f66..f866caf0ed 100644 --- a/internal/xds/translator/listener.go +++ b/internal/xds/translator/listener.go @@ -119,6 +119,9 @@ func http2ProtocolOptions(opts *ir.HTTP2Settings) *corev3.Http2ProtocolOptions { if opts.ConnectionKeepalive.Timeout != nil { keepalive.Timeout = durationpb.New(time.Duration(*opts.ConnectionKeepalive.Timeout) * time.Second) } + if opts.ConnectionKeepalive.IntervalJitter != nil { + keepalive.IntervalJitter = &typev3.Percent{Value: float64(*opts.ConnectionKeepalive.IntervalJitter)} + } if opts.ConnectionKeepalive.ConnectionIdleInterval != nil { keepalive.ConnectionIdleInterval = durationpb.New(time.Duration(*opts.ConnectionKeepalive.ConnectionIdleInterval) * time.Second) } diff --git a/internal/xds/translator/testdata/in/xds-ir/http2-keepalive.yaml b/internal/xds/translator/testdata/in/xds-ir/http2-keepalive.yaml index b8a1d99182..b539ec8d5b 100644 --- a/internal/xds/translator/testdata/in/xds-ir/http2-keepalive.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/http2-keepalive.yaml @@ -14,6 +14,7 @@ http: connectionKeepalive: interval: 60 timeout: 10 + intervalJitter: 20 connectionIdleInterval: 30 routes: - name: "first-route" diff --git a/internal/xds/translator/testdata/out/xds-ir/http2-keepalive.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http2-keepalive.listeners.yaml index 1970b887b1..00964415dd 100644 --- a/internal/xds/translator/testdata/out/xds-ir/http2-keepalive.listeners.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/http2-keepalive.listeners.yaml @@ -13,6 +13,8 @@ connectionKeepalive: connectionIdleInterval: 30s interval: 60s + intervalJitter: + value: 20 timeout: 10s initialConnectionWindowSize: 33554432 initialStreamWindowSize: 65536 diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index 4cccbddbfa..fe10e58291 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -2399,6 +2399,7 @@ _Appears in:_ | --- | --- | --- | --- | --- | | `interval` | _[Duration](https://gateway-api.sigs.k8s.io/reference/1.4/spec/#duration)_ | false | | Interval specifies how often to send HTTP/2 PING frames to keep the connection alive. | | `timeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/1.4/spec/#duration)_ | false | | Timeout specifies how long to wait for a PING response before considering the connection dead. | +| `intervalJitter` | _integer_ | false | | IntervalJitter specifies a random jitter percentage added to each interval.
Defaults to 15% if not specified. | | `connectionIdleInterval` | _[Duration](https://gateway-api.sigs.k8s.io/reference/1.4/spec/#duration)_ | false | | ConnectionIdleInterval specifies how long a connection must be idle before a PING is sent. | diff --git a/test/helm/gateway-crds-helm/all.out.yaml b/test/helm/gateway-crds-helm/all.out.yaml index 8ad08a02bb..7f2bc43d5b 100644 --- a/test/helm/gateway-crds-helm/all.out.yaml +++ b/test/helm/gateway-crds-helm/all.out.yaml @@ -21948,6 +21948,26 @@ spec: http2: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 connection + keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies how long a connection + must be idle before a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send HTTP/2 PING + frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait for a PING + response before considering the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -25095,6 +25115,26 @@ spec: http2: description: HTTP2 provides HTTP/2 configuration on the listener. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 connection + keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies how long a connection + must be idle before a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send HTTP/2 PING + frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait for a PING + response before considering the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -26917,6 +26957,28 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 connection + keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies how + long a connection must be idle before a PING is + sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send + HTTP/2 PING frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait + for a PING response before considering the connection + dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -40686,6 +40748,33 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures + HTTP/2 connection keepalive using + PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval + specifies how long a connection + must be idle before a PING is + sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies + how often to send HTTP/2 PING + frames to keep the connection + alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies + how long to wait for a PING + response before considering + the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -41955,6 +42044,33 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures + HTTP/2 connection keepalive using + PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval + specifies how long a connection + must be idle before a PING is + sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies + how often to send HTTP/2 PING + frames to keep the connection + alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies + how long to wait for a PING + response before considering + the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -43380,6 +43496,30 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures + HTTP/2 connection keepalive using PING + frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval + specifies how long a connection must + be idle before a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how + often to send HTTP/2 PING frames to + keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long + to wait for a PING response before + considering the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -44723,6 +44863,29 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 + connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before + a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often + to send HTTP/2 PING frames to keep the connection + alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to + wait for a PING response before considering + the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -47405,6 +47568,28 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 + connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before a + PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send + HTTP/2 PING frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait + for a PING response before considering the connection + dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -48562,6 +48747,28 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 + connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before a + PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send + HTTP/2 PING frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait + for a PING response before considering the connection + dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -49930,6 +50137,29 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures + HTTP/2 connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before + a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often + to send HTTP/2 PING frames to keep the + connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long + to wait for a PING response before considering + the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -51356,6 +51586,28 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 + connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before a + PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send + HTTP/2 PING frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait + for a PING response before considering the connection + dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ diff --git a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml index ebb016d68c..ca72fcf585 100644 --- a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml +++ b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml @@ -1128,6 +1128,26 @@ spec: http2: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 connection + keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies how long a connection + must be idle before a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send HTTP/2 PING + frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait for a PING + response before considering the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -4275,6 +4295,26 @@ spec: http2: description: HTTP2 provides HTTP/2 configuration on the listener. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 connection + keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies how long a connection + must be idle before a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send HTTP/2 PING + frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait for a PING + response before considering the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -6097,6 +6137,28 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 connection + keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies how + long a connection must be idle before a PING is + sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send + HTTP/2 PING frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait + for a PING response before considering the connection + dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -19866,6 +19928,33 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures + HTTP/2 connection keepalive using + PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval + specifies how long a connection + must be idle before a PING is + sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies + how often to send HTTP/2 PING + frames to keep the connection + alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies + how long to wait for a PING + response before considering + the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -21135,6 +21224,33 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures + HTTP/2 connection keepalive using + PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval + specifies how long a connection + must be idle before a PING is + sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies + how often to send HTTP/2 PING + frames to keep the connection + alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies + how long to wait for a PING + response before considering + the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -22560,6 +22676,30 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures + HTTP/2 connection keepalive using PING + frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval + specifies how long a connection must + be idle before a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how + often to send HTTP/2 PING frames to + keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long + to wait for a PING response before + considering the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -23903,6 +24043,29 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 + connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before + a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often + to send HTTP/2 PING frames to keep the connection + alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to + wait for a PING response before considering + the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -26585,6 +26748,28 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 + connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before a + PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send + HTTP/2 PING frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait + for a PING response before considering the connection + dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -27742,6 +27927,28 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 + connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before a + PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send + HTTP/2 PING frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait + for a PING response before considering the connection + dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -29110,6 +29317,29 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures + HTTP/2 connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before + a PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often + to send HTTP/2 PING frames to keep the + connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long + to wait for a PING response before considering + the connection dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -30536,6 +30766,28 @@ spec: description: HTTP2 provides HTTP/2 configuration for backend connections. properties: + connectionKeepalive: + description: ConnectionKeepalive configures HTTP/2 + connection keepalive using PING frames. + properties: + connectionIdleInterval: + description: ConnectionIdleInterval specifies + how long a connection must be idle before a + PING is sent. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + interval: + description: Interval specifies how often to send + HTTP/2 PING frames to keep the connection alive. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + timeout: + description: Timeout specifies how long to wait + for a PING response before considering the connection + dead. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ From 55cfed6227ab0f68f3014afedd72aece34449981 Mon Sep 17 00:00:00 2001 From: Rajat Vig Date: Mon, 9 Feb 2026 00:38:58 +0000 Subject: [PATCH 3/8] add generated code Signed-off-by: Rajat Vig --- test/helm/gateway-crds-helm/all.out.yaml | 88 +++++++++++++++++++ .../envoy-gateway-crds.out.yaml | 88 +++++++++++++++++++ 2 files changed, 176 insertions(+) diff --git a/test/helm/gateway-crds-helm/all.out.yaml b/test/helm/gateway-crds-helm/all.out.yaml index 7f2bc43d5b..189d0a0c28 100644 --- a/test/helm/gateway-crds-helm/all.out.yaml +++ b/test/helm/gateway-crds-helm/all.out.yaml @@ -21962,6 +21962,14 @@ spec: frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection dead. @@ -25129,6 +25137,14 @@ spec: frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection dead. @@ -26972,6 +26988,14 @@ spec: HTTP/2 PING frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection @@ -40767,6 +40791,14 @@ spec: alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING @@ -42063,6 +42095,14 @@ spec: alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING @@ -43513,6 +43553,14 @@ spec: keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before @@ -44879,6 +44927,14 @@ spec: alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering @@ -47583,6 +47639,14 @@ spec: HTTP/2 PING frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection @@ -48762,6 +48826,14 @@ spec: HTTP/2 PING frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection @@ -50153,6 +50225,14 @@ spec: connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering @@ -51601,6 +51681,14 @@ spec: HTTP/2 PING frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection diff --git a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml index ca72fcf585..1c3d034877 100644 --- a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml +++ b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml @@ -1142,6 +1142,14 @@ spec: frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection dead. @@ -4309,6 +4317,14 @@ spec: frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection dead. @@ -6152,6 +6168,14 @@ spec: HTTP/2 PING frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection @@ -19947,6 +19971,14 @@ spec: alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING @@ -21243,6 +21275,14 @@ spec: alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING @@ -22693,6 +22733,14 @@ spec: keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before @@ -24059,6 +24107,14 @@ spec: alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering @@ -26763,6 +26819,14 @@ spec: HTTP/2 PING frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection @@ -27942,6 +28006,14 @@ spec: HTTP/2 PING frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection @@ -29333,6 +29405,14 @@ spec: connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering @@ -30781,6 +30861,14 @@ spec: HTTP/2 PING frames to keep the connection alive. pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string + intervalJitter: + description: |- + IntervalJitter specifies a random jitter percentage added to each interval. + Defaults to 15% if not specified. + format: int32 + maximum: 100 + minimum: 0 + type: integer timeout: description: Timeout specifies how long to wait for a PING response before considering the connection From f3fbb6890c5ac3e558b6eb8feec9ee4bfbc61443 Mon Sep 17 00:00:00 2001 From: Rajat Vig Date: Mon, 9 Feb 2026 00:49:53 +0000 Subject: [PATCH 4/8] add validations Signed-off-by: Rajat Vig --- internal/gatewayapi/http.go | 3 + ...cy-http2-keepalive-invalid-timeout.in.yaml | 31 ++++ ...y-http2-keepalive-invalid-timeout.out.yaml | 138 ++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive-invalid-timeout.in.yaml create mode 100644 internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive-invalid-timeout.out.yaml diff --git a/internal/gatewayapi/http.go b/internal/gatewayapi/http.go index 2d64b3b130..20c7bf1b1d 100644 --- a/internal/gatewayapi/http.go +++ b/internal/gatewayapi/http.go @@ -91,6 +91,9 @@ func buildIRHTTP2Settings(http2Settings *egv1a1.HTTP2Settings) (*ir.HTTP2Setting keepalive.Timeout = ptr.To(uint32(d.Seconds())) } } + if keepalive.Interval != nil && keepalive.Timeout != nil && *keepalive.Timeout >= *keepalive.Interval { + errs = errors.Join(errs, fmt.Errorf("ConnectionKeepalive.Timeout must be less than Interval")) + } if http2Settings.ConnectionKeepalive.IntervalJitter != nil { keepalive.IntervalJitter = http2Settings.ConnectionKeepalive.IntervalJitter } diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive-invalid-timeout.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive-invalid-timeout.in.yaml new file mode 100644 index 0000000000..af370c367c --- /dev/null +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive-invalid-timeout.in.yaml @@ -0,0 +1,31 @@ +clientTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + namespace: envoy-gateway + name: target-gateway-1-section-http-1 + spec: + http2: + connectionKeepalive: + interval: 10s + timeout: 60s + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: http-1 +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + namespace: envoy-gateway + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http-1 + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: Same diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive-invalid-timeout.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive-invalid-timeout.out.yaml new file mode 100644 index 0000000000..0d3a5ea81d --- /dev/null +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive-invalid-timeout.out.yaml @@ -0,0 +1,138 @@ +clientTrafficPolicies: +- apiVersion: gateway.envoyproxy.io/v1alpha1 + kind: ClientTrafficPolicy + metadata: + name: target-gateway-1-section-http-1 + namespace: envoy-gateway + spec: + http2: + connectionKeepalive: + interval: 10s + timeout: 60s + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + sectionName: http-1 + status: + ancestors: + - ancestorRef: + group: gateway.networking.k8s.io + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http-1 + conditions: + - lastTransitionTime: null + message: 'HTTP2: ConnectionKeepalive.Timeout must be less than Interval.' + reason: Invalid + status: "False" + type: Accepted + controllerName: gateway.envoyproxy.io/gatewayclass-controller +gateways: +- apiVersion: gateway.networking.k8s.io/v1 + kind: Gateway + metadata: + name: gateway-1 + namespace: envoy-gateway + spec: + gatewayClassName: envoy-gateway-class + listeners: + - allowedRoutes: + namespaces: + from: Same + name: http-1 + port: 80 + protocol: HTTP + status: + listeners: + - attachedRoutes: 0 + conditions: + - lastTransitionTime: null + message: Sending translated listener configuration to the data plane + reason: Programmed + status: "True" + type: Programmed + - lastTransitionTime: null + message: Listener has been successfully translated + reason: Accepted + status: "True" + type: Accepted + - lastTransitionTime: null + message: Listener references have been resolved + reason: ResolvedRefs + status: "True" + type: ResolvedRefs + name: http-1 + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + - group: gateway.networking.k8s.io + kind: GRPCRoute +infraIR: + envoy-gateway/gateway-1: + proxy: + listeners: + - address: null + name: envoy-gateway/gateway-1/http-1 + ports: + - containerPort: 10080 + name: http-80 + protocol: HTTP + servicePort: 80 + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway + ownerReference: + kind: GatewayClass + name: envoy-gateway-class + name: envoy-gateway/gateway-1 + namespace: envoy-gateway-system +xdsIR: + envoy-gateway/gateway-1: + accessLog: + json: + - path: /dev/stdout + globalResources: + proxyServiceCluster: + metadata: + kind: Service + name: envoy-envoy-gateway-gateway-1-196ae069 + namespace: envoy-gateway-system + sectionName: "8080" + name: envoy-gateway/gateway-1 + settings: + - addressType: IP + endpoints: + - host: 7.6.5.4 + port: 8080 + zone: zone1 + metadata: + kind: Service + name: envoy-envoy-gateway-gateway-1-196ae069 + namespace: envoy-gateway-system + sectionName: "8080" + name: envoy-gateway/gateway-1 + protocol: TCP + http: + - address: 0.0.0.0 + externalPort: 80 + hostnames: + - '*' + isHTTP2: false + metadata: + kind: Gateway + name: gateway-1 + namespace: envoy-gateway + sectionName: http-1 + name: envoy-gateway/gateway-1/http-1 + path: + escapedSlashesAction: UnescapeAndRedirect + mergeSlashes: true + port: 10080 + readyListener: + address: 0.0.0.0 + ipFamily: IPv4 + path: /ready + port: 19003 From 1eb2bf78b623f8102f5f0b0bb964f3a1d2cbc59d Mon Sep 17 00:00:00 2001 From: Rajat Vig Date: Mon, 16 Feb 2026 11:46:55 +0000 Subject: [PATCH 5/8] add CEL validations + change buildHTTP2Settings Signed-off-by: Rajat Vig --- api/v1alpha1/shared_types.go | 1 + .../experimental-gatewayapi-crds.yaml | 306 +++++------------- ....envoyproxy.io_backendtrafficpolicies.yaml | 4 + ...y.envoyproxy.io_clienttrafficpolicies.yaml | 4 + ....envoyproxy.io_envoyextensionpolicies.yaml | 4 + .../gateway.envoyproxy.io_envoyproxies.yaml | 18 ++ ...ateway.envoyproxy.io_securitypolicies.yaml | 16 + .../templates/standard-gatewayapi-crds.yaml | 12 - charts/gateway-helm/crds/gatewayapi-crds.yaml | 306 +++++------------- ....envoyproxy.io_backendtrafficpolicies.yaml | 4 + ...y.envoyproxy.io_clienttrafficpolicies.yaml | 4 + ....envoyproxy.io_envoyextensionpolicies.yaml | 4 + .../gateway.envoyproxy.io_envoyproxies.yaml | 18 ++ ...ateway.envoyproxy.io_securitypolicies.yaml | 16 + internal/gatewayapi/http.go | 3 - ...cy-http2-keepalive-invalid-timeout.in.yaml | 31 -- ...y-http2-keepalive-invalid-timeout.out.yaml | 138 -------- internal/xds/translator/cluster.go | 17 + .../testdata/in/xds-ir/http2-route.yaml | 5 + .../out/xds-ir/http2-route.clusters.yaml | 6 + 20 files changed, 277 insertions(+), 640 deletions(-) delete mode 100644 internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive-invalid-timeout.in.yaml delete mode 100644 internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive-invalid-timeout.out.yaml diff --git a/api/v1alpha1/shared_types.go b/api/v1alpha1/shared_types.go index fe1e9df220..ff8428f11b 100644 --- a/api/v1alpha1/shared_types.go +++ b/api/v1alpha1/shared_types.go @@ -725,6 +725,7 @@ type HTTP2Settings struct { } // HTTP2ConnectionKeepalive configures HTTP/2 PING-based keepalive settings. +// +kubebuilder:validation:XValidation:rule="!has(self.timeout) || !has(self.interval) || duration(self.timeout) < duration(self.interval)",message="timeout must be less than interval" type HTTP2ConnectionKeepalive struct { // Interval specifies how often to send HTTP/2 PING frames to keep the connection alive. // +optional diff --git a/charts/gateway-crds-helm/templates/experimental-gatewayapi-crds.yaml b/charts/gateway-crds-helm/templates/experimental-gatewayapi-crds.yaml index e763641dfa..3ca2945b02 100644 --- a/charts/gateway-crds-helm/templates/experimental-gatewayapi-crds.yaml +++ b/charts/gateway-crds-helm/templates/experimental-gatewayapi-crds.yaml @@ -2860,30 +2860,19 @@ spec: properties: clientCertificateRef: description: |- - ClientCertificateRef references an object that contains a client certificate - and its associated private key. It can reference standard Kubernetes resources, - i.e., Secret, or implementation-specific custom resources. - - A ClientCertificateRef is considered invalid if: - - * It refers to a resource that cannot be resolved (e.g., the referenced resource - does not exist) or is misconfigured (e.g., a Secret does not contain the keys - named `tls.crt` and `tls.key`). In this case, the `ResolvedRefs` condition - on the Gateway MUST be set to False with the Reason `InvalidClientCertificateRef` - and the Message of the Condition MUST indicate why the reference is invalid. - - * It refers to a resource in another namespace UNLESS there is a ReferenceGrant - in the target namespace that allows the certificate to be attached. - If a ReferenceGrant does not allow this reference, the `ResolvedRefs` condition - on the Gateway MUST be set to False with the Reason `RefNotPermitted`. - - Implementations MAY choose to perform further validation of the certificate - content (e.g., checking expiry or enforcing specific formats). In such cases, - an implementation-specific Reason and Message MUST be set. - - Support: Core - Reference to a Kubernetes TLS Secret (with the type `kubernetes.io/tls`). - Support: Implementation-specific - Other resource kinds or Secrets with a - different type (e.g., `Opaque`). + ClientCertificateRef is a reference to an object that contains a Client + Certificate and the associated private key. + + 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. If a ReferenceGrant does not allow this reference, the + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + + ClientCertificateRef can reference to standard Kubernetes resources, i.e. + Secret, or implementation-specific custom resources. + + Support: Core properties: group: default: "" @@ -4448,30 +4437,19 @@ spec: properties: clientCertificateRef: description: |- - ClientCertificateRef references an object that contains a client certificate - and its associated private key. It can reference standard Kubernetes resources, - i.e., Secret, or implementation-specific custom resources. - - A ClientCertificateRef is considered invalid if: - - * It refers to a resource that cannot be resolved (e.g., the referenced resource - does not exist) or is misconfigured (e.g., a Secret does not contain the keys - named `tls.crt` and `tls.key`). In this case, the `ResolvedRefs` condition - on the Gateway MUST be set to False with the Reason `InvalidClientCertificateRef` - and the Message of the Condition MUST indicate why the reference is invalid. - - * It refers to a resource in another namespace UNLESS there is a ReferenceGrant - in the target namespace that allows the certificate to be attached. - If a ReferenceGrant does not allow this reference, the `ResolvedRefs` condition - on the Gateway MUST be set to False with the Reason `RefNotPermitted`. - - Implementations MAY choose to perform further validation of the certificate - content (e.g., checking expiry or enforcing specific formats). In such cases, - an implementation-specific Reason and Message MUST be set. - - Support: Core - Reference to a Kubernetes TLS Secret (with the type `kubernetes.io/tls`). - Support: Implementation-specific - Other resource kinds or Secrets with a - different type (e.g., `Opaque`). + ClientCertificateRef is a reference to an object that contains a Client + Certificate and the associated private key. + + 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. If a ReferenceGrant does not allow this reference, the + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + + ClientCertificateRef can reference to standard Kubernetes resources, i.e. + Secret, or implementation-specific custom resources. + + Support: Core properties: group: default: "" @@ -5665,14 +5643,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -5744,14 +5718,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -5956,14 +5926,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -6035,14 +6001,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -6333,14 +6295,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -6411,14 +6369,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -6622,14 +6576,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -6700,14 +6650,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -8316,7 +8262,6 @@ spec: If the list has entries, only those entries must be sent. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set type: object @@ -8355,7 +8300,6 @@ spec: request must be set to the actual number of bytes forwarded. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set allowedResponseHeaders: @@ -8367,7 +8311,6 @@ spec: except Authority or Host must be copied. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set path: @@ -8472,14 +8415,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -8551,14 +8490,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -8869,9 +8804,6 @@ spec: enum: - 301 - 302 - - 303 - - 307 - - 308 type: integer type: object responseHeaderModifier: @@ -8919,14 +8851,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -8998,14 +8926,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -9818,7 +9742,6 @@ spec: If the list has entries, only those entries must be sent. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set type: object @@ -9857,7 +9780,6 @@ spec: request must be set to the actual number of bytes forwarded. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set allowedResponseHeaders: @@ -9869,7 +9791,6 @@ spec: except Authority or Host must be copied. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set path: @@ -9971,14 +9892,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -10049,14 +9966,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -10367,9 +10280,6 @@ spec: enum: - 301 - 302 - - 303 - - 307 - - 308 type: integer type: object responseHeaderModifier: @@ -10416,14 +10326,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -10494,14 +10400,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -10835,14 +10737,10 @@ spec: - RegularExpression type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header to + be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -12522,7 +12420,6 @@ spec: If the list has entries, only those entries must be sent. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set type: object @@ -12561,7 +12458,6 @@ spec: request must be set to the actual number of bytes forwarded. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set allowedResponseHeaders: @@ -12573,7 +12469,6 @@ spec: except Authority or Host must be copied. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set path: @@ -12678,14 +12573,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -12757,14 +12648,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -13075,9 +12962,6 @@ spec: enum: - 301 - 302 - - 303 - - 307 - - 308 type: integer type: object responseHeaderModifier: @@ -13125,14 +13009,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -13204,14 +13084,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -14024,7 +13900,6 @@ spec: If the list has entries, only those entries must be sent. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set type: object @@ -14063,7 +13938,6 @@ spec: request must be set to the actual number of bytes forwarded. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set allowedResponseHeaders: @@ -14075,7 +13949,6 @@ spec: except Authority or Host must be copied. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set path: @@ -14177,14 +14050,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -14255,14 +14124,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -14573,9 +14438,6 @@ spec: enum: - 301 - 302 - - 303 - - 307 - - 308 type: integer type: object responseHeaderModifier: @@ -14622,14 +14484,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -14700,14 +14558,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -15041,14 +14895,10 @@ spec: - RegularExpression type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header to + be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml index 23266b095f..d3e35efe7a 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -677,6 +677,10 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than interval + rule: '!has(self.timeout) || !has(self.interval) || duration(self.timeout) + < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml index 79a5ab7adc..398df78927 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml @@ -827,6 +827,10 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than interval + rule: '!has(self.timeout) || !has(self.interval) || duration(self.timeout) + < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml index 542f8caff7..365064b4e2 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml @@ -740,6 +740,10 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than interval + rule: '!has(self.timeout) || !has(self.interval) || + duration(self.timeout) < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml index 9be5b6d257..bbd3d7f373 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml @@ -11818,6 +11818,11 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than + interval + rule: '!has(self.timeout) || !has(self.interval) + || duration(self.timeout) < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -13122,6 +13127,11 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than + interval + rule: '!has(self.timeout) || !has(self.interval) + || duration(self.timeout) < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -14579,6 +14589,10 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than interval + rule: '!has(self.timeout) || !has(self.interval) + || duration(self.timeout) < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -15953,6 +15967,10 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than interval + rule: '!has(self.timeout) || !has(self.interval) + || duration(self.timeout) < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml index 63db538e61..c59fec9f65 100644 --- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -1360,6 +1360,10 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than interval + rule: '!has(self.timeout) || !has(self.interval) + || duration(self.timeout) < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -2547,6 +2551,10 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than interval + rule: '!has(self.timeout) || !has(self.interval) + || duration(self.timeout) < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -3946,6 +3954,10 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than interval + rule: '!has(self.timeout) || !has(self.interval) + || duration(self.timeout) < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -5402,6 +5414,10 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than interval + rule: '!has(self.timeout) || !has(self.interval) + || duration(self.timeout) < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ diff --git a/charts/gateway-crds-helm/templates/standard-gatewayapi-crds.yaml b/charts/gateway-crds-helm/templates/standard-gatewayapi-crds.yaml index a663cce86f..fcc9e088b7 100644 --- a/charts/gateway-crds-helm/templates/standard-gatewayapi-crds.yaml +++ b/charts/gateway-crds-helm/templates/standard-gatewayapi-crds.yaml @@ -7087,9 +7087,6 @@ spec: enum: - 301 - 302 - - 303 - - 307 - - 308 type: integer type: object responseHeaderModifier: @@ -8024,9 +8021,6 @@ spec: enum: - 301 - 302 - - 303 - - 307 - - 308 type: integer type: object responseHeaderModifier: @@ -9902,9 +9896,6 @@ spec: enum: - 301 - 302 - - 303 - - 307 - - 308 type: integer type: object responseHeaderModifier: @@ -10839,9 +10830,6 @@ spec: enum: - 301 - 302 - - 303 - - 307 - - 308 type: integer type: object responseHeaderModifier: diff --git a/charts/gateway-helm/crds/gatewayapi-crds.yaml b/charts/gateway-helm/crds/gatewayapi-crds.yaml index 53f41ad8ee..ee7eb803a7 100644 --- a/charts/gateway-helm/crds/gatewayapi-crds.yaml +++ b/charts/gateway-helm/crds/gatewayapi-crds.yaml @@ -2859,30 +2859,19 @@ spec: properties: clientCertificateRef: description: |- - ClientCertificateRef references an object that contains a client certificate - and its associated private key. It can reference standard Kubernetes resources, - i.e., Secret, or implementation-specific custom resources. - - A ClientCertificateRef is considered invalid if: - - * It refers to a resource that cannot be resolved (e.g., the referenced resource - does not exist) or is misconfigured (e.g., a Secret does not contain the keys - named `tls.crt` and `tls.key`). In this case, the `ResolvedRefs` condition - on the Gateway MUST be set to False with the Reason `InvalidClientCertificateRef` - and the Message of the Condition MUST indicate why the reference is invalid. - - * It refers to a resource in another namespace UNLESS there is a ReferenceGrant - in the target namespace that allows the certificate to be attached. - If a ReferenceGrant does not allow this reference, the `ResolvedRefs` condition - on the Gateway MUST be set to False with the Reason `RefNotPermitted`. - - Implementations MAY choose to perform further validation of the certificate - content (e.g., checking expiry or enforcing specific formats). In such cases, - an implementation-specific Reason and Message MUST be set. - - Support: Core - Reference to a Kubernetes TLS Secret (with the type `kubernetes.io/tls`). - Support: Implementation-specific - Other resource kinds or Secrets with a - different type (e.g., `Opaque`). + ClientCertificateRef is a reference to an object that contains a Client + Certificate and the associated private key. + + 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. If a ReferenceGrant does not allow this reference, the + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + + ClientCertificateRef can reference to standard Kubernetes resources, i.e. + Secret, or implementation-specific custom resources. + + Support: Core properties: group: default: "" @@ -4447,30 +4436,19 @@ spec: properties: clientCertificateRef: description: |- - ClientCertificateRef references an object that contains a client certificate - and its associated private key. It can reference standard Kubernetes resources, - i.e., Secret, or implementation-specific custom resources. - - A ClientCertificateRef is considered invalid if: - - * It refers to a resource that cannot be resolved (e.g., the referenced resource - does not exist) or is misconfigured (e.g., a Secret does not contain the keys - named `tls.crt` and `tls.key`). In this case, the `ResolvedRefs` condition - on the Gateway MUST be set to False with the Reason `InvalidClientCertificateRef` - and the Message of the Condition MUST indicate why the reference is invalid. - - * It refers to a resource in another namespace UNLESS there is a ReferenceGrant - in the target namespace that allows the certificate to be attached. - If a ReferenceGrant does not allow this reference, the `ResolvedRefs` condition - on the Gateway MUST be set to False with the Reason `RefNotPermitted`. - - Implementations MAY choose to perform further validation of the certificate - content (e.g., checking expiry or enforcing specific formats). In such cases, - an implementation-specific Reason and Message MUST be set. - - Support: Core - Reference to a Kubernetes TLS Secret (with the type `kubernetes.io/tls`). - Support: Implementation-specific - Other resource kinds or Secrets with a - different type (e.g., `Opaque`). + ClientCertificateRef is a reference to an object that contains a Client + Certificate and the associated private key. + + 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. If a ReferenceGrant does not allow this reference, the + "ResolvedRefs" condition MUST be set to False for this listener with the + "RefNotPermitted" reason. + + ClientCertificateRef can reference to standard Kubernetes resources, i.e. + Secret, or implementation-specific custom resources. + + Support: Core properties: group: default: "" @@ -5664,14 +5642,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -5743,14 +5717,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -5955,14 +5925,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -6034,14 +6000,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -6332,14 +6294,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -6410,14 +6368,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -6621,14 +6575,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -6699,14 +6649,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -8315,7 +8261,6 @@ spec: If the list has entries, only those entries must be sent. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set type: object @@ -8354,7 +8299,6 @@ spec: request must be set to the actual number of bytes forwarded. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set allowedResponseHeaders: @@ -8366,7 +8310,6 @@ spec: except Authority or Host must be copied. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set path: @@ -8471,14 +8414,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -8550,14 +8489,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -8868,9 +8803,6 @@ spec: enum: - 301 - 302 - - 303 - - 307 - - 308 type: integer type: object responseHeaderModifier: @@ -8918,14 +8850,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -8997,14 +8925,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -9817,7 +9741,6 @@ spec: If the list has entries, only those entries must be sent. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set type: object @@ -9856,7 +9779,6 @@ spec: request must be set to the actual number of bytes forwarded. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set allowedResponseHeaders: @@ -9868,7 +9790,6 @@ spec: except Authority or Host must be copied. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set path: @@ -9970,14 +9891,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -10048,14 +9965,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -10366,9 +10279,6 @@ spec: enum: - 301 - 302 - - 303 - - 307 - - 308 type: integer type: object responseHeaderModifier: @@ -10415,14 +10325,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -10493,14 +10399,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -10834,14 +10736,10 @@ spec: - RegularExpression type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header to + be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -12521,7 +12419,6 @@ spec: If the list has entries, only those entries must be sent. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set type: object @@ -12560,7 +12457,6 @@ spec: request must be set to the actual number of bytes forwarded. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set allowedResponseHeaders: @@ -12572,7 +12468,6 @@ spec: except Authority or Host must be copied. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set path: @@ -12677,14 +12572,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -12756,14 +12647,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -13074,9 +12961,6 @@ spec: enum: - 301 - 302 - - 303 - - 307 - - 308 type: integer type: object responseHeaderModifier: @@ -13124,14 +13008,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -13203,14 +13083,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP + Header to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -14023,7 +13899,6 @@ spec: If the list has entries, only those entries must be sent. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set type: object @@ -14062,7 +13937,6 @@ spec: request must be set to the actual number of bytes forwarded. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set allowedResponseHeaders: @@ -14074,7 +13948,6 @@ spec: except Authority or Host must be copied. items: type: string - maxItems: 64 type: array x-kubernetes-list-type: set path: @@ -14176,14 +14049,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -14254,14 +14123,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -14572,9 +14437,6 @@ spec: enum: - 301 - 302 - - 303 - - 307 - - 308 type: integer type: object responseHeaderModifier: @@ -14621,14 +14483,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -14699,14 +14557,10 @@ spec: pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$ type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header + to be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name @@ -15040,14 +14894,10 @@ spec: - RegularExpression type: string value: - description: |- - Value is the value of HTTP Header to be matched. - - Must consist of printable US-ASCII characters, optionally separated - by single tabs or spaces. See: https://tools.ietf.org/html/rfc7230#section-3.2 + description: Value is the value of HTTP Header to + be matched. maxLength: 4096 minLength: 1 - pattern: ^[!-~]+([\t ]?[!-~]+)*$ type: string required: - name 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 b7ff610cc7..03198ddb9d 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_backendtrafficpolicies.yaml @@ -676,6 +676,10 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than interval + rule: '!has(self.timeout) || !has(self.interval) || duration(self.timeout) + < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ 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 c37bdf495a..ef94c299ef 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml @@ -826,6 +826,10 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than interval + rule: '!has(self.timeout) || !has(self.interval) || duration(self.timeout) + < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ 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 4c8da9e79c..04686a04ba 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml @@ -739,6 +739,10 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than interval + rule: '!has(self.timeout) || !has(self.interval) || + duration(self.timeout) < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ 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 ec138f70cf..0c839a685e 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml @@ -11817,6 +11817,11 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than + interval + rule: '!has(self.timeout) || !has(self.interval) + || duration(self.timeout) < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -13121,6 +13126,11 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than + interval + rule: '!has(self.timeout) || !has(self.interval) + || duration(self.timeout) < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -14578,6 +14588,10 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than interval + rule: '!has(self.timeout) || !has(self.interval) + || duration(self.timeout) < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -15952,6 +15966,10 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than interval + rule: '!has(self.timeout) || !has(self.interval) + || duration(self.timeout) < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ 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 679644fd89..93ef8336d4 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml @@ -1359,6 +1359,10 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than interval + rule: '!has(self.timeout) || !has(self.interval) + || duration(self.timeout) < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -2546,6 +2550,10 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than interval + rule: '!has(self.timeout) || !has(self.interval) + || duration(self.timeout) < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -3945,6 +3953,10 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than interval + rule: '!has(self.timeout) || !has(self.interval) + || duration(self.timeout) < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ @@ -5401,6 +5413,10 @@ spec: pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ type: string type: object + x-kubernetes-validations: + - message: timeout must be less than interval + rule: '!has(self.timeout) || !has(self.interval) + || duration(self.timeout) < duration(self.interval)' initialConnectionWindowSize: allOf: - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ diff --git a/internal/gatewayapi/http.go b/internal/gatewayapi/http.go index 20c7bf1b1d..2d64b3b130 100644 --- a/internal/gatewayapi/http.go +++ b/internal/gatewayapi/http.go @@ -91,9 +91,6 @@ func buildIRHTTP2Settings(http2Settings *egv1a1.HTTP2Settings) (*ir.HTTP2Setting keepalive.Timeout = ptr.To(uint32(d.Seconds())) } } - if keepalive.Interval != nil && keepalive.Timeout != nil && *keepalive.Timeout >= *keepalive.Interval { - errs = errors.Join(errs, fmt.Errorf("ConnectionKeepalive.Timeout must be less than Interval")) - } if http2Settings.ConnectionKeepalive.IntervalJitter != nil { keepalive.IntervalJitter = http2Settings.ConnectionKeepalive.IntervalJitter } diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive-invalid-timeout.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive-invalid-timeout.in.yaml deleted file mode 100644 index af370c367c..0000000000 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive-invalid-timeout.in.yaml +++ /dev/null @@ -1,31 +0,0 @@ -clientTrafficPolicies: -- apiVersion: gateway.envoyproxy.io/v1alpha1 - kind: ClientTrafficPolicy - metadata: - namespace: envoy-gateway - name: target-gateway-1-section-http-1 - spec: - http2: - connectionKeepalive: - interval: 10s - timeout: 60s - targetRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-1 - sectionName: http-1 -gateways: -- apiVersion: gateway.networking.k8s.io/v1 - kind: Gateway - metadata: - namespace: envoy-gateway - name: gateway-1 - spec: - gatewayClassName: envoy-gateway-class - listeners: - - name: http-1 - protocol: HTTP - port: 80 - allowedRoutes: - namespaces: - from: Same diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive-invalid-timeout.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive-invalid-timeout.out.yaml deleted file mode 100644 index 0d3a5ea81d..0000000000 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive-invalid-timeout.out.yaml +++ /dev/null @@ -1,138 +0,0 @@ -clientTrafficPolicies: -- apiVersion: gateway.envoyproxy.io/v1alpha1 - kind: ClientTrafficPolicy - metadata: - name: target-gateway-1-section-http-1 - namespace: envoy-gateway - spec: - http2: - connectionKeepalive: - interval: 10s - timeout: 60s - targetRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-1 - sectionName: http-1 - status: - ancestors: - - ancestorRef: - group: gateway.networking.k8s.io - kind: Gateway - name: gateway-1 - namespace: envoy-gateway - sectionName: http-1 - conditions: - - lastTransitionTime: null - message: 'HTTP2: ConnectionKeepalive.Timeout must be less than Interval.' - reason: Invalid - status: "False" - type: Accepted - controllerName: gateway.envoyproxy.io/gatewayclass-controller -gateways: -- apiVersion: gateway.networking.k8s.io/v1 - kind: Gateway - metadata: - name: gateway-1 - namespace: envoy-gateway - spec: - gatewayClassName: envoy-gateway-class - listeners: - - allowedRoutes: - namespaces: - from: Same - name: http-1 - port: 80 - protocol: HTTP - status: - listeners: - - attachedRoutes: 0 - conditions: - - lastTransitionTime: null - message: Sending translated listener configuration to the data plane - reason: Programmed - status: "True" - type: Programmed - - lastTransitionTime: null - message: Listener has been successfully translated - reason: Accepted - status: "True" - type: Accepted - - lastTransitionTime: null - message: Listener references have been resolved - reason: ResolvedRefs - status: "True" - type: ResolvedRefs - name: http-1 - supportedKinds: - - group: gateway.networking.k8s.io - kind: HTTPRoute - - group: gateway.networking.k8s.io - kind: GRPCRoute -infraIR: - envoy-gateway/gateway-1: - proxy: - listeners: - - address: null - name: envoy-gateway/gateway-1/http-1 - ports: - - containerPort: 10080 - name: http-80 - protocol: HTTP - servicePort: 80 - metadata: - labels: - gateway.envoyproxy.io/owning-gateway-name: gateway-1 - gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway - ownerReference: - kind: GatewayClass - name: envoy-gateway-class - name: envoy-gateway/gateway-1 - namespace: envoy-gateway-system -xdsIR: - envoy-gateway/gateway-1: - accessLog: - json: - - path: /dev/stdout - globalResources: - proxyServiceCluster: - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-1-196ae069 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-1 - settings: - - addressType: IP - endpoints: - - host: 7.6.5.4 - port: 8080 - zone: zone1 - metadata: - kind: Service - name: envoy-envoy-gateway-gateway-1-196ae069 - namespace: envoy-gateway-system - sectionName: "8080" - name: envoy-gateway/gateway-1 - protocol: TCP - http: - - address: 0.0.0.0 - externalPort: 80 - hostnames: - - '*' - isHTTP2: false - metadata: - kind: Gateway - name: gateway-1 - namespace: envoy-gateway - sectionName: http-1 - name: envoy-gateway/gateway-1/http-1 - path: - escapedSlashesAction: UnescapeAndRedirect - mergeSlashes: true - port: 10080 - readyListener: - address: 0.0.0.0 - ipFamily: IPv4 - path: /ready - port: 19003 diff --git a/internal/xds/translator/cluster.go b/internal/xds/translator/cluster.go index 0384f8dac7..4150b2b511 100644 --- a/internal/xds/translator/cluster.go +++ b/internal/xds/translator/cluster.go @@ -1351,6 +1351,23 @@ func buildHTTP2Settings(opts *ir.HTTP2Settings) *corev3.Http2ProtocolOptions { } } + if opts.ConnectionKeepalive != nil { + keepalive := &corev3.KeepaliveSettings{} + if opts.ConnectionKeepalive.Interval != nil { + keepalive.Interval = durationpb.New(time.Duration(*opts.ConnectionKeepalive.Interval) * time.Second) + } + if opts.ConnectionKeepalive.Timeout != nil { + keepalive.Timeout = durationpb.New(time.Duration(*opts.ConnectionKeepalive.Timeout) * time.Second) + } + if opts.ConnectionKeepalive.IntervalJitter != nil { + keepalive.IntervalJitter = &xdstype.Percent{Value: float64(*opts.ConnectionKeepalive.IntervalJitter)} + } + if opts.ConnectionKeepalive.ConnectionIdleInterval != nil { + keepalive.ConnectionIdleInterval = durationpb.New(time.Duration(*opts.ConnectionKeepalive.ConnectionIdleInterval) * time.Second) + } + out.ConnectionKeepalive = keepalive + } + return out } diff --git a/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml b/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml index 2532906f5c..6a2a1c3911 100644 --- a/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml @@ -34,6 +34,11 @@ http: initialStreamWindowSize: 524288000 maxConcurrentStreams: 200 resetStreamOnError: true + connectionKeepalive: + interval: 60 + timeout: 10 + intervalJitter: 20 + connectionIdleInterval: 30 - name: "second-route" hostname: "*" pathMatch: diff --git a/internal/xds/translator/testdata/out/xds-ir/http2-route.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http2-route.clusters.yaml index ed267e2009..76192596d3 100644 --- a/internal/xds/translator/testdata/out/xds-ir/http2-route.clusters.yaml +++ b/internal/xds/translator/testdata/out/xds-ir/http2-route.clusters.yaml @@ -27,6 +27,12 @@ '@type': type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicitHttpConfig: http2ProtocolOptions: + connectionKeepalive: + connectionIdleInterval: 30s + interval: 60s + intervalJitter: + value: 20 + timeout: 10s initialConnectionWindowSize: 524288000 initialStreamWindowSize: 1048576 maxConcurrentStreams: 200 From 49714972f3fefd981f632fea16168137bb1269cc Mon Sep 17 00:00:00 2001 From: Rajat Vig Date: Mon, 16 Feb 2026 11:53:31 +0000 Subject: [PATCH 6/8] fix: gen code Signed-off-by: Rajat Vig --- .../testdata/backendtrafficpolicy-http2-keepalive.out.yaml | 3 +-- .../testdata/clienttrafficpolicy-http2-keepalive.out.yaml | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml index 4f74856aa4..201b72b8ed 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml @@ -117,8 +117,7 @@ infraIR: envoy-gateway/gateway-1: proxy: listeners: - - address: null - name: envoy-gateway/gateway-1/http + - name: envoy-gateway/gateway-1/http ports: - containerPort: 10080 name: http-80 diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml index 4a7902d104..d96576df4c 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml @@ -75,8 +75,7 @@ infraIR: envoy-gateway/gateway-1: proxy: listeners: - - address: null - name: envoy-gateway/gateway-1/http-1 + - name: envoy-gateway/gateway-1/http-1 ports: - containerPort: 10080 name: http-80 From fa3c82adb18a2973c3928579408ef02d3c5ab0b0 Mon Sep 17 00:00:00 2001 From: Rajat Vig Date: Mon, 16 Feb 2026 12:09:44 +0000 Subject: [PATCH 7/8] fix: use metav1.Duration in IR Signed-off-by: Rajat Vig --- internal/gatewayapi/http.go | 6 +++--- .../backendtrafficpolicy-http2-keepalive.out.yaml | 6 +++--- .../clienttrafficpolicy-http2-keepalive.out.yaml | 6 +++--- internal/ir/xds.go | 12 ++++++------ internal/ir/zz_generated.deepcopy.go | 6 +++--- internal/xds/translator/cluster.go | 6 +++--- internal/xds/translator/listener.go | 7 +++---- .../testdata/in/xds-ir/http2-keepalive.yaml | 6 +++--- .../translator/testdata/in/xds-ir/http2-route.yaml | 6 +++--- 9 files changed, 30 insertions(+), 31 deletions(-) diff --git a/internal/gatewayapi/http.go b/internal/gatewayapi/http.go index 2d64b3b130..a604b69c1c 100644 --- a/internal/gatewayapi/http.go +++ b/internal/gatewayapi/http.go @@ -80,7 +80,7 @@ func buildIRHTTP2Settings(http2Settings *egv1a1.HTTP2Settings) (*ir.HTTP2Setting if err != nil { errs = errors.Join(errs, fmt.Errorf("invalid ConnectionKeepalive.Interval: %w", err)) } else { - keepalive.Interval = ptr.To(uint32(d.Seconds())) + keepalive.Interval = ir.MetaV1DurationPtr(d) } } if http2Settings.ConnectionKeepalive.Timeout != nil { @@ -88,7 +88,7 @@ func buildIRHTTP2Settings(http2Settings *egv1a1.HTTP2Settings) (*ir.HTTP2Setting if err != nil { errs = errors.Join(errs, fmt.Errorf("invalid ConnectionKeepalive.Timeout: %w", err)) } else { - keepalive.Timeout = ptr.To(uint32(d.Seconds())) + keepalive.Timeout = ir.MetaV1DurationPtr(d) } } if http2Settings.ConnectionKeepalive.IntervalJitter != nil { @@ -99,7 +99,7 @@ func buildIRHTTP2Settings(http2Settings *egv1a1.HTTP2Settings) (*ir.HTTP2Setting if err != nil { errs = errors.Join(errs, fmt.Errorf("invalid ConnectionKeepalive.ConnectionIdleInterval: %w", err)) } else { - keepalive.ConnectionIdleInterval = ptr.To(uint32(d.Seconds())) + keepalive.ConnectionIdleInterval = ir.MetaV1DurationPtr(d) } } http2.ConnectionKeepalive = keepalive diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml index 201b72b8ed..762e5ea33f 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml @@ -212,10 +212,10 @@ xdsIR: traffic: http2: connectionKeepalive: - connectionIdleInterval: 30 - interval: 60 + connectionIdleInterval: 30s + interval: 60s intervalJitter: 20 - timeout: 10 + timeout: 10s readyListener: address: 0.0.0.0 ipFamily: IPv4 diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml index d96576df4c..33484bb598 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml @@ -123,10 +123,10 @@ xdsIR: - '*' http2: connectionKeepalive: - connectionIdleInterval: 30 - interval: 60 + connectionIdleInterval: 30s + interval: 60s intervalJitter: 20 - timeout: 10 + timeout: 10s isHTTP2: false metadata: kind: Gateway diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 2a297ab2e8..026d978e66 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -634,14 +634,14 @@ type HTTP2Settings struct { // HTTP2ConnectionKeepalive configures HTTP/2 PING-based keepalive settings. // +k8s:deepcopy-gen=true type HTTP2ConnectionKeepalive struct { - // Interval specifies how often to send HTTP/2 PING frames (in seconds). - Interval *uint32 `json:"interval,omitempty" yaml:"interval,omitempty"` - // Timeout specifies how long to wait for a PING response (in seconds). - Timeout *uint32 `json:"timeout,omitempty" yaml:"timeout,omitempty"` + // Interval specifies how often to send HTTP/2 PING frames. + Interval *metav1.Duration `json:"interval,omitempty" yaml:"interval,omitempty"` + // Timeout specifies how long to wait for a PING response. + Timeout *metav1.Duration `json:"timeout,omitempty" yaml:"timeout,omitempty"` // IntervalJitter specifies a random jitter percentage added to each interval (0-100). IntervalJitter *uint32 `json:"intervalJitter,omitempty" yaml:"intervalJitter,omitempty"` - // ConnectionIdleInterval specifies idle time before sending a PING (in seconds). - ConnectionIdleInterval *uint32 `json:"connectionIdleInterval,omitempty" yaml:"connectionIdleInterval,omitempty"` + // ConnectionIdleInterval specifies idle time before sending a PING. + ConnectionIdleInterval *metav1.Duration `json:"connectionIdleInterval,omitempty" yaml:"connectionIdleInterval,omitempty"` } // ResponseOverride defines the configuration to override specific responses with a custom one. diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index 201c194345..9ba7b3f9bd 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -1707,12 +1707,12 @@ func (in *HTTP2ConnectionKeepalive) DeepCopyInto(out *HTTP2ConnectionKeepalive) *out = *in if in.Interval != nil { in, out := &in.Interval, &out.Interval - *out = new(uint32) + *out = new(metav1.Duration) **out = **in } if in.Timeout != nil { in, out := &in.Timeout, &out.Timeout - *out = new(uint32) + *out = new(metav1.Duration) **out = **in } if in.IntervalJitter != nil { @@ -1722,7 +1722,7 @@ func (in *HTTP2ConnectionKeepalive) DeepCopyInto(out *HTTP2ConnectionKeepalive) } if in.ConnectionIdleInterval != nil { in, out := &in.ConnectionIdleInterval, &out.ConnectionIdleInterval - *out = new(uint32) + *out = new(metav1.Duration) **out = **in } } diff --git a/internal/xds/translator/cluster.go b/internal/xds/translator/cluster.go index 4150b2b511..9764d6e11d 100644 --- a/internal/xds/translator/cluster.go +++ b/internal/xds/translator/cluster.go @@ -1354,16 +1354,16 @@ func buildHTTP2Settings(opts *ir.HTTP2Settings) *corev3.Http2ProtocolOptions { if opts.ConnectionKeepalive != nil { keepalive := &corev3.KeepaliveSettings{} if opts.ConnectionKeepalive.Interval != nil { - keepalive.Interval = durationpb.New(time.Duration(*opts.ConnectionKeepalive.Interval) * time.Second) + keepalive.Interval = durationpb.New(opts.ConnectionKeepalive.Interval.Duration) } if opts.ConnectionKeepalive.Timeout != nil { - keepalive.Timeout = durationpb.New(time.Duration(*opts.ConnectionKeepalive.Timeout) * time.Second) + keepalive.Timeout = durationpb.New(opts.ConnectionKeepalive.Timeout.Duration) } if opts.ConnectionKeepalive.IntervalJitter != nil { keepalive.IntervalJitter = &xdstype.Percent{Value: float64(*opts.ConnectionKeepalive.IntervalJitter)} } if opts.ConnectionKeepalive.ConnectionIdleInterval != nil { - keepalive.ConnectionIdleInterval = durationpb.New(time.Duration(*opts.ConnectionKeepalive.ConnectionIdleInterval) * time.Second) + keepalive.ConnectionIdleInterval = durationpb.New(opts.ConnectionKeepalive.ConnectionIdleInterval.Duration) } out.ConnectionKeepalive = keepalive } diff --git a/internal/xds/translator/listener.go b/internal/xds/translator/listener.go index 8d2e88214f..85bd1eee33 100644 --- a/internal/xds/translator/listener.go +++ b/internal/xds/translator/listener.go @@ -11,7 +11,6 @@ import ( "net" "strconv" "strings" - "time" xdscore "github.com/cncf/xds/go/xds/core/v3" matcher "github.com/cncf/xds/go/xds/type/matcher/v3" @@ -114,16 +113,16 @@ func http2ProtocolOptions(opts *ir.HTTP2Settings) *corev3.Http2ProtocolOptions { if opts.ConnectionKeepalive != nil { keepalive := &corev3.KeepaliveSettings{} if opts.ConnectionKeepalive.Interval != nil { - keepalive.Interval = durationpb.New(time.Duration(*opts.ConnectionKeepalive.Interval) * time.Second) + keepalive.Interval = durationpb.New(opts.ConnectionKeepalive.Interval.Duration) } if opts.ConnectionKeepalive.Timeout != nil { - keepalive.Timeout = durationpb.New(time.Duration(*opts.ConnectionKeepalive.Timeout) * time.Second) + keepalive.Timeout = durationpb.New(opts.ConnectionKeepalive.Timeout.Duration) } if opts.ConnectionKeepalive.IntervalJitter != nil { keepalive.IntervalJitter = &typev3.Percent{Value: float64(*opts.ConnectionKeepalive.IntervalJitter)} } if opts.ConnectionKeepalive.ConnectionIdleInterval != nil { - keepalive.ConnectionIdleInterval = durationpb.New(time.Duration(*opts.ConnectionKeepalive.ConnectionIdleInterval) * time.Second) + keepalive.ConnectionIdleInterval = durationpb.New(opts.ConnectionKeepalive.ConnectionIdleInterval.Duration) } out.ConnectionKeepalive = keepalive } diff --git a/internal/xds/translator/testdata/in/xds-ir/http2-keepalive.yaml b/internal/xds/translator/testdata/in/xds-ir/http2-keepalive.yaml index b539ec8d5b..ab7e7d6a1a 100644 --- a/internal/xds/translator/testdata/in/xds-ir/http2-keepalive.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/http2-keepalive.yaml @@ -12,10 +12,10 @@ http: initialStreamWindowSize: 33554432 maxConcurrentStreams: 200 connectionKeepalive: - interval: 60 - timeout: 10 + interval: 60s + timeout: 10s intervalJitter: 20 - connectionIdleInterval: 30 + connectionIdleInterval: 30s routes: - name: "first-route" hostname: "*" diff --git a/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml b/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml index 6a2a1c3911..0de76a52d2 100644 --- a/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/http2-route.yaml @@ -35,10 +35,10 @@ http: maxConcurrentStreams: 200 resetStreamOnError: true connectionKeepalive: - interval: 60 - timeout: 10 + interval: 60s + timeout: 10s intervalJitter: 20 - connectionIdleInterval: 30 + connectionIdleInterval: 30s - name: "second-route" hostname: "*" pathMatch: From d86786e38c2e3033dd09305fffea140f0027b640 Mon Sep 17 00:00:00 2001 From: Rajat Vig Date: Mon, 16 Feb 2026 12:16:34 +0000 Subject: [PATCH 8/8] fix: gen code Signed-off-by: Rajat Vig --- .../testdata/backendtrafficpolicy-http2-keepalive.out.yaml | 2 +- .../testdata/clienttrafficpolicy-http2-keepalive.out.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml index 762e5ea33f..3b2c568f3f 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-http2-keepalive.out.yaml @@ -213,7 +213,7 @@ xdsIR: http2: connectionKeepalive: connectionIdleInterval: 30s - interval: 60s + interval: 1m0s intervalJitter: 20 timeout: 10s readyListener: diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml index 33484bb598..281ca73022 100644 --- a/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml +++ b/internal/gatewayapi/testdata/clienttrafficpolicy-http2-keepalive.out.yaml @@ -124,7 +124,7 @@ xdsIR: http2: connectionKeepalive: connectionIdleInterval: 30s - interval: 60s + interval: 1m0s intervalJitter: 20 timeout: 10s isHTTP2: false