Kuadrant / kuadrant-controller

Apache License 2.0
12 stars 7 forks source link

support gateways RLPs alone #198

Closed eguzki closed 2 years ago

eguzki commented 2 years ago

what

Fix #197

how

Before merging route and gateway level limits/{gateway actions}, add gateway level limits/{gateway actions} for the hostnames defined in the gateway (falling back to global wildcard * if not defined)

verification steps

Deploy the kuadrant controller

make local-setup
kubectl apply -f - <<EOF
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: HTTPRoute
metadata:
  name: toystore
  labels:
    app: toystore
spec:
  parentRefs:
    - name: istio-ingressgateway
      namespace: istio-system
  hostnames: ["*.toystore.com"]
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: "/toy"
          method: GET
        - path:
            type: PathPrefix
            value: "/free"
          method: GET
        - path:
            type: Exact
            value: "/admin/toy"
          method: POST
      backendRefs:
        - name: toystore
          port: 80
EOF

Check toystore HTTPRoute works and it is not rate limited.

GET /toy: no rate limiting

while :; do curl --write-out '%{http_code}' --silent --output /dev/null -H "Host: api.toystore.com" http://localhost:9080/toy | egrep --color "\b(429)\b|$"; sleep 1; done

POST /admin/toy: no rate limiting

while :; do curl --write-out '%{http_code}' --silent --output /dev/null -H "Host: api.toystore.com" -X POST http://localhost:9080/admin/toy | egrep --color "\b(429)\b|$"; sleep 1; done

Adding gateway level RLP

Policy Rate Limits
POST /* 2 reqs / 10 secs (0.2 rps) **
kubectl apply -f - <<EOF
---
apiVersion: apim.kuadrant.io/v1alpha1
kind: RateLimitPolicy
metadata:
  name: istio-gw
  namespace: istio-system
spec:
  targetRef:
    group: gateway.networking.k8s.io
    kind: Gateway
    name: istio-ingressgateway
  rateLimits:
    - rules:
      - methods: ["POST"]
      configurations:
        - actions:
            - generic_key:
                descriptor_key: expensive_op
                descriptor_value: "1"
      limits:
        - conditions: ["expensive_op == '1'"]
          maxValue: 2
          seconds: 10
          variables: []
EOF

Validating the gateway level rate limit policy:

GET /toy : no rate limiting

while :; do curl --write-out '%{http_code}' --silent --output /dev/null -H "Host: api.toystore.com" http://localhost:9080/toy | egrep --color "\b(429)\b|$"; sleep 1; done

POST /admin/toy: expected to be rate limited @ 2 reqs / 10 secs (0.2 rps)

while :; do curl --write-out '%{http_code}' --silent --output /dev/null -H "Host: api.toystore.com" -X POST http://localhost:9080/admin/toy | egrep --color "\b(429)\b|$"; sleep 1; done