diff --git a/charts/consul/templates/crd-servicerouters.yaml b/charts/consul/templates/crd-servicerouters.yaml index 786054dc46..b28281dbb8 100644 --- a/charts/consul/templates/crd-servicerouters.yaml +++ b/charts/consul/templates/crd-servicerouters.yaml @@ -68,6 +68,10 @@ spec: description: Destination controls how to proxy the matching request(s) to a service. properties: + idleTimeout: + description: IdleTimeout is total amount of time permitted + for the request stream to be idle. + type: string namespace: description: Namespace is the Consul namespace to resolve the service from instead of the current namespace. If diff --git a/control-plane/api/v1alpha1/servicerouter_types.go b/control-plane/api/v1alpha1/servicerouter_types.go index 34486289c6..48bcf065be 100644 --- a/control-plane/api/v1alpha1/servicerouter_types.go +++ b/control-plane/api/v1alpha1/servicerouter_types.go @@ -140,6 +140,9 @@ type ServiceRouteDestination struct { // This requires that either match.http.pathPrefix or match.http.pathExact // be configured on this route. PrefixRewrite string `json:"prefixRewrite,omitempty"` + // IdleTimeout is total amount of time permitted + // for the request stream to be idle. + IdleTimeout metav1.Duration `json:"idleTimeout,omitempty"` // RequestTimeout is the total amount of time permitted for the entire // downstream request (and retries) to be processed. IdleTimeout metav1.Duration `json:"idleTimeout,omitempty"` @@ -340,6 +343,7 @@ func (in *ServiceRouteDestination) toConsul() *capi.ServiceRouteDestination { Namespace: in.Namespace, Partition: in.Partition, PrefixRewrite: in.PrefixRewrite, + IdleTimeout: in.IdleTimeout.Duration, RequestTimeout: in.RequestTimeout.Duration, NumRetries: in.NumRetries, RetryOnConnectFailure: in.RetryOnConnectFailure, diff --git a/control-plane/api/v1alpha1/servicerouter_types_test.go b/control-plane/api/v1alpha1/servicerouter_types_test.go index d0919871ce..653bdc26c1 100644 --- a/control-plane/api/v1alpha1/servicerouter_types_test.go +++ b/control-plane/api/v1alpha1/servicerouter_types_test.go @@ -82,6 +82,7 @@ func TestServiceRouter_MatchesConsul(t *testing.T) { ServiceSubset: "serviceSubset", Namespace: "namespace", PrefixRewrite: "prefixRewrite", + IdleTimeout: metav1.Duration{Duration: 1 * time.Second}, RequestTimeout: metav1.Duration{Duration: 1 * time.Second}, NumRetries: 1, RetryOnConnectFailure: true, @@ -158,6 +159,7 @@ func TestServiceRouter_MatchesConsul(t *testing.T) { ServiceSubset: "serviceSubset", Namespace: "namespace", PrefixRewrite: "prefixRewrite", + IdleTimeout: 1 * time.Second, RequestTimeout: 1 * time.Second, NumRetries: 1, RetryOnConnectFailure: true, @@ -283,6 +285,7 @@ func TestServiceRouter_ToConsul(t *testing.T) { ServiceSubset: "serviceSubset", Namespace: "namespace", PrefixRewrite: "prefixRewrite", + IdleTimeout: metav1.Duration{Duration: 1 * time.Second}, RequestTimeout: metav1.Duration{Duration: 1 * time.Second}, NumRetries: 1, RetryOnConnectFailure: true, @@ -359,6 +362,7 @@ func TestServiceRouter_ToConsul(t *testing.T) { ServiceSubset: "serviceSubset", Namespace: "namespace", PrefixRewrite: "prefixRewrite", + IdleTimeout: 1 * time.Second, RequestTimeout: 1 * time.Second, NumRetries: 1, RetryOnConnectFailure: true, @@ -717,7 +721,7 @@ func TestServiceRouter_Validate(t *testing.T) { }, namespacesEnabled: false, expectedErrMsgs: []string{ - `servicerouter.consul.hashicorp.com "foo" is invalid: spec.routes[0]: Invalid value: "{\"match\":{\"http\":{}},\"destination\":{\"prefixRewrite\":\"prefixRewrite\",\"requestTimeout\":\"0s\"}}": destination.prefixRewrite requires that either match.http.pathPrefix or match.http.pathExact be configured on this route`, + `servicerouter.consul.hashicorp.com "foo" is invalid: spec.routes[0]: Invalid value: "{\"match\":{\"http\":{}},\"destination\":{\"prefixRewrite\":\"prefixRewrite\",\"idleTimeout\":\"0s\",\"requestTimeout\":\"0s\"}}": destination.prefixRewrite requires that either match.http.pathPrefix or match.http.pathExact be configured on this route`, }, }, "namespaces disabled: single destination namespace specified": { diff --git a/control-plane/api/v1alpha1/zz_generated.deepcopy.go b/control-plane/api/v1alpha1/zz_generated.deepcopy.go index cedd78a1e5..330526701c 100644 --- a/control-plane/api/v1alpha1/zz_generated.deepcopy.go +++ b/control-plane/api/v1alpha1/zz_generated.deepcopy.go @@ -1947,6 +1947,7 @@ func (in *ServiceRoute) DeepCopy() *ServiceRoute { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServiceRouteDestination) DeepCopyInto(out *ServiceRouteDestination) { *out = *in + out.IdleTimeout = in.IdleTimeout out.RequestTimeout = in.RequestTimeout if in.RetryOnStatusCodes != nil { in, out := &in.RetryOnStatusCodes, &out.RetryOnStatusCodes