Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change Limit defition to refelct v1beta3 #577

Merged
merged 2 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions testsuite/kuadrant/policy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
"""Contains Base class for policies"""

from dataclasses import dataclass

from testsuite.kubernetes import KubernetesObject
from testsuite.utils import check_condition


@dataclass
class CelPredicate:
"""Dataclass that references CEL predicate e.g. auth.identity.anonymous == 'true'"""

predicate: str


@dataclass
class CelExpression:
"""Dataclass that references CEL expression"""

expression: str
averevki marked this conversation as resolved.
Show resolved Hide resolved


def has_condition(condition_type, status="True", reason=None, message=None):
"""Returns function, that returns True if the Kubernetes object has a specific value"""

Expand Down
2 changes: 1 addition & 1 deletion testsuite/kuadrant/policy/authorization/sections.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ def add_success_dynamic(self, name: str, value: SUCCESS_RESPONSE, **common_featu
This section is for items wrapped as Envoy Dynamic Metadata.
"""

success_dynamic_metadata = self.section.setdefault("success", {}).setdefault("dynamicMetadata", {})
success_dynamic_metadata = self.section.setdefault("success", {}).setdefault("filters", {})
asdict_value = asdict(value)
add_common_features(asdict_value, **common_features)
success_dynamic_metadata.update({name: asdict_value})
Expand Down
14 changes: 6 additions & 8 deletions testsuite/kuadrant/policy/rate_limit.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@

import time
from dataclasses import dataclass
from typing import Iterable, Literal
from typing import Iterable

from testsuite.gateway import Referencable
from testsuite.kubernetes import modify
from testsuite.kubernetes.client import KubernetesClient
from testsuite.kuadrant.policy import Policy
from testsuite.kuadrant.policy.authorization import Rule
from testsuite.kuadrant.policy import Policy, CelPredicate, CelExpression
from testsuite.utils import asdict


Expand All @@ -17,8 +16,7 @@ class Limit:
"""Limit dataclass"""

limit: int
duration: int
unit: Literal["second", "minute", "day"] = "second"
window: str


class RateLimitPolicy(Policy):
Expand Down Expand Up @@ -47,8 +45,8 @@ def add_limit(
self,
name,
limits: Iterable[Limit],
when: Iterable[Rule] = None,
counters: list[str] = None,
when: list[CelPredicate] = None,
counters: list[CelExpression] = None,
):
"""Add another limit"""
limit: dict = {
Expand All @@ -57,7 +55,7 @@ def add_limit(
if when:
limit["when"] = [asdict(rule) for rule in when]
if counters:
limit["counters"] = counters
limit["counters"] = [asdict(rule) for rule in counters]

if self.spec_section is None:
self.spec_section = self.model.spec
Expand Down
2 changes: 1 addition & 1 deletion testsuite/tests/kuadrantctl/cli/test_simple_limit.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def oas(oas, blame, gateway, hostname, backend):
oas.add_top_level_route(gateway, hostname, blame("route"))
oas.add_backend_to_paths(backend)

oas["paths"]["/anything"]["get"]["x-kuadrant"] = {"rate_limit": {"rates": [asdict(Limit(3, 20))]}}
oas["paths"]["/anything"]["get"]["x-kuadrant"] = {"rate_limit": {"rates": [asdict(Limit(3, "20s"))]}}
return oas


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

pytestmark = [pytest.mark.kuadrant_only, pytest.mark.limitador]

LIMIT = Limit(3, 5)
LIMIT = Limit(3, "5s")


@pytest.fixture(scope="module")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ def test_rules_exclusivity_authorization(cluster, route, oidc_provider, module_l
def test_rules_exclusivity_rate_limit(cluster, route, module_label, blame):
"""Test that server will reject object with implicit and explicit defaults simultaneously in RateLimitPolicy"""
rate_limit = RateLimitPolicy.create_instance(cluster, blame("limit"), route, labels={"testRun": module_label})
rate_limit.defaults.add_limit("inside-defaults", [Limit(2, 5)])
rate_limit.add_limit("outside-defaults", [Limit(2, 5)])
rate_limit.defaults.add_limit("inside-defaults", [Limit(2, "5s")])
rate_limit.add_limit("outside-defaults", [Limit(2, "5s")])

with pytest.raises(OpenShiftPythonException, match="Implicit and explicit defaults are mutually exclusive"):
rate_limit.commit()
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def rate_limit(cluster, blame, module_label, route):
"""

policy = RateLimitPolicy.create_instance(cluster, blame("limit"), route, labels={"testRun": module_label})
policy.add_limit("basic", [Limit(5, 10)])
policy.add_limit("basic", [Limit(5, "10s")])
return policy


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def authorization2(request, route2, blame, openshift, label):
@pytest.fixture(scope="module")
def rate_limit(rate_limit):
"""Add limit to 1st RateLimitPolicy allowing 1 request per 10 minutes (a.k.a. '1rp10m' RateLimitPolicy)"""
rate_limit.add_limit("1rp10m", [Limit(1, 10)])
rate_limit.add_limit("1rp10m", [Limit(1, "10s")])
return rate_limit


Expand All @@ -38,7 +38,7 @@ def rate_limit2(request, route2, blame, openshift, label):
"""2nd RateLimitPolicy allowing 2 requests per 10 minutes (a.k.a. '2rp10m' RateLimitPolicy)"""
rlp = RateLimitPolicy.create_instance(openshift, blame("2rp10m"), route2, labels={"testRun": label})
request.addfinalizer(rlp.delete)
rlp.add_limit("2rp10m", [Limit(2, 10)])
rlp.add_limit("2rp10m", [Limit(2, "10s")])
rlp.commit()
rlp.wait_for_ready()
return rlp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def rate_limit2(request, gateway, blame, cluster, label):
"""2nd RateLimitPolicy object allowing 1 request per 10 minutes (a.k.a. '1rp10m')"""
rlp = RateLimitPolicy.create_instance(cluster, blame("2rp10m"), gateway, labels={"testRun": label})
request.addfinalizer(rlp.delete)
rlp.add_limit("1rp10m", [Limit(1, 600)])
rlp.add_limit("1rp10m", [Limit(1, "600s")])
rlp.commit()
rlp.wait_for_partial_enforced()
return rlp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
@pytest.fixture(scope="module")
def rate_limit(rate_limit):
"""Add limit to 1st RateLimitPolicy allowing 1 request per 10 minutes (a.k.a. '1rp10m' RateLimitPolicy)"""
rate_limit.add_limit("1rp10m", [Limit(1, 10)])
rate_limit.add_limit("1rp10m", [Limit(1, "10s")])
return rate_limit


Expand All @@ -23,7 +23,7 @@ def rate_limit2(request, route2, blame, cluster, label):
"""2nd RateLimitPolicy allowing 2 requests per 10 minutes (a.k.a. '2rp10m' RateLimitPolicy)"""
rlp = RateLimitPolicy.create_instance(cluster, blame("2rp10m"), route2, labels={"testRun": label})
request.addfinalizer(rlp.delete)
rlp.add_limit("2rp10m", [Limit(2, 10)])
rlp.add_limit("2rp10m", [Limit(2, "10s")])
rlp.commit()
rlp.wait_for_ready()
return rlp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import pytest

from testsuite.gateway import RouteMatch, PathMatch, MatchType, HTTPMethod
from testsuite.kuadrant.policy.authorization import Pattern
from testsuite.kuadrant.policy import CelPredicate
from testsuite.kuadrant.policy.rate_limit import Limit


Expand All @@ -28,8 +28,8 @@ def route(route, backend):
@pytest.fixture(scope="module")
def rate_limit(rate_limit):
"""Add limit to the policy"""
when = [Pattern("request.path", "eq", "/anything"), Pattern("request.method", "eq", "GET")]
rate_limit.add_limit("anything", [Limit(5, 10)], when=when)
when = [CelPredicate("request.path == '/anything'"), CelPredicate("request.method == 'GET'")]
rate_limit.add_limit("anything", [Limit(5, "10s")], when=when)
return rate_limit


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
@pytest.fixture(scope="module")
def rate_limit(rate_limit):
"""Add limit to the policy"""
rate_limit.add_limit("multiple", [Limit(3, 10)])
rate_limit.add_limit("multiple", [Limit(3, "10s")])
return rate_limit


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import pytest

from testsuite.kuadrant.policy.authorization import Pattern
from testsuite.kuadrant.policy import CelPredicate
from testsuite.kuadrant.policy.rate_limit import Limit


Expand All @@ -12,8 +12,7 @@
@pytest.fixture(scope="module")
def rate_limit(rate_limit):
"""Add limit to the policy"""
when = Pattern("request.method", "eq", "GET")
rate_limit.add_limit("test", [Limit(5, 10)], when=[when])
rate_limit.add_limit("test", [Limit(5, "10s")], when=[CelPredicate("request.method == 'GET'")])
return rate_limit


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import pytest

from testsuite.kuadrant.policy import CelPredicate
from testsuite.kuadrant.policy.rate_limit import Limit
from testsuite.kuadrant.policy.authorization import Pattern


pytestmark = [pytest.mark.kuadrant_only, pytest.mark.limitador]
Expand All @@ -12,9 +12,9 @@
@pytest.fixture(scope="module")
def rate_limit(rate_limit):
"""Add limit to the policy"""
when = Pattern("request.path", "eq", "/get")
rate_limit.add_limit("test1", [Limit(8, 10)], when=[when])
rate_limit.add_limit("test2", [Limit(3, 5)], when=[when])
when = CelPredicate("request.path == '/get'")
rate_limit.add_limit("test1", [Limit(8, "10s")], when=[when])
rate_limit.add_limit("test2", [Limit(3, "5s")], when=[when])
return rate_limit


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@

import pytest

from testsuite.kuadrant.policy import CelPredicate
from testsuite.kuadrant.policy.rate_limit import Limit
from testsuite.kuadrant.policy.authorization import Pattern

pytestmark = [pytest.mark.kuadrant_only, pytest.mark.limitador]


@pytest.fixture(scope="module")
def rate_limit(rate_limit):
"""Add limit to the policy"""
when = [Pattern("request.path", "eq", "/get")]
rate_limit.add_limit("multiple", [Limit(5, 10)], when=when)
rate_limit.add_limit("multiple", [Limit(5, "10s")], when=[CelPredicate("request.path == '/get'")])
return rate_limit


Expand Down
6 changes: 3 additions & 3 deletions testsuite/tests/singlecluster/limitador/test_basic_limit.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
@pytest.fixture(
scope="module",
params=[
pytest.param(Limit(2, 15), id="2 requests every 15 sec"),
pytest.param(Limit(5, 10), id="5 requests every 10 sec"),
pytest.param(Limit(3, 5), id="3 request every 5 sec"),
pytest.param(Limit(2, "15s"), id="2 requests every 15 sec"),
pytest.param(Limit(5, "10s"), id="5 requests every 10 sec"),
pytest.param(Limit(3, "5s"), id="3 request every 5 sec"),
],
)
def limit(request):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
@pytest.fixture(scope="module")
def rate_limit(rate_limit):
"""Add limit to the policy"""
rate_limit.add_limit("multiple", [Limit(5, 10)])
rate_limit.add_limit("multiple", [Limit(5, "10s")])
return rate_limit


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

pytestmark = [pytest.mark.kuadrant_only, pytest.mark.limitador]

GATEWAY_LIMIT = Limit(3, 5)
ROUTE_LIMIT = Limit(2, 5)
GATEWAY_LIMIT = Limit(3, "5s")
ROUTE_LIMIT = Limit(2, "5s")


@pytest.fixture(scope="module")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def authorization(authorization, oidc_provider):
@pytest.fixture(scope="module")
def rate_limit(rate_limit):
"""Add basic rate limiting rules in the overrides block"""
rate_limit.overrides.add_limit("override", [Limit(2, 5)])
rate_limit.overrides.add_limit("override", [Limit(2, "5s")])
return rate_limit


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ def test_rules_exclusivity_explicit_authorization(cluster, route, oidc_provider,
def test_rules_exclusivity_implicit_rate_limit(cluster, route, module_label, blame):
"""Test that server will reject a RateLimitPolicy with overrides and implicit defaults defined simultaneously"""
rate_limit = RateLimitPolicy.create_instance(cluster, blame("limit"), route, labels={"testRun": module_label})
rate_limit.overrides.add_limit("overrides", [Limit(2, 5)])
rate_limit.add_limit("implicit-defaults", [Limit(2, 5)])
rate_limit.overrides.add_limit("overrides", [Limit(2, "5s")])
rate_limit.add_limit("implicit-defaults", [Limit(2, "5s")])

with pytest.raises(OpenShiftPythonException, match="Overrides and implicit defaults are mutually exclusive"):
rate_limit.commit()
Expand All @@ -56,8 +56,8 @@ def test_rules_exclusivity_implicit_rate_limit(cluster, route, module_label, bla
def test_rules_exclusivity_explicit_rate_limit(cluster, route, module_label, blame):
"""Test that server will reject a RateLimitPolicy with overrides and explicit defaults defined simultaneously"""
rate_limit = RateLimitPolicy.create_instance(cluster, blame("limit"), route, labels={"testRun": module_label})
rate_limit.overrides.add_limit("overrides", [Limit(2, 5)])
rate_limit.defaults.add_limit("explicit-defaults", [Limit(2, 5)])
rate_limit.overrides.add_limit("overrides", [Limit(2, "5s")])
rate_limit.defaults.add_limit("explicit-defaults", [Limit(2, "5s")])

with pytest.raises(OpenShiftPythonException, match="Overrides and explicit defaults are mutually exclusive"):
rate_limit.commit()
13 changes: 4 additions & 9 deletions testsuite/tests/singlecluster/test_rate_limit_anonymous.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import pytest

from testsuite.httpx.auth import HttpxOidcClientAuth
from testsuite.kuadrant.policy.authorization import Pattern, JsonResponse, ValueFrom
from testsuite.kuadrant.policy import CelPredicate
from testsuite.kuadrant.policy.authorization import JsonResponse, ValueFrom
from testsuite.kuadrant.policy.rate_limit import Limit

pytestmark = [pytest.mark.kuadrant_only, pytest.mark.limitador]
Expand All @@ -14,14 +15,8 @@ def rate_limit(rate_limit):
"""Add limit to the policy only for anonymous users"""
rate_limit.add_limit(
"basic",
[Limit(5, 10)],
when=[
Pattern(
selector=r"metadata.filter_metadata.envoy\.filters\.http\.ext_authz.identity.anonymous",
operator="eq",
value='"true"',
)
],
[Limit(5, "10s")],
when=[CelPredicate("auth.identity.anonymous == 'true'")],
)
return rate_limit

Expand Down
5 changes: 2 additions & 3 deletions testsuite/tests/singlecluster/test_rate_limit_authz.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import pytest

from testsuite.httpx.auth import HttpxOidcClientAuth
from testsuite.kuadrant.policy import CelExpression
from testsuite.kuadrant.policy.authorization import ValueFrom, JsonResponse
from testsuite.kuadrant.policy.rate_limit import Limit

Expand All @@ -13,9 +14,7 @@
@pytest.fixture(scope="module")
def rate_limit(rate_limit):
"""Add limit to the policy"""
rate_limit.add_limit(
"basic", [Limit(5, 60)], counters=[r"metadata.filter_metadata.envoy\.filters\.http\.ext_authz.identity.user"]
)
rate_limit.add_limit("basic", [Limit(5, "60s")], counters=[CelExpression("auth.identity.user")])
return rate_limit


Expand Down
Loading