Header and query match
Use header and query matchers in a route delegation setup.
Configuration overview
In this guide you walk through a route delegation example where headers and query parameters are added as matchers to the parent and child HTTPRoute resources. A routing hierarchy can be created only if the child defines the same header and query matchers that the parent HTTPResource defines. You can optionally define additional header or query matchers on the child HTTPRoute resource.
For example, if the parent HTTPRoute resource specifies the header
header, the child must specify the same header matcher.
The following image illustrates the route delegation hierarchy:
parent
HTTPRoute:
- The parent HTTPRoute resource delegates traffic as follows:
/anything/team1
delegates traffic to the child HTTPRoute resourcechild-team1
in namespaceteam1
for requests that include theheader1; val1
request header and thequery1=val1
query parameter./anything/team2
delegates traffic to the child HTTPRoute resourcechild-team2
in namespaceteam2
for requests that include theheader2: val2
request header and thequery2=val2
query parameter.
child-team1
HTTPRoute:
- The child HTTPRoute resource
child-team1
matches incoming traffic for the/anything/team1/foo
prefix path if theheader1: val1
andheaderX: valX
request headers andquery1=val1
andqueryX=valX
query parameters are present in the request. Requests that match these conditions are forwarded to the httpbin app in namespaceteam1
. Note that the headers and query parameters are a superset of the headers and query parameters that the parent HTTPRoute resource defines.
child-team2
HTTPRoute:
- The child HTTPRoute resource
child-team2
matches incoming traffic for the/anything/team2/bar
exact prefix path if theheaderX: valX
request header andqueryX=valX
query parameter are present in the request. Because the child HTTPRoute resource does not specify the same header and query parameters that the parent HTTPRoute specified, the route is considered invalid.
Before you begin
-
Create the namespaces for
team1
andteam2
.kubectl create namespace team1 kubectl create namespace team2
-
Deploy the httpbin app into both namespaces.
kubectl -n team1 apply -f https://raw.githubusercontent.com/solo-io/gloo-mesh-use-cases/main/policy-demo/httpbin.yaml kubectl -n team2 apply -f https://raw.githubusercontent.com/solo-io/gloo-mesh-use-cases/main/policy-demo/httpbin.yaml
-
Verify that the httpbin apps are up and running.
kubectl get pods -n team1 kubectl get pods -n team2
Example output:
NAME READY STATUS RESTARTS AGE httpbin-f46cc8b9b-bzl9z 3/3 Running 0 7s NAME READY STATUS RESTARTS AGE httpbin-f46cc8b9b-nhtmg 3/3 Running 0 6s
Setup
-
Create the parent HTTPRoute resource that matches incoming traffic on the
delegation.example
domain. The HTTPRoute resource specifies two routes:- Route 1 matches on the following conditions. If these conditions are met, the routing decision is delegated to a child HTTPRoute resource in the
team1
namespace.- path prefix match on
/anything/team1
- exact header match on
header1=val1
- exact query parameter match on
query1=val1
- path prefix match on
- Route 2 matches on the following conditions. If these conditions are met, the routing decision is delegated to a child HTTPRoute resource in the
team2
namespace.- path prefix match on
/anything/team2
- exact header match on
header2=val2
- exact query parameter match on
query2=val2
- path prefix match on
kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: parent namespace: gloo-system spec: hostnames: - delegation.example parentRefs: - name: http rules: - matches: - path: type: PathPrefix value: /anything/team1 headers: - type: Exact name: header1 value: val1 queryParams: - type: Exact name: query1 value: val1 backendRefs: - group: gateway.networking.k8s.io kind: HTTPRoute name: "*" namespace: team1 - matches: - path: type: PathPrefix value: /anything/team2 headers: - type: Exact name: header2 value: val2 queryParams: - type: Exact name: query2 value: val2 backendRefs: - group: gateway.networking.k8s.io kind: HTTPRoute name: "*" namespace: team2 EOF
- Route 1 matches on the following conditions. If these conditions are met, the routing decision is delegated to a child HTTPRoute resource in the
-
Create the
child-team1
HTTPRoute resource in theteam1
namespace that matches traffic on the/anything/team1/foo
path prefix if theheader1=val1
andheaderX=valX
request headers and thequery1=val1
andqueryX=valX
query parameters are present in the request. Requests that meet these conditions are forwarded to the httpbin app in theteam1
namespace.kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: child-team1 namespace: team1 spec: rules: - matches: - path: type: PathPrefix value: /anything/team1/foo headers: - type: Exact name: header1 value: val1 - type: Exact name: headerX value: valX queryParams: - type: Exact name: query1 value: val1 - type: Exact name: queryX value: valX backendRefs: - name: httpbin port: 8000 EOF
-
Create the
child-team2
HTTPRoute resource in theteam2
namespace that matches traffic on the/anything/team2/bar
exact prefix if theheaderX=valX
request header andqueryX=valX
query parameter are present in the request. Requests that meets these conditions are forwarded to the httpbin app in theteam2
namespace.kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: child-team2 namespace: team2 spec: rules: - matches: - path: type: Exact value: /anything/team2/foo headers: - type: Exact name: headerX value: valX queryParams: - type: Exact name: queryX value: valX backendRefs: - name: httpbin port: 8000 EOF
-
Send a request to the
delegation.example
domain along the/anything/team1/foo
path with theheader1=val1
request header and thequery1=val1
query parameter. Verify that you get back a 404 HTTP response code. Although you included the header and query parameters that are defined on the parent HTTPRoute resource, the headers and query parameters that the child HTTPRoute resource matches on are missing in your request.curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo?query1=val1 \ -H "host: delegation.example:8080" -H "header1: val1"
curl -i localhost:8080/anything/team1/foo1?query1=val1 \ -H "host: delegation.example" -H "header1: val1"
Example output:
HTTP/1.1 404 Not Found date: Mon, 06 May 2024 16:01:48 GMT server: envoy transfer-encoding: chunked
-
Send another request to the
delegation.example
domain along the/anything/team1/foo
path. This time, you include all of the header and query parameters that the parent and child HTTPRoute resources defined. Verify that you get back a 200 HTTP response code.curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo?query1=val1&queryX=valX \ -H "host: delegation.example:8080" -H "header1: val1" -H "headerX: valX"
curl -i localhost:8080/anything/team1/foo1?query1=val1&queryX=valX \ -H "host: delegation.example:8080" -H "header1: val1" -H "headerX: valX"
Example output:
HTTP/1.1 200 OK access-control-allow-credentials: true access-control-allow-origin: * content-type: application/json; encoding=utf-8 date: Mon, 06 May 2024 15:59:32 GMT x-envoy-upstream-service-time: 0 server: envoy transfer-encoding: chunked
-
Send another request to the
delegation.example
domain along the/anything/team2/bar
path that is configured on thechild-team2
HTTPRoute resource and include all of the header and query parameters that are defined on the parent and child HTTPRoute resources. Verify that you get back a 404 HTTP response code. Because thechild-team2
HTTPRoute resource does not specify the same header and query matchers as the parent HTTPRoute resource, the routing configuration is considered invalid.curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team2/bar?queryX=valX&query2=val2 \ -H "host: delegation.example:8080" -H "headerX: valX" -H "header2: val2"
curl -i localhost:8080/anything/team2/bar?queryX=valX&query2=val2 \ -H "host: delegation.example:8080" -H "headerX: valX" -H "header2: val2"
Example output:
HTTP/1.1 404 Not Found date: Mon, 06 May 2024 16:01:48 GMT server: envoy transfer-encoding: chunked
Cleanup
You can remove the resources that you created in this guide.kubectl delete httproute parent -n gloo-system
kubectl delete httproute child-team1 -n team1
kubectl delete httproute child-team2 -n team2
kubectl delete -n team1 -f https://raw.githubusercontent.com/solo-io/gloo-mesh-use-cases/main/policy-demo/httpbin.yaml
kubectl delete -n team2 -f https://raw.githubusercontent.com/solo-io/gloo-mesh-use-cases/main/policy-demo/httpbin.yaml
kubectl delete namespaces team1 team2