From 01f9503585a9e7d34f05f2702a8bb731c8e5672c Mon Sep 17 00:00:00 2001 From: Rudrakh Panigrahi Date: Mon, 21 Oct 2024 09:15:25 +0530 Subject: [PATCH] add docs for ratelimit invert match headers --- api/v1alpha1/ratelimit_types.go | 1 - .../latest/tasks/traffic/global-rate-limit.md | 52 ++++- .../latest/tasks/traffic/local-rate-limit.md | 182 ++++++++++++++++++ 3 files changed, 230 insertions(+), 5 deletions(-) diff --git a/api/v1alpha1/ratelimit_types.go b/api/v1alpha1/ratelimit_types.go index d7a43751077..72382d699f1 100644 --- a/api/v1alpha1/ratelimit_types.go +++ b/api/v1alpha1/ratelimit_types.go @@ -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"` } diff --git a/site/content/en/latest/tasks/traffic/global-rate-limit.md b/site/content/en/latest/tasks/traffic/global-rate-limit.md index 15cc462dbf4..47eac33bc3e 100644 --- a/site/content/en/latest/tasks/traffic/global-rate-limit.md +++ b/site/content/en/latest/tasks/traffic/global-rate-limit.md @@ -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" %}} @@ -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 @@ -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. @@ -809,7 +853,7 @@ spec: targetRefs: - group: gateway.networking.k8s.io kind: HTTPRoute - name: http-ratelimit + name: http-ratelimit rateLimit: type: Global global: @@ -858,7 +902,7 @@ spec: targetRefs: - group: gateway.networking.k8s.io kind: HTTPRoute - name: http-ratelimit + name: http-ratelimit rateLimit: type: Global global: diff --git a/site/content/en/latest/tasks/traffic/local-rate-limit.md b/site/content/en/latest/tasks/traffic/local-rate-limit.md index 62e369044a5..b4e26e484be 100644 --- a/site/content/en/latest/tasks/traffic/local-rate-limit.md +++ b/site/content/en/latest/tasks/traffic/local-rate-limit.md @@ -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 <}} + +### HTTPRoute + +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + +```shell +cat <}} + +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.