Skip to content

Commit

Permalink
Implement BTP Timeout API
Browse files Browse the repository at this point in the history
Signed-off-by: Guy Daich <[email protected]>
  • Loading branch information
guydc committed Jan 16, 2024
1 parent 9081d82 commit 8485b19
Show file tree
Hide file tree
Showing 15 changed files with 921 additions and 20 deletions.
76 changes: 71 additions & 5 deletions internal/gatewayapi/backendtrafficpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"net"
"sort"
"strings"
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
Expand Down Expand Up @@ -248,6 +249,7 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
hc *ir.HealthCheck
cb *ir.CircuitBreaker
fi *ir.FaultInjection
to *ir.Timeout
)

// Build IR
Expand All @@ -266,6 +268,9 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
if policy.Spec.CircuitBreaker != nil {
cb = t.buildCircuitBreaker(policy)
}
if policy.Spec.Timeout != nil {
to = t.buildTimeout(policy)
}

if policy.Spec.FaultInjection != nil {
fi = t.buildFaultInjection(policy)
Expand All @@ -283,6 +288,7 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen
r.HealthCheck = hc
r.CircuitBreaker = cb
r.FaultInjection = fi
r.BackendTimeout = to
}
}
}
Expand All @@ -298,6 +304,7 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back
hc *ir.HealthCheck
cb *ir.CircuitBreaker
fi *ir.FaultInjection
ct *ir.Timeout
)

// Build IR
Expand All @@ -319,6 +326,9 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back
if policy.Spec.FaultInjection != nil {
fi = t.buildFaultInjection(policy)
}
if policy.Spec.Timeout != nil {
ct = t.buildTimeout(policy)
}

// Apply IR to all the routes within the specific Gateway
// If the feature is already set, then skip it, since it must be have
Expand Down Expand Up @@ -348,6 +358,9 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back
if r.FaultInjection == nil {
r.FaultInjection = fi
}
if r.BackendTimeout == nil {
r.BackendTimeout = ct
}
}

}
Expand Down Expand Up @@ -776,7 +789,7 @@ func (t *Translator) buildCircuitBreaker(policy *egv1a1.BackendTrafficPolicy) *i
if ui32, ok := int64ToUint32(*pcb.MaxConnections); ok {
cb.MaxConnections = &ui32
} else {
setCircuitBreakerPolicyErrorCondition(policy, fmt.Sprintf("invalid MaxConnections value %d", *pcb.MaxConnections))
SetBackendTrafficPolicyTranslationErrorCondition(policy, "Circuit Breaker", fmt.Sprintf("invalid MaxConnections value %d", *pcb.MaxConnections))
return nil
}
}
Expand All @@ -785,7 +798,7 @@ func (t *Translator) buildCircuitBreaker(policy *egv1a1.BackendTrafficPolicy) *i
if ui32, ok := int64ToUint32(*pcb.MaxParallelRequests); ok {
cb.MaxParallelRequests = &ui32
} else {
setCircuitBreakerPolicyErrorCondition(policy, fmt.Sprintf("invalid MaxParallelRequests value %d", *pcb.MaxParallelRequests))
SetBackendTrafficPolicyTranslationErrorCondition(policy, "Circuit Breaker", fmt.Sprintf("invalid MaxParallelRequests value %d", *pcb.MaxParallelRequests))

Check warning on line 801 in internal/gatewayapi/backendtrafficpolicy.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/backendtrafficpolicy.go#L801

Added line #L801 was not covered by tests
return nil
}
}
Expand All @@ -794,7 +807,7 @@ func (t *Translator) buildCircuitBreaker(policy *egv1a1.BackendTrafficPolicy) *i
if ui32, ok := int64ToUint32(*pcb.MaxPendingRequests); ok {
cb.MaxPendingRequests = &ui32
} else {
setCircuitBreakerPolicyErrorCondition(policy, fmt.Sprintf("invalid MaxPendingRequests value %d", *pcb.MaxPendingRequests))
SetBackendTrafficPolicyTranslationErrorCondition(policy, "Circuit Breaker", fmt.Sprintf("invalid MaxPendingRequests value %d", *pcb.MaxPendingRequests))

Check warning on line 810 in internal/gatewayapi/backendtrafficpolicy.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/backendtrafficpolicy.go#L810

Added line #L810 was not covered by tests
return nil
}
}
Expand All @@ -803,8 +816,61 @@ func (t *Translator) buildCircuitBreaker(policy *egv1a1.BackendTrafficPolicy) *i
return cb
}

func setCircuitBreakerPolicyErrorCondition(policy *egv1a1.BackendTrafficPolicy, errMsg string) {
message := fmt.Sprintf("Unable to translate Circuit Breaker: %s", errMsg)
func (t *Translator) buildTimeout(policy *egv1a1.BackendTrafficPolicy) *ir.Timeout {
var tto *ir.TCPTimeout
var hto *ir.HTTPTimeout

pto := policy.Spec.Timeout

if pto.TCP != nil && pto.TCP.ConnectTimeout != nil {
d, err := time.ParseDuration(string(*pto.TCP.ConnectTimeout))
if err != nil {
SetBackendTrafficPolicyTranslationErrorCondition(policy, "TCP Timeout", fmt.Sprintf("invalid ConnectTimeout value %s", *pto.TCP.ConnectTimeout))
return nil
}
tto = &ir.TCPTimeout{
ConnectTimeout: ptr.To(metav1.Duration{Duration: d}),
}
}

if pto.HTTP != nil {
var cit *metav1.Duration
var mcd *metav1.Duration

if pto.HTTP.ConnectionIdleTimeout != nil {
d, err := time.ParseDuration(string(*pto.HTTP.ConnectionIdleTimeout))
if err != nil {
SetBackendTrafficPolicyTranslationErrorCondition(policy, "HTTP Timeout", fmt.Sprintf("invalid ConnectionIdleTimeout value %s", *pto.HTTP.ConnectionIdleTimeout))
return nil
}

Check warning on line 845 in internal/gatewayapi/backendtrafficpolicy.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/backendtrafficpolicy.go#L843-L845

Added lines #L843 - L845 were not covered by tests
cit = ptr.To(metav1.Duration{Duration: d})
}

if pto.HTTP.MaxConnectionDuration != nil {
d, err := time.ParseDuration(string(*pto.HTTP.MaxConnectionDuration))
if err != nil {
SetBackendTrafficPolicyTranslationErrorCondition(policy, "HTTP Timeout", fmt.Sprintf("invalid MaxConnectionDuration value %s", *pto.HTTP.MaxConnectionDuration))
return nil
}

Check warning on line 854 in internal/gatewayapi/backendtrafficpolicy.go

View check run for this annotation

Codecov / codecov/patch

internal/gatewayapi/backendtrafficpolicy.go#L852-L854

Added lines #L852 - L854 were not covered by tests
mcd = ptr.To(metav1.Duration{Duration: d})
}

hto = &ir.HTTPTimeout{
ConnectionIdleTimeout: cit,
MaxConnectionDuration: mcd,
}

}

return &ir.Timeout{
TCP: tto,
HTTP: hto,
}

}

func SetBackendTrafficPolicyTranslationErrorCondition(policy *egv1a1.BackendTrafficPolicy, field, errMsg string) {
message := fmt.Sprintf("Unable to translate %s: %s", field, errMsg)
status.SetBackendTrafficPolicyCondition(policy,
gwv1a2.PolicyConditionAccepted,
metav1.ConditionFalse,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
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
grpcRoutes:
- apiVersion: gateway.networking.k8s.io/v1alpha2
kind: GRPCRoute
metadata:
namespace: default
name: grpcroute-1
spec:
parentRefs:
- namespace: envoy-gateway
name: gateway-1
sectionName: http
rules:
- backendRefs:
- name: service-1
port: 8080
backendTrafficPolicies:
- 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
namespace: envoy-gateway
timeout:
tcp:
connectTimeout: 20kib
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
backendTrafficPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
creationTimestamp: null
name: policy-for-gateway
namespace: envoy-gateway
spec:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
namespace: envoy-gateway
timeout:
tcp:
connectTimeout: 20kib
status:
conditions:
- lastTransitionTime: null
message: 'Unable to translate TCP Timeout: invalid ConnectTimeout value 20kib'
reason: Invalid
status: "False"
type: Accepted
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
creationTimestamp: null
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
grpcRoutes:
- apiVersion: gateway.networking.k8s.io/v1alpha2
kind: GRPCRoute
metadata:
creationTimestamp: null
name: grpcroute-1
namespace: default
spec:
parentRefs:
- name: gateway-1
namespace: envoy-gateway
sectionName: http
rules:
- backendRefs:
- name: service-1
port: 8080
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
protocol: HTTP
servicePort: 80
metadata:
labels:
gateway.envoyproxy.io/owning-gateway-name: gateway-1
gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
name: envoy-gateway/gateway-1
xdsIR:
envoy-gateway/gateway-1:
accessLog:
text:
- path: /dev/stdout
http:
- address: 0.0.0.0
hostnames:
- '*'
isHTTP2: true
name: envoy-gateway/gateway-1/http
path:
escapedSlashesAction: UnescapeAndRedirect
mergeSlashes: true
port: 10080
routes:
- backendWeights:
invalid: 0
valid: 0
destination:
name: grpcroute/default/grpcroute-1/rule/0
settings:
- addressType: IP
endpoints:
- host: 7.7.7.7
port: 8080
protocol: GRPC
weight: 1
hostname: '*'
name: grpcroute/default/grpcroute-1/rule/0/match/-1/*
Loading

0 comments on commit 8485b19

Please sign in to comment.