Description
Describe the bug
In the Gateway 0.7.1 release, the HTTPRoute matching precedence order was changed, giving "method" higher precedence than headers and query params.
This change makes our matching precedence logic incorrect.
To Reproduce
Steps to reproduce the behavior:
- Deploy NKG
- Create the default http gateway
- Create this cafe app:
apiVersion: apps/v1
kind: Deployment
metadata:
name: coffee-method
spec:
replicas: 1
selector:
matchLabels:
app: coffee-method
template:
metadata:
labels:
app: coffee-method
spec:
containers:
- name: coffee-method
image: nginxdemos/nginx-hello:plain-text
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: coffee-method
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: coffee-method
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: coffee-headers
spec:
replicas: 1
selector:
matchLabels:
app: coffee-headers
template:
metadata:
labels:
app: coffee-headers
spec:
containers:
- name: coffee-headers
image: nginxdemos/nginx-hello:plain-text
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: coffee-headers
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: coffee-headers
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: coffee-params
spec:
replicas: 1
selector:
matchLabels:
app: coffee-params
template:
metadata:
labels:
app: coffee-params
spec:
containers:
- name: coffee-params
image: nginxdemos/nginx-hello:plain-text
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: coffee-params
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: coffee-params
and this HTTPRoute:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: coffee
spec:
parentRefs:
- name: gateway
hostnames:
- "cafe.example.com"
rules:
- matches: # /coffee/ -X POST -H "version:v2" or curl /coffee\?TEST=v2 -X POST -H "version:v2"
- path:
type: PathPrefix
value: /coffee
method: POST
backendRefs:
- name: coffee-method
port: 80
- matches: # /coffee/\?TEST=v2 -H "version:v2"
- path:
type: PathPrefix
value: /coffee
headers:
- name: version
value: v2
backendRefs:
- name: coffee-headers
port: 80
- matches: # /coffee/\?TEST=v2
- path:
type: PathPrefix
value: /coffee
queryParams:
- name: TEST
value: v2
backendRefs:
- name: coffee-params
port: 80
Then execute the following curl command:
curl --resolve cafe.example.com:$GW_PORT:$GW_IP http://cafe.example.com:$GW_PORT/coffee/\?TEST=v2 -H "version:v2" -X POST
You will see a response from coffee-headers
, but the response should be from coffee-method
.
Note: All the matches in the HTTPRoute have a comment with the requests that should match.
Expected behavior
When a request satisfies multiple matches, the match should be selected according to the criteria in the spec: https://github.com/kubernetes-sigs/gateway-api/blob/ab03a594e7db13b8d2579929b204d8d10990fd2b/apis/v1beta1/httproute_types.go#L158
Your environment
- Edge (main)