diff --git a/api/v1alpha1/clienttrafficpolicy_types.go b/api/v1alpha1/clienttrafficpolicy_types.go index 27a11678070..3037e4b0c04 100644 --- a/api/v1alpha1/clienttrafficpolicy_types.go +++ b/api/v1alpha1/clienttrafficpolicy_types.go @@ -84,6 +84,10 @@ type ClientTrafficPolicySpec struct { // // +optional Headers *HeaderSettings `json:"headers,omitempty"` + // Timeout settings for the client connections. + // + // +optional + Timeout *ClientTimeout `json:"timeout,omitempty"` } // HeaderSettings providess configuration options for headers on the listener. diff --git a/api/v1alpha1/timeout_types.go b/api/v1alpha1/timeout_types.go index b26eb721b07..78289c968fa 100644 --- a/api/v1alpha1/timeout_types.go +++ b/api/v1alpha1/timeout_types.go @@ -41,3 +41,18 @@ type HTTPTimeout struct { // +optional MaxConnectionDuration *gwapiv1.Duration `json:"maxConnectionDuration,omitempty"` } + +type ClientTimeout struct { + // Timeout settings for HTTP. + // + // +optional + HTTP *HTTPClientTimeout `json:"http,omitempty"` +} + +type HTTPClientTimeout struct { + // The duration envoy waits for the complete request reception. This timer starts upon request + // initiation and stops when either the last byte of the request is sent upstream or when the response begins. + // + // +optional + RequestReceivedTimeout *gwapiv1.Duration `json:"requestReceivedTimeout,omitempty"` +} diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 0d1ba2bbecc..738dbc00a3b 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -373,6 +373,26 @@ func (in *ClientIPDetectionSettings) DeepCopy() *ClientIPDetectionSettings { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClientTimeout) DeepCopyInto(out *ClientTimeout) { + *out = *in + if in.HTTP != nil { + in, out := &in.HTTP, &out.HTTP + *out = new(HTTPClientTimeout) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientTimeout. +func (in *ClientTimeout) DeepCopy() *ClientTimeout { + if in == nil { + return nil + } + out := new(ClientTimeout) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClientTrafficPolicy) DeepCopyInto(out *ClientTrafficPolicy) { *out = *in @@ -476,6 +496,11 @@ func (in *ClientTrafficPolicySpec) DeepCopyInto(out *ClientTrafficPolicySpec) { *out = new(HeaderSettings) (*in).DeepCopyInto(*out) } + if in.Timeout != nil { + in, out := &in.Timeout, &out.Timeout + *out = new(ClientTimeout) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClientTrafficPolicySpec. @@ -1717,6 +1742,26 @@ func (in *HTTPActiveHealthChecker) DeepCopy() *HTTPActiveHealthChecker { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HTTPClientTimeout) DeepCopyInto(out *HTTPClientTimeout) { + *out = *in + if in.RequestReceivedTimeout != nil { + in, out := &in.RequestReceivedTimeout, &out.RequestReceivedTimeout + *out = new(apisv1.Duration) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPClientTimeout. +func (in *HTTPClientTimeout) DeepCopy() *HTTPClientTimeout { + if in == nil { + return nil + } + out := new(HTTPClientTimeout) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HTTPExtAuthService) DeepCopyInto(out *HTTPExtAuthService) { *out = *in 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 7786dcbdf68..83141a9c569 100644 --- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml +++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml @@ -230,6 +230,21 @@ spec: format: int32 type: integer type: object + timeout: + description: Timeout settings for the client connections. + properties: + http: + description: Timeout settings for HTTP. + properties: + requestReceivedTimeout: + description: The duration envoy waits for the complete request + reception. This timer starts upon request initiation and + stops when either the last byte of the request is sent upstream + or when the response begins. + pattern: ^([0-9]{1,5}(h|m|s|ms)){1,4}$ + type: string + type: object + type: object tls: description: TLS settings configure TLS termination settings with the downstream client. diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md index c8b4b4fa7c7..55a26a48d13 100644 --- a/site/content/en/latest/api/extension_types.md +++ b/site/content/en/latest/api/extension_types.md @@ -246,6 +246,20 @@ _Appears in:_ | `customHeader` | _[CustomHeaderExtensionSettings](#customheaderextensionsettings)_ | false | CustomHeader provides configuration for determining the client IP address for a request based on a trusted custom HTTP header. This uses the the custom_header original IP detection extension. Refer to https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/http/original_ip_detection/custom_header/v3/custom_header.proto for more details. | +#### ClientTimeout + + + + + +_Appears in:_ +- [ClientTrafficPolicySpec](#clienttrafficpolicyspec) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `http` | _[HTTPClientTimeout](#httpclienttimeout)_ | false | Timeout settings for HTTP. | + + #### ClientTrafficPolicy @@ -299,6 +313,7 @@ _Appears in:_ | `path` | _[PathSettings](#pathsettings)_ | false | Path enables managing how the incoming path set by clients can be normalized. | | `http1` | _[HTTP1Settings](#http1settings)_ | false | HTTP1 provides HTTP/1 configuration on the listener. | | `headers` | _[HeaderSettings](#headersettings)_ | false | HeaderSettings provides configuration for header management. | +| `timeout` | _[ClientTimeout](#clienttimeout)_ | false | Timeout settings for the client connections. | @@ -1145,6 +1160,20 @@ _Appears in:_ | `expectedResponse` | _[ActiveHealthCheckPayload](#activehealthcheckpayload)_ | false | ExpectedResponse defines a list of HTTP expected responses to match. | +#### HTTPClientTimeout + + + + + +_Appears in:_ +- [ClientTimeout](#clienttimeout) + +| Field | Type | Required | Description | +| --- | --- | --- | --- | +| `requestReceivedTimeout` | _[Duration](#duration)_ | false | The duration envoy waits for the complete request reception. This timer starts upon request initiation and stops when either the last byte of the request is sent upstream or when the response begins. | + + #### HTTPExtAuthService diff --git a/test/cel-validation/clienttrafficpolicy_test.go b/test/cel-validation/clienttrafficpolicy_test.go index 582656bd39d..31f04da8f3b 100644 --- a/test/cel-validation/clienttrafficpolicy_test.go +++ b/test/cel-validation/clienttrafficpolicy_test.go @@ -15,12 +15,11 @@ import ( "testing" "time" + egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/ptr" - + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - - egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1" ) func TestClientTrafficPolicyTarget(t *testing.T) { @@ -283,6 +282,27 @@ func TestClientTrafficPolicyTarget(t *testing.T) { "spec.tls: Invalid value: \"object\": setting ciphers has no effect if the minimum possible TLS version is 1.3", }, }, + { + desc: "valid timeout", + mutate: func(ctp *egv1a1.ClientTrafficPolicy) { + d := gwapiv1.Duration("300s") + ctp.Spec = egv1a1.ClientTrafficPolicySpec{ + TargetRef: gwapiv1a2.PolicyTargetReferenceWithSectionName{ + PolicyTargetReference: gwapiv1a2.PolicyTargetReference{ + Group: gwapiv1a2.Group("gateway.networking.k8s.io"), + Kind: gwapiv1a2.Kind("Gateway"), + Name: gwapiv1a2.ObjectName("eg"), + }, + }, + Timeout: &egv1a1.ClientTimeout{ + HTTP: &egv1a1.HTTPClientTimeout{ + RequestReceivedTimeout: &d, + }, + }, + } + }, + wantErrors: []string{}, + }, } for _, tc := range cases {