Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions internal/gatewayapi/sort.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package gatewayapi

import (
"sort"

"github.com/envoyproxy/gateway/internal/ir"
)

type XdsIRRoutes []*ir.HTTPRoute

func (x XdsIRRoutes) Len() int { return len(x) }
func (x XdsIRRoutes) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x XdsIRRoutes) Less(i, j int) bool {
// 1. Sort based on characters in a matching path.
pCountI := pathMatchCount(x[i].PathMatch)
pCountJ := pathMatchCount(x[j].PathMatch)
if pCountI < pCountJ {
return true
}
if pCountI > pCountJ {
return false
}
// Equal case

// 2. Sort based on the number of Header matches.
hCountI := len(x[i].HeaderMatches)
hCountJ := len(x[j].HeaderMatches)
if hCountI < hCountJ {
return true
}
if hCountI > hCountJ {
return false
}
// Equal case

// 3. Sort based on the number of Query param matches.
qCountI := len(x[i].QueryParamMatches)
qCountJ := len(x[j].QueryParamMatches)
return qCountI < qCountJ
}

// sortXdsIR sorts the xdsIR based on the match precedence
// defined in the Gateway API spec.
// https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.HTTPRouteRule
func sortXdsIRMap(xdsIR XdsIRMap) {
for _, ir := range xdsIR {
ir := ir
sort.SliceStable(ir.HTTP, func(i, j int) bool { return ir.HTTP[i].Name < ir.HTTP[j].Name })
for _, http := range ir.HTTP {
// descending order
sort.Sort(sort.Reverse(XdsIRRoutes(http.Routes)))
}
}
}

func pathMatchCount(pathMatch *ir.StringMatch) int {
if pathMatch != nil {
if pathMatch.Exact != nil {
return len(*pathMatch.Exact)
}
if pathMatch.Prefix != nil {
return len(*pathMatch.Prefix)
}
if pathMatch.SafeRegex != nil {
return len(*pathMatch.SafeRegex)
}
}
return 0
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
gateways:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gateway-1
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same
httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
namespace: envoy-gateway
name: httproute-1
spec:
parentRefs:
- namespace: envoy-gateway
name: gateway-1
rules:
- matches:
- path:
value: "/"
backendRefs:
- name: service-1
port: 8080
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
namespace: envoy-gateway
name: httproute-2
spec:
parentRefs:
- namespace: envoy-gateway
name: gateway-1
hostnames:
- example.com
rules:
- matches:
- path:
value: "/v1/example"
queryParams:
- name: "debug"
value: "yes"
backendRefs:
- name: service-1
port: 8080
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
namespace: envoy-gateway
name: httproute-3
spec:
parentRefs:
- namespace: envoy-gateway
name: gateway-1
hostnames:
- example.com
rules:
- matches:
- path:
value: "/v1/example"
backendRefs:
- name: service-2
port: 8080
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
namespace: envoy-gateway
name: httproute-4
spec:
parentRefs:
- namespace: envoy-gateway
name: gateway-1
hostnames:
- example.net
rules:
- matches:
- path:
value: "/v1/status"
headers:
- name: "version"
value: "one"
backendRefs:
- name: service-1
port: 8080
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
namespace: envoy-gateway
name: httproute-5
spec:
parentRefs:
- namespace: envoy-gateway
name: gateway-1
hostnames:
- example.net
rules:
- matches:
- path:
value: "/v1/status"
backendRefs:
- name: service-2
port: 8080
services:
- apiVersion: v1
kind: Service
metadata:
namespace: envoy-gateway
name: service-1
spec:
clusterIP: 7.7.7.7
ports:
- port: 8080
- apiVersion: v1
kind: Service
metadata:
namespace: envoy-gateway
name: service-2
spec:
clusterIP: 8.8.8.8
ports:
- port: 8080
Loading