From 199f50c3386d956239c8e2ca4f5d8269fda80015 Mon Sep 17 00:00:00 2001 From: yaelSchechter <159942322+yaelSchechter@users.noreply.github.com> Date: Sun, 18 Feb 2024 18:10:31 +0200 Subject: [PATCH] api: Support Timeouts in ClientTrafficPolicy (#2605) * feat: Suppress 'X-Envoy' headers and pass-through the upstream 'Server' header by default (#2585) * Implement and update tests for the default header transformations. Signed-off-by: Lior Okman * Make 'gen-check' happy Signed-off-by: Lior Okman --------- Signed-off-by: Lior Okman Signed-off-by: Yael Shechter * bug: fix merge race (#2604) Between https://github.com/envoyproxy/gateway/pull/2585 & https://github.com/envoyproxy/gateway/pull/2581 Signed-off-by: Arko Dasgupta Signed-off-by: Yael Shechter * feat: downstream mTLS (#2490) * feat: downstream mTLS Relates to https://github.com/envoyproxy/gateway/pull/2483 Signed-off-by: Arko Dasgupta * configmap provider logic Signed-off-by: Arko Dasgupta * gatewayapi translation Signed-off-by: Arko Dasgupta * fix charts Signed-off-by: Arko Dasgupta * tests Signed-off-by: Arko Dasgupta * lint Signed-off-by: Arko Dasgupta --------- Signed-off-by: Arko Dasgupta Signed-off-by: Yael Shechter * add timeout to clientTrafficPolicy Signed-off-by: Yael Shechter * fix comment Signed-off-by: Yael Shechter * add omitempty Signed-off-by: Yael Shechter * add cel test for coverage Signed-off-by: Yael Shechter * run make commands Signed-off-by: Yael Shechter * change request timeout field name and desc Signed-off-by: Yael Shechter * tidy up comment Signed-off-by: Yael Shechter * fix cel test Signed-off-by: Yael Shechter * fix typo Signed-off-by: Yael Shechter * run generate Signed-off-by: Yael Shechter --------- Signed-off-by: Lior Okman Signed-off-by: Yael Shechter Signed-off-by: Arko Dasgupta Co-authored-by: Lior Okman Co-authored-by: Arko Dasgupta Co-authored-by: zirain --- api/v1alpha1/clienttrafficpolicy_types.go | 4 ++ api/v1alpha1/timeout_types.go | 15 +++++++ api/v1alpha1/zz_generated.deepcopy.go | 45 +++++++++++++++++++ ...y.envoyproxy.io_clienttrafficpolicies.yaml | 15 +++++++ site/content/en/latest/api/extension_types.md | 29 ++++++++++++ .../clienttrafficpolicy_test.go | 26 +++++++++-- 6 files changed, 131 insertions(+), 3 deletions(-) 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 {