-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #463 from pehala/kuadrantctl
Add Kuadrantctl tests
- Loading branch information
Showing
16 changed files
with
404 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
default: | ||
dynaconf_merge: true | ||
cluster: {} | ||
kuadrantctl: "kuadrantctl" | ||
tools: | ||
project: "tools" | ||
cfssl: "cfssl" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# pylint: disable=line-too-long | ||
""" | ||
Help as of 0.2.3 | ||
Kuadrant configuration command line utility | ||
Usage: | ||
kuadrantctl [command] | ||
Available Commands: | ||
completion Generate the autocompletion script for the specified shell | ||
generate Commands related to kubernetes object generation | ||
gatewayapi Generate Gataway API resources | ||
httproute Generate Gateway API HTTPRoute from OpenAPI 3.0.X | ||
kuadrant Generate Kuadrant resources | ||
authpolicy Generate Kuadrant AuthPolicy from OpenAPI 3.0.X | ||
ratelimitpolicy Generate Kuadrant Rate Limit Policy from OpenAPI 3.0.X | ||
help Help about any command | ||
version Print the version number of kuadrantctl | ||
Flags: | ||
-h, --help help for httproute | ||
--oas string Path to OpenAPI spec file (in JSON or YAML format), URL, or '-' to read from standard input (required) | ||
-o, --output-format string Output format: 'yaml' or 'json'. (default "yaml") | ||
Global Flags: | ||
-v, --verbose verbose output | ||
Use "kuadrantctl [command] --help" for more information about a command. | ||
""" | ||
|
||
import subprocess | ||
|
||
|
||
class KuadrantCTL: | ||
"""Wrapper on top of kuadrantctl binary""" | ||
|
||
def __init__(self, binary) -> None: | ||
super().__init__() | ||
self.binary = binary | ||
|
||
def run(self, *args, **kwargs): | ||
"""Passes arguments to Subprocess.run, see that for more details""" | ||
args = (self.binary, *args) | ||
kwargs.setdefault("capture_output", True) | ||
kwargs.setdefault("check", True) | ||
kwargs.setdefault("text", True) | ||
# We do supply value for check :) | ||
return subprocess.run(args, **kwargs) # pylint: disable= subprocess-run-check |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
"""OAS processing""" | ||
|
||
import contextlib | ||
import json | ||
import tempfile | ||
from collections import UserDict | ||
|
||
import yaml | ||
|
||
from testsuite.backend import Backend | ||
from testsuite.gateway import Referencable, Hostname | ||
|
||
|
||
@contextlib.contextmanager | ||
def as_tmp_file(text): | ||
"""Saves text in a temporary file and returns absolute path""" | ||
with tempfile.NamedTemporaryFile("w") as file: | ||
file.write(text) | ||
file.flush() | ||
yield file.name | ||
|
||
|
||
class OASWrapper(UserDict): | ||
"""Wrapper for OpenAPISpecification""" | ||
|
||
def as_json(self): | ||
"""Returns OAS as JSON""" | ||
return json.dumps(self.data) | ||
|
||
def as_yaml(self): | ||
"""Returns OAS as YAML""" | ||
return yaml.dump(self.data) | ||
|
||
def add_backend_to_paths(self, backend: Backend): | ||
"""Adds backend to all paths, should be only used in tests that do not test this section""" | ||
for path in self["paths"].values(): | ||
path["x-kuadrant"] = { | ||
"backendRefs": [backend.reference], | ||
} | ||
|
||
def add_top_level_route(self, parent: Referencable, hostname: Hostname, name: str): | ||
"""Adds top-level x-kuadrant definition for Route, should be only used in tests that do not test this section""" | ||
self["x-kuadrant"] = { | ||
"route": { | ||
"name": name, | ||
"hostnames": [hostname.hostname], | ||
"parentRefs": [parent.reference], | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
--- | ||
openapi: 3.1.0 | ||
info: | ||
title: Httpbin | ||
version: 0.0.51 | ||
paths: | ||
"/get": | ||
get: | ||
operationId: get_get | ||
responses: | ||
'200': | ||
description: Successful Response | ||
content: | ||
application/json: | ||
schema: | ||
type: string | ||
"/anything": | ||
get: | ||
operationId: get_anything | ||
responses: | ||
'200': | ||
description: Successful Response | ||
content: | ||
application/json: | ||
schema: | ||
type: string | ||
put: | ||
operationId: put_anything | ||
responses: | ||
'200': | ||
description: Successful Response | ||
content: | ||
application/json: | ||
schema: | ||
type: string |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
"""Tests basic commands""" | ||
|
||
import pytest | ||
|
||
|
||
# https://github.com/Kuadrant/kuadrantctl/issues/90 | ||
@pytest.mark.parametrize("command", ["help", "version"]) | ||
def test_commands(kuadrantctl, command): | ||
"""Test that basic commands exists and returns anything""" | ||
result = kuadrantctl.run(command) | ||
assert not result.stderr, f"Command '{command}' returned an error: {result.stderr}" | ||
assert result.stdout, f"Command '{command}' returned empty output" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
"""Tests that you can generate simple AuthPolicy, focused on the cmdline options more than on extension functionality""" | ||
|
||
import pytest | ||
|
||
from testsuite.httpx.auth import HttpxOidcClientAuth | ||
from testsuite.oas import as_tmp_file | ||
from testsuite.policy.authorization.auth_policy import AuthPolicy | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def auth(keycloak): | ||
"""Returns authentication object for HTTPX""" | ||
return HttpxOidcClientAuth(keycloak.get_token, "authorization") | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def oas(oas, keycloak, blame, gateway, hostname, backend): | ||
"""Add OIDC configuration""" | ||
oas.add_top_level_route(gateway, hostname, blame("route")) | ||
|
||
oas["components"] = { | ||
"securitySchemes": { | ||
"oidc": { | ||
"type": "openIdConnect", | ||
"openIdConnectUrl": keycloak.well_known["issuer"], | ||
# https://github.com/Kuadrant/kuadrantctl/issues/94 | ||
# "openIdConnectUrl": keycloak.well_known["issuer"] + "/.well-known/openid-configuration", | ||
} | ||
} | ||
} | ||
anything = oas["paths"]["/anything"] | ||
anything["x-kuadrant"] = { | ||
"backendRefs": [backend.reference], | ||
} | ||
anything["get"]["security"] = [{"oidc": []}] | ||
return oas | ||
|
||
|
||
@pytest.mark.parametrize("encoder", [pytest.param("as_json", id="JSON"), pytest.param("as_yaml", id="YAML")]) | ||
@pytest.mark.parametrize("stdin", [pytest.param(True, id="STDIN"), pytest.param(False, id="File")]) | ||
def test_generate_authpolicy(request, kuadrantctl, oas, encoder, openshift, client, stdin, auth): | ||
"""Generates Policy from OAS and tests that it works as expected""" | ||
encoded = getattr(oas, encoder)() | ||
|
||
if stdin: | ||
result = kuadrantctl.run("generate", "kuadrant", "authpolicy", "--oas", "-", input=encoded) | ||
else: | ||
with as_tmp_file(encoded) as file_name: | ||
result = kuadrantctl.run("generate", "kuadrant", "authpolicy", "--oas", file_name) | ||
|
||
policy = openshift.apply_from_string(result.stdout, AuthPolicy) | ||
request.addfinalizer(policy.delete) | ||
|
||
policy.wait_for_ready() | ||
|
||
response = client.get("/anything") | ||
assert response.status_code == 401 | ||
|
||
response = client.get("/anything", auth=auth) | ||
assert response.status_code == 200 | ||
|
||
response = client.get("/anything", headers={"Authorization": "Bearer xyz"}) | ||
assert response.status_code == 401 | ||
|
||
response = client.put("/anything") | ||
assert response.status_code == 200 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
""" | ||
Tests that you can generate simple RateLimitPolicy, focused on the cmdline options more than on extension | ||
functionality | ||
""" | ||
|
||
import pytest | ||
|
||
from testsuite.oas import as_tmp_file | ||
from testsuite.policy.rate_limit_policy import Limit, RateLimitPolicy | ||
from testsuite.utils import asdict | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def oas(oas, blame, gateway, hostname, backend): | ||
"""Add X-Kuadrant specific fields""" | ||
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))]}} | ||
return oas | ||
|
||
|
||
@pytest.mark.parametrize("encoder", [pytest.param("as_json", id="JSON"), pytest.param("as_yaml", id="YAML")]) | ||
@pytest.mark.parametrize("stdin", [pytest.param(True, id="STDIN"), pytest.param(False, id="File")]) | ||
def test_generate_limit(request, kuadrantctl, oas, encoder, openshift, client, stdin): | ||
"""Tests that RateLimitPolicy can be generated and that it is enforced as expected""" | ||
encoded = getattr(oas, encoder)() | ||
|
||
if stdin: | ||
result = kuadrantctl.run("generate", "kuadrant", "ratelimitpolicy", "--oas", "-", input=encoded) | ||
else: | ||
with as_tmp_file(encoded) as file_name: | ||
result = kuadrantctl.run("generate", "kuadrant", "ratelimitpolicy", "--oas", file_name) | ||
|
||
policy = openshift.apply_from_string(result.stdout, RateLimitPolicy) | ||
request.addfinalizer(policy.delete) | ||
policy.wait_for_ready() | ||
|
||
responses = client.get_many("/anything", 3) | ||
responses.assert_all(status_code=200) | ||
assert client.get("/anything").status_code == 429 | ||
|
||
# Check that it did not affect other endpoints | ||
responses = client.get_many("/get", 5) | ||
responses.assert_all(status_code=200) |
Oops, something went wrong.