Skip to content

Commit

Permalink
Refactor testsuite to be more aligned with Gateway API
Browse files Browse the repository at this point in the history
  • Loading branch information
pehala committed Nov 16, 2023
1 parent de10819 commit 60b4d7f
Show file tree
Hide file tree
Showing 54 changed files with 1,019 additions and 1,037 deletions.
105 changes: 105 additions & 0 deletions testsuite/objects/gateway.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
"""Module containing Proxy related stuff"""
from abc import abstractmethod, ABC
from dataclasses import dataclass
from typing import TYPE_CHECKING, Optional, Any

from . import LifecycleObject, asdict
from ..certificates import Certificate

if TYPE_CHECKING:
from testsuite.openshift.client import OpenShiftClient
from testsuite.openshift.httpbin import Httpbin


class Referencable(ABC):
"""Object that can be referenced in Gateway API style"""

@property
@abstractmethod
def reference(self) -> dict[str, str]:
"""
Returns dict, which can be used as reference in Gateway API Objects.
https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1beta1.ParentReference
"""


@dataclass
class CustomReference(Referencable):
"""
Manually creates Reference object.
https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io%2fv1beta1.ParentReference
"""

@property
def reference(self) -> dict[str, Any]:
return asdict(self)

group: str
kind: str
name: str
namespace: Optional[str] = None
sectionName: Optional[str] = None # pylint: disable=invalid-name
port: Optional[int] = None


class Gateway(LifecycleObject, Referencable):
"""
Abstraction layer for a Gateway sitting between end-user and Kuadrant
Simplified: Equals to Gateway Kubernetes object
"""

@property
@abstractmethod
def openshift(self) -> "OpenShiftClient":
"""Returns OpenShift client for this gateway"""

@property
@abstractmethod
def service_name(self) -> str:
"""Service name for this gateway"""

@abstractmethod
def wait_for_ready(self, timeout: int = 90):
"""Waits until the gateway is ready"""

@abstractmethod
def get_tls_cert(self) -> Optional[Certificate]:
"""Returns TLS cert bound to this Gateway, if the Gateway does not use TLS, returns None"""


class GatewayRoute(LifecycleObject, Referencable):
"""
Abstraction layer for *Route objects in Gateway API
Simplified: Equals to HTTPRoute Kubernetes object
"""

@classmethod
@abstractmethod
def create_instance(
cls,
openshift: "OpenShiftClient",
name,
gateway: Gateway,
labels: dict[str, str] = None,
):
"""Creates new gateway instance"""

@abstractmethod
def add_hostname(self, hostname: str):
"""Adds hostname to the Route"""

@abstractmethod
def remove_hostname(self, hostname: str):
"""Remove hostname from the Route"""

@abstractmethod
def remove_all_hostnames(self):
"""Remove all hostnames from the Route"""

@abstractmethod
def add_backend(self, backend: "Httpbin", prefix):
"""Adds another backend to the Route, with specific prefix"""

@abstractmethod
def remove_all_backend(self):
"""Sets match for a specific backend"""
33 changes: 33 additions & 0 deletions testsuite/objects/hostname.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Abstract classes for Hostname related stuff"""
from abc import ABC, abstractmethod

from httpx import Client

from .gateway import Gateway


class Hostname(ABC):
"""
Abstraction layer on top of externally exposed hostname
Simplified: Does not have any equal Kubernetes object. It is a hostname you can send HTTP request to
"""

@abstractmethod
def client(self, **kwargs) -> Client:
"""Return Httpx client for the requests to this backend"""

@property
@abstractmethod
def hostname(self) -> str:
"""Returns full hostname in string form associated with this object"""


class Exposer:
"""Exposes hostnames to be accessible from outside"""

@abstractmethod
def expose_hostname(self, name, gateway: Gateway) -> Hostname:
"""
Exposes hostname, so it is accessible from outside
Actual hostname is generated from "name" and is returned in a form of a Hostname object
"""
114 changes: 0 additions & 114 deletions testsuite/openshift/envoy.py

This file was deleted.

2 changes: 1 addition & 1 deletion testsuite/openshift/httpbin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from importlib import resources

from testsuite.objects import LifecycleObject
from testsuite.objects.gateway import Referencable
from testsuite.openshift.client import OpenShiftClient
from testsuite.openshift.objects.gateway_api import Referencable


class Httpbin(LifecycleObject, Referencable):
Expand Down
9 changes: 5 additions & 4 deletions testsuite/openshift/objects/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Base classes/methods for our own APIObjects"""
import functools

from openshift import APIObject
from openshift import APIObject, timeout

from testsuite.objects import LifecycleObject

Expand Down Expand Up @@ -48,6 +48,7 @@ def commit(self):

def delete(self, ignore_not_found=True, cmd_args=None):
"""Deletes the resource, by default ignored not found"""
deleted = super().delete(ignore_not_found, cmd_args)
self.committed = False
return deleted
with timeout(30):
deleted = super().delete(ignore_not_found, cmd_args)
self.committed = False
return deleted
11 changes: 5 additions & 6 deletions testsuite/openshift/objects/auth_config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from testsuite.openshift.client import OpenShiftClient
from testsuite.openshift.objects import OpenShiftObject, modify
from .sections import IdentitySection, MetadataSection, ResponseSection, AuthorizationSection
from ..route import Route


class AuthConfig(OpenShiftObject):
Expand Down Expand Up @@ -42,19 +41,19 @@ def create_instance(
cls,
openshift: OpenShiftClient,
name,
route: Optional[Route],
route,
labels: Dict[str, str] = None,
hostnames: List[str] = None,
):
"""Creates base instance"""
model: Dict = {
"apiVersion": "authorino.kuadrant.io/v1beta2",
"kind": "AuthConfig",
"metadata": {"name": name, "namespace": openshift.project, "labels": labels},
"spec": {"hosts": hostnames or [route.hostname]}, # type: ignore
"spec": {"hosts": []},
}

return cls(model, context=openshift.context)
obj = cls(model, context=openshift.context)
route.add_auth_config(obj)
return obj

@modify
def add_host(self, hostname):
Expand Down
31 changes: 4 additions & 27 deletions testsuite/openshift/objects/auth_config/auth_policy.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,16 @@
"""Module containing classes related to Auth Policy"""
from typing import Dict, List
from typing import Dict

from testsuite.objects import Rule, asdict

from testsuite.objects.gateway import Referencable
from testsuite.openshift.client import OpenShiftClient
from testsuite.openshift.objects import modify
from testsuite.openshift.objects.auth_config import AuthConfig
from testsuite.openshift.objects.gateway_api.route import HTTPRoute


class AuthPolicy(AuthConfig):
"""AuthPolicy object, it serves as Kuadrants AuthConfig"""

def __init__(self, dict_to_model=None, string_to_model=None, context=None, route: HTTPRoute = None):
super().__init__(dict_to_model, string_to_model, context)
self._route = route

@property
def route(self) -> HTTPRoute:
"""Returns route to which the Policy is bound, won't work with objects fetched from Openshift"""
if not self._route:
# TODO: Fetch route from Openshift directly
raise ValueError("This instance doesnt have a Route specified!!")
return self._route

@property
def auth_section(self):
return self.model.spec.setdefault("rules", {})
Expand All @@ -34,9 +21,8 @@ def create_instance( # type: ignore
cls,
openshift: OpenShiftClient,
name,
route: HTTPRoute,
route: Referencable,
labels: Dict[str, str] = None,
hostnames: List[str] = None,
):
"""Creates base instance"""
model: Dict = {
Expand All @@ -48,16 +34,7 @@ def create_instance( # type: ignore
},
}

return cls(model, context=openshift.context, route=route)

def add_host(self, hostname):
return self.route.add_hostname(hostname)

def remove_host(self, hostname):
return self.route.remove_hostname(hostname)

def remove_all_hosts(self):
return self.route.remove_all_hostnames()
return cls(model, context=openshift.context)

@modify
def add_rule(self, when: list[Rule]):
Expand Down
2 changes: 1 addition & 1 deletion testsuite/openshift/objects/dnspolicy.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import openshift as oc

from testsuite.objects import asdict
from testsuite.objects.gateway import Referencable
from testsuite.openshift.client import OpenShiftClient
from testsuite.openshift.objects import OpenShiftObject
from testsuite.openshift.objects.gateway_api import Referencable


@dataclass
Expand Down
Loading

0 comments on commit 60b4d7f

Please sign in to comment.