Skip to content

Commit

Permalink
fix: Gateway-target BTP ignored when route timeout defined (#4860)
Browse files Browse the repository at this point in the history
* fix: Gateway-target BTP ignored when route timeout defined

Signed-off-by: Guy Daich <[email protected]>

* fix gen, add note

Signed-off-by: Guy Daich <[email protected]>

---------

Signed-off-by: Guy Daich <[email protected]>
  • Loading branch information
guydc authored Dec 11, 2024
1 parent 0898544 commit e6fce34
Show file tree
Hide file tree
Showing 18 changed files with 391 additions and 91 deletions.
9 changes: 4 additions & 5 deletions internal/gatewayapi/backendtrafficpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(
if policy.Spec.Retry != nil {
rt = buildRetry(policy.Spec.Retry)
}
if to, err = buildClusterSettingsTimeout(policy.Spec.ClusterSettings, nil); err != nil {
if to, err = buildClusterSettingsTimeout(policy.Spec.ClusterSettings); err != nil {
err = perr.WithMessage(err, "Timeout")
errs = errors.Join(errs, err)
}
Expand Down Expand Up @@ -399,8 +399,7 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(
continue
}

// Some timeout setting originate from the route.
if localTo, err := buildClusterSettingsTimeout(policy.Spec.ClusterSettings, r.Traffic); err == nil {
if localTo, err := buildClusterSettingsTimeout(policy.Spec.ClusterSettings); err == nil {
to = localTo
}

Expand Down Expand Up @@ -484,7 +483,7 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(
if policy.Spec.Retry != nil {
rt = buildRetry(policy.Spec.Retry)
}
if ct, err = buildClusterSettingsTimeout(policy.Spec.ClusterSettings, nil); err != nil {
if ct, err = buildClusterSettingsTimeout(policy.Spec.ClusterSettings); err != nil {
err = perr.WithMessage(err, "Timeout")
errs = errors.Join(errs, err)
}
Expand Down Expand Up @@ -585,7 +584,7 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(
// Update the Host field in HealthCheck, now that we have access to the Route Hostname.
r.Traffic.HealthCheck.SetHTTPHostIfAbsent(r.Hostname)

if ct, err = buildClusterSettingsTimeout(policy.Spec.ClusterSettings, r.Traffic); err == nil {
if ct, err = buildClusterSettingsTimeout(policy.Spec.ClusterSettings); err == nil {
r.Traffic.Timeout = ct
}

Expand Down
40 changes: 3 additions & 37 deletions internal/gatewayapi/clustersettings.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func translateTrafficFeatures(policy *egv1a1.ClusterSettings) (*ir.TrafficFeatur
}
ret := &ir.TrafficFeatures{}

if timeout, err := buildClusterSettingsTimeout(*policy, nil); err != nil {
if timeout, err := buildClusterSettingsTimeout(*policy); err != nil {
return nil, err
} else {
ret.Timeout = timeout
Expand Down Expand Up @@ -83,14 +83,11 @@ func translateTrafficFeatures(policy *egv1a1.ClusterSettings) (*ir.TrafficFeatur
return ret, nil
}

func buildClusterSettingsTimeout(policy egv1a1.ClusterSettings, routeTrafficFeatures *ir.TrafficFeatures) (*ir.Timeout, error) {
func buildClusterSettingsTimeout(policy egv1a1.ClusterSettings) (*ir.Timeout, error) {
if policy.Timeout == nil {
if routeTrafficFeatures != nil {
// Don't lose any existing timeout definitions.
return mergeTimeoutSettings(nil, routeTrafficFeatures.Timeout), nil
}
return nil, nil
}

var (
errs error
to = &ir.Timeout{}
Expand Down Expand Up @@ -146,40 +143,9 @@ func buildClusterSettingsTimeout(policy egv1a1.ClusterSettings, routeTrafficFeat
RequestTimeout: rt,
}
}

// The timeout from route's TrafficFeatures takes precedence over the timeout in BTP
if routeTrafficFeatures != nil {
to = mergeTimeoutSettings(routeTrafficFeatures.Timeout, to)
}

return to, errs
}

// merge secondary into main if both are not nil, otherwise return the
// one that is not nil. If both are nil, returns nil
func mergeTimeoutSettings(main, secondary *ir.Timeout) *ir.Timeout {
switch {
case main == nil && secondary == nil:
return nil
case main == nil:
return secondary.DeepCopy()
case secondary == nil:
return main
default: // Neither main nor secondary are nil here
if secondary.HTTP != nil {
setIfNil(&main.HTTP, &ir.HTTPTimeout{})
setIfNil(&main.HTTP.RequestTimeout, secondary.HTTP.RequestTimeout)
setIfNil(&main.HTTP.ConnectionIdleTimeout, secondary.HTTP.ConnectionIdleTimeout)
setIfNil(&main.HTTP.MaxConnectionDuration, secondary.HTTP.MaxConnectionDuration)
}
if secondary.TCP != nil {
setIfNil(&main.TCP, &ir.TCPTimeout{})
setIfNil(&main.TCP.ConnectTimeout, secondary.TCP.ConnectTimeout)
}
return main
}
}

func buildBackendConnection(policy egv1a1.ClusterSettings) (*ir.BackendConnection, error) {
if policy.Connection == nil {
return nil, nil
Expand Down
25 changes: 4 additions & 21 deletions internal/gatewayapi/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,14 +266,12 @@ func (t *Translator) processHTTPRouteRules(httpRoute *HTTPRouteContext, parentRe

func processRouteTimeout(irRoute *ir.HTTPRoute, rule gwapiv1.HTTPRouteRule) {
if rule.Timeouts != nil {
rto := &ir.Timeout{}

if rule.Timeouts.Request != nil {
d, err := time.ParseDuration(string(*rule.Timeouts.Request))
if err != nil {
d, _ = time.ParseDuration(HTTPRequestTimeout)
}
setRequestTimeout(rto, metav1.Duration{Duration: d})
irRoute.Timeout = ptr.To(metav1.Duration{Duration: d})
}

// Also set the IR Route Timeout to the backend request timeout
Expand All @@ -283,23 +281,8 @@ func processRouteTimeout(irRoute *ir.HTTPRoute, rule gwapiv1.HTTPRouteRule) {
if err != nil {
d, _ = time.ParseDuration(HTTPRequestTimeout)
}
setRequestTimeout(rto, metav1.Duration{Duration: d})
}

irRoute.Traffic = &ir.TrafficFeatures{
Timeout: rto,
}
}
}

func setRequestTimeout(irTimeout *ir.Timeout, d metav1.Duration) {
switch {
case irTimeout.HTTP == nil:
irTimeout.HTTP = &ir.HTTPTimeout{
RequestTimeout: ptr.To(d),
irRoute.Timeout = ptr.To(metav1.Duration{Duration: d})
}
default:
irTimeout.HTTP.RequestTimeout = ptr.To(d)
}
}

Expand Down Expand Up @@ -760,11 +743,11 @@ func (t *Translator) processHTTPRouteParentRefListener(route RouteContext, route
ExtensionRefs: routeRoute.ExtensionRefs,
IsHTTP2: routeRoute.IsHTTP2,
SessionPersistence: routeRoute.SessionPersistence,
Timeout: routeRoute.Timeout,
}
if routeRoute.Traffic != nil {
hostRoute.Traffic = &ir.TrafficFeatures{
Timeout: routeRoute.Traffic.Timeout,
Retry: routeRoute.Traffic.Retry,
Retry: routeRoute.Traffic.Retry,
}
}
perHostRoutes = append(perHostRoutes, hostRoute)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,27 @@ httpRoutes:
port: 8080
timeouts:
request: 130s
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: default
name: httproute-2
spec:
hostnames:
- gateway.envoyproxy.io
parentRefs:
- namespace: envoy-gateway
name: gateway-1
sectionName: http
rules:
- matches:
- path:
value: "/"
backendRefs:
- name: service-1
port: 8080
timeouts:
request: 130s
backendTrafficPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
Expand All @@ -47,4 +68,20 @@ backendTrafficPolicies:
kind: HTTPRoute
name: httproute-1
useClientProtocol: true

- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
namespace: envoy-gateway
name: policy-for-gateway
spec:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
useClientProtocol: true
loadBalancer:
type: ConsistentHash
consistentHash:
type: Cookie
cookie:
name: "test"
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,44 @@ backendTrafficPolicies:
status: "True"
type: Accepted
controllerName: gateway.envoyproxy.io/gatewayclass-controller
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
creationTimestamp: null
name: policy-for-gateway
namespace: envoy-gateway
spec:
loadBalancer:
consistentHash:
cookie:
name: test
type: Cookie
type: ConsistentHash
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
useClientProtocol: true
status:
ancestors:
- ancestorRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
namespace: envoy-gateway
conditions:
- lastTransitionTime: null
message: Policy has been accepted.
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: null
message: 'This policy is being overridden by other backendTrafficPolicies
for these routes: [default/httproute-1]'
reason: Overridden
status: "True"
type: Overridden
controllerName: gateway.envoyproxy.io/gatewayclass-controller
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
Expand All @@ -44,7 +82,7 @@ gateways:
protocol: HTTP
status:
listeners:
- attachedRoutes: 1
- attachedRoutes: 2
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
Expand Down Expand Up @@ -108,6 +146,46 @@ httpRoutes:
name: gateway-1
namespace: envoy-gateway
sectionName: http
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: httproute-2
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: /
timeouts:
request: 130s
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:
Expand Down Expand Up @@ -165,8 +243,33 @@ xdsIR:
distinct: false
name: ""
prefix: /
timeout: 2m10s
traffic: {}
useClientProtocol: true
- destination:
name: httproute/default/httproute-2/rule/0
settings:
- addressType: IP
endpoints:
- host: 7.7.7.7
port: 8080
protocol: HTTP
weight: 1
hostname: gateway.envoyproxy.io
isHTTP2: false
metadata:
kind: HTTPRoute
name: httproute-2
namespace: default
name: httproute/default/httproute-2/rule/0/match/0/gateway_envoyproxy_io
pathMatch:
distinct: false
name: ""
prefix: /
timeout: 2m10s
traffic:
timeout:
http:
requestTimeout: 2m10s
loadBalancer:
consistentHash:
cookie:
name: test
useClientProtocol: true
Original file line number Diff line number Diff line change
Expand Up @@ -336,11 +336,12 @@ xdsIR:
distinct: false
name: ""
prefix: /
timeout: 1s
traffic:
timeout:
http:
connectionIdleTimeout: 21s
maxConnectionDuration: 22s
requestTimeout: 1s
requestTimeout: 23s
tcp:
connectTimeout: 20s
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,4 @@ xdsIR:
distinct: false
name: ""
prefix: /
traffic:
timeout:
http:
requestTimeout: 1s
timeout: 1s
Original file line number Diff line number Diff line change
Expand Up @@ -332,10 +332,10 @@ xdsIR:
distinct: false
name: ""
prefix: /
timeout: 1s
traffic:
timeout:
http:
maxConnectionDuration: 22s
requestTimeout: 1s
tcp:
connectTimeout: 20s
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,4 @@ xdsIR:
distinct: false
name: ""
prefix: /
traffic:
timeout:
http:
requestTimeout: 1s
timeout: 1s
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,4 @@ xdsIR:
distinct: false
name: ""
prefix: /
traffic:
timeout:
http:
requestTimeout: 5s
timeout: 5s
Loading

0 comments on commit e6fce34

Please sign in to comment.