Skip to content

Commit

Permalink
add docs for ratelimit invert match headers
Browse files Browse the repository at this point in the history
  • Loading branch information
rudrakhp committed Oct 21, 2024
1 parent 26ec49a commit 01f9503
Show file tree
Hide file tree
Showing 3 changed files with 230 additions and 5 deletions.
1 change: 0 additions & 1 deletion api/v1alpha1/ratelimit_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ type HeaderMatch struct { // TODO: zhaohuabing this type could be replaced with
//
// +optional
// +kubebuilder:default=false
// +notImplementedHide
Invert *bool `json:"invert,omitempty"`
}

Expand Down
52 changes: 48 additions & 4 deletions site/content/en/latest/tasks/traffic/global-rate-limit.md
Original file line number Diff line number Diff line change
Expand Up @@ -433,11 +433,11 @@ server: envoy
```

## Rate Limit Distinct Users
## Rate Limit Distinct Users Except Admin

Here is an example of a rate limit implemented by the application developer to limit distinct users who can be differentiated based on the
value in the `x-user-id` header. Here, user `one` (recognised from the traffic flow using the header `x-user-id` and value `one`) will be rate limited at 3 requests/hour
and so will user `two` (recognised from the traffic flow using the header `x-user-id` and value `two`).
and so will user `two` (recognised from the traffic flow using the header `x-user-id` and value `two`). But if `x-user-id` is `admin`, it will not be rate limited even beyond 3 requests/hour.

{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
Expand All @@ -461,6 +461,9 @@ spec:
- headers:
- type: Distinct
name: x-user-id
- name: x-user-id
value: admin
invert: true
limit:
requests: 3
unit: Hour
Expand Down Expand Up @@ -636,6 +639,47 @@ transfer-encoding: chunked
```

But when the value for header `x-user-id` is set to `admin` and 4 requests are sent, all 4 of them should respond with 200 OK.

```shell
for i in {1..4}; do curl -I --header "Host: ratelimit.example" --header "x-user-id: admin" http://${GATEWAY_HOST}/get ; sleep 1; done
```

```console
HTTP/1.1 200 OK
content-type: application/json
x-content-type-options: nosniff
date: Wed, 08 Feb 2023 02:33:31 GMT
content-length: 460
x-envoy-upstream-service-time: 4
server: envoy
HTTP/1.1 200 OK
content-type: application/json
x-content-type-options: nosniff
date: Wed, 08 Feb 2023 02:33:32 GMT
content-length: 460
x-envoy-upstream-service-time: 2
server: envoy
HTTP/1.1 200 OK
content-type: application/json
x-content-type-options: nosniff
date: Wed, 08 Feb 2023 02:33:33 GMT
content-length: 460
x-envoy-upstream-service-time: 0
server: envoy
HTTP/1.1 200 OK
content-type: application/json
x-content-type-options: nosniff
date: Wed, 08 Feb 2023 02:33:33 GMT
content-length: 460
x-envoy-upstream-service-time: 0
server: envoy
```

## Rate Limit All Requests

This example shows you how to rate limit all requests matching the HTTPRoute rule at 3 requests/Hour by leaving the `clientSelectors` field unset.
Expand Down Expand Up @@ -809,7 +853,7 @@ spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
name: http-ratelimit
rateLimit:
type: Global
global:
Expand Down Expand Up @@ -858,7 +902,7 @@ spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
name: http-ratelimit
rateLimit:
type: Global
global:
Expand Down
182 changes: 182 additions & 0 deletions site/content/en/latest/tasks/traffic/local-rate-limit.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,188 @@ server: envoy

```

## Rate Limit Specific User Unless with Admin Role

Here is an example of a rate limit implemented by the application developer to limit a specific user by matching on a custom `x-user-id` header
with a value set to `one`. But the user must not be limited if logging in with admin role determined by custom header `x-user-role` set to `admin`.

{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}

```shell
cat <<EOF | kubectl apply -f -
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
type: Local
local:
rules:
- clientSelectors:
- headers:
- name: x-user-id
value: one
- name: x-user-role
value: admin
invert: true
limit:
requests: 3
unit: Hour
EOF
```

{{% /tab %}}
{{% tab header="Apply from file" %}}
Save and apply the following resource to your cluster:

```yaml
---
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: BackendTrafficPolicy
metadata:
name: policy-httproute
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: HTTPRoute
name: http-ratelimit
rateLimit:
type: Local
local:
rules:
- clientSelectors:
- headers:
- name: x-user-id
value: one
- name: x-user-role
value: admin
invert: true
limit:
requests: 3
unit: Hour
```
{{% /tab %}}
{{< /tabpane >}}
### HTTPRoute
{{< tabpane text=true >}}
{{% tab header="Apply from stdin" %}}
```shell
cat <<EOF | kubectl apply -f -
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-ratelimit
spec:
parentRefs:
- name: eg
hostnames:
- ratelimit.example
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ""
kind: Service
name: backend
port: 3000
EOF
```

{{% /tab %}}
{{% tab header="Apply from file" %}}
Save and apply the following resource to your cluster:

```yaml
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-ratelimit
spec:
parentRefs:
- name: eg
hostnames:
- ratelimit.example
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- group: ""
kind: Service
name: backend
port: 3000
```
{{% /tab %}}
{{< /tabpane >}}
The HTTPRoute status should indicate that it has been accepted and is bound to the example Gateway.
```shell
kubectl get httproute/http-ratelimit -o yaml
```

Get the Gateway's address:

```shell
export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')
```

Let's query `ratelimit.example/get` 4 times. We should receive a `200` response from the example Gateway for all the 4 requests, unlike previous example where the last request was rate limited.

```shell
for i in {1..4}; do curl -I --header "Host: ratelimit.example" --header "x-user-id: one" --header "x-user-role: admin" http://${GATEWAY_HOST}/get ; sleep 1; done
```

```console
HTTP/1.1 200 OK
content-type: application/json
x-content-type-options: nosniff
date: Wed, 08 Feb 2023 02:33:31 GMT
content-length: 460
x-envoy-upstream-service-time: 4
server: envoy

HTTP/1.1 200 OK
content-type: application/json
x-content-type-options: nosniff
date: Wed, 08 Feb 2023 02:33:32 GMT
content-length: 460
x-envoy-upstream-service-time: 2
server: envoy

HTTP/1.1 200 OK
content-type: application/json
x-content-type-options: nosniff
date: Wed, 08 Feb 2023 02:33:33 GMT
content-length: 460
x-envoy-upstream-service-time: 0
server: envoy

HTTP/1.1 200 OK
content-type: application/json
x-content-type-options: nosniff
date: Wed, 08 Feb 2023 02:33:33 GMT
content-length: 460
x-envoy-upstream-service-time: 0
server: envoy

```

## Rate Limit All Requests

This example shows you how to rate limit all requests matching the HTTPRoute rule at 3 requests/Hour by leaving the `clientSelectors` field unset.
Expand Down

0 comments on commit 01f9503

Please sign in to comment.