Skip to content

Commit

Permalink
feat(translator): preserve route order in CTP
Browse files Browse the repository at this point in the history
Signed-off-by: Guy Daich <[email protected]>
  • Loading branch information
guydc committed Dec 20, 2024
1 parent ca2d80b commit 389b43d
Show file tree
Hide file tree
Showing 14 changed files with 876 additions and 17 deletions.
7 changes: 7 additions & 0 deletions api/v1alpha1/clienttrafficpolicy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ type ClientTrafficPolicySpec struct {
//
// +optional
HealthCheck *HealthCheckSettings `json:"healthCheck,omitempty"`
// PreserveRouteOrder determines if the order of matching for HTTPRoutes is determined by Gateway-API
// specification (https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteRule)
// or preserves the order defined by users in the HTTPRoute's HTTPRouteRule list.
// Default: False
//
// +optional
PreserveRouteOrder *bool `json:"preserveRouteOrder,omitempty"`
}

// HeaderSettings provides configuration options for headers on the listener.
Expand Down
5 changes: 5 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,13 @@ spec:
- UnescapeAndRedirect
type: string
type: object
preserveRouteOrder:
description: |-
PreserveRouteOrder determines if the order of matching for HTTPRoutes is determined by Gateway-API
specification (https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.HTTPRouteRule)
or preserves the order defined by users in the HTTPRoute's HTTPRouteRule list.
Default: False
type: boolean
targetRef:
description: |-
TargetRef is the name of the resource this policy is being attached to.
Expand Down
4 changes: 4 additions & 0 deletions internal/gatewayapi/clienttrafficpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,10 @@ func (t *Translator) translateClientTrafficPolicyForListener(policy *egv1a1.Clie
errs = errors.Join(errs, err)
}

if policy.Spec.PreserveRouteOrder != nil && *policy.Spec.PreserveRouteOrder {
httpIR.PreserverRouteOrder = true
}

// Early return if got any errors
if errs != nil {
return errs
Expand Down
7 changes: 7 additions & 0 deletions internal/gatewayapi/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package gatewayapi
import (
"fmt"
"net"
"sort"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -53,6 +54,12 @@ type RoutesTranslator interface {
func (t *Translator) ProcessHTTPRoutes(httpRoutes []*gwapiv1.HTTPRoute, gateways []*GatewayContext, resources *resource.Resources, xdsIR resource.XdsIRMap) []*HTTPRouteContext {
var relevantHTTPRoutes []*HTTPRouteContext

// always sort initially by creation time stamp. Later on, additional sorting based on matcher type and
// match length may occur.
sort.Slice(httpRoutes, func(i, j int) bool {
return httpRoutes[i].CreationTimestamp.Before(&(httpRoutes[j].CreationTimestamp))
})

for _, h := range httpRoutes {
if h == nil {
panic("received nil httproute")
Expand Down
6 changes: 4 additions & 2 deletions internal/gatewayapi/sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,10 @@ func (x XdsIRRoutes) Less(i, j int) bool {
func sortXdsIRMap(xdsIR resource.XdsIRMap) {
for _, irItem := range xdsIR {
for _, http := range irItem.HTTP {
// descending order
sort.Sort(sort.Reverse(XdsIRRoutes(http.Routes)))
if !http.PreserverRouteOrder {
// descending order
sort.Sort(sort.Reverse(XdsIRRoutes(http.Routes)))
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
clientTrafficPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
namespace: envoy-gateway
name: target-gateway-1
spec:
preserveRouteOrder: false
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
namespace: envoy-gateway
name: target-gateway-1-section-http-1
spec:
preserveRouteOrder: true
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: gateway-1
sectionName: http-preserve-order
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gateway-1
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http-preserve-order
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
- name: http-2
protocol: HTTP
port: 8080
allowedRoutes:
namespaces:
from: All
httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: default
name: httproute-1
spec:
parentRefs:
- namespace: envoy-gateway
name: gateway-1
rules:
- matches:
- path:
type: PathPrefix
value: "/"
backendRefs:
- name: service-1
port: 8080
- matches:
- path:
type: RegularExpression
value: "/regex/between/prefixes/*"
backendRefs:
- name: service-1
port: 8080
- matches:
- path:
type: PathPrefix
value: "/specific/prefix/after/less/specific"
backendRefs:
- name: service-1
port: 8080
- matches:
- path:
type: Exact
value: "/exact"
backendRefs:
- name: service-1
port: 8080
- matches:
- path:
type: RegularExpression
value: "/regex/between/exacts/*"
backendRefs:
- name: service-1
port: 8080
- matches:
- path:
type: Exact
value: "/specific/exact/after/less/specific"
backendRefs:
- name: service-1
port: 8080
- matches:
- path:
type: RegularExpression
value: "/short/regex/*"
backendRefs:
- name: service-1
port: 8080
- matches:
- path:
type: RegularExpression
value: "/longer/regex/after/shorter/regex/*"
backendRefs:
- name: service-1
port: 8080
Loading

0 comments on commit 389b43d

Please sign in to comment.