Skip to content

Commit

Permalink
Merge pull request Kuadrant#516 from averevki/dns-geo-tests
Browse files Browse the repository at this point in the history
Add geo load-balancing tests
  • Loading branch information
averevki authored Sep 11, 2024
2 parents 9558a7d + 7bb9e09 commit b4f9624
Show file tree
Hide file tree
Showing 18 changed files with 264 additions and 121 deletions.
20 changes: 15 additions & 5 deletions config/settings.local.yaml.tpl
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
#default:
# tester: "someuser" # Optional: name of the user, who is running the tests, defaults to whoami/uid
# cluster: # Primary cluster where tests should run
# api_url: "https://api.kubernetes.com" # Optional: Kubernetes API URL, if None it will use Kubernetes that you are logged in
# token: "KUADRANT_RULEZ" # Optional: Kubernetes Token, if None it will Kubernetes that you are logged in
# kubeconfig_path: "~/.kube/config" # Optional: Kubeconfig to use, if None the default one is used
# kuadrantctl: kuadrantctl
# tools:
# project: "tools" # Optional: Kubernetes project, where external tools are located
Expand Down Expand Up @@ -44,11 +40,25 @@
# metrics_service_name: "" # controller metrics service name for already deployed Authorino
# default_exposer: "kubernetes" # Force Exposer typem options: 'openshift', 'kind', 'kubernetes'
# control_plane:
# additional_clusters: [] # List of additional clusters for Multicluster testing, see 'cluster' option for more details
# cluster: # Primary cluster where tests should run
# api_url: "https://api.kubernetes.com" # Optional: Kubernetes API URL, if None it will use Kubernetes that you are logged in
# token: "KUADRANT_RULEZ" # Optional: Kubernetes Token, if None it will Kubernetes that you are logged in
# kubeconfig_path: "~/.kube/config" # Optional: Kubeconfig to use, if None the default one is used
# cluster2: # Second cluster for the multicluster tests
# api_url: "https://api.kubernetes2.com"
# token: "KUADRANT_RULEZ"
# kubeconfig_path: "~/.kube/config2"
# provider_secret: "aws-credentials" # Name of the Secret resource that contains DNS provider credentials
# issuer: # Issuer object for testing TLSPolicy
# name: "selfsigned-cluster-issuer" # Name of Issuer CR
# kind: "ClusterIssuer" # Kind of Issuer, can be "Issuer" or "ClusterIssuer"
# dns:
# dns_server:
# geo_code: "DE" # dns provider geo code of the dns server
# address: "ns1.seolizer.de" # dns nameserver hostname or ip
# dns_server2:
# geo_code: "AU" # dns provider geo code of the second dns server
# address: "ns2.seolizer.de" # second dns nameserver hostname or ip
# letsencrypt:
# issuer: # Issuer object for testing TLSPolicy
# name: "letsencrypt-staging-issuer" # Name of Issuer CR
Expand Down
9 changes: 4 additions & 5 deletions testsuite/capabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import functools

from openshift_client import selector
from weakget import weakget

from testsuite.config import settings

Expand All @@ -12,14 +11,14 @@
def has_kuadrant():
"""Returns True, if Kuadrant deployment is present and should be used"""
project = settings["service_protection"]["system_project"]
clusters = weakget(settings)["control_plane"]["additional_clusters"] % []
clusters.append(settings["cluster"])
clusters = [settings["control_plane"]["cluster"]]
if cluster2 := settings["control_plane"]["cluster2"]:
clusters.append(cluster2)
for cluster in clusters:
system_project = cluster.change_project(project)
# Try if Kuadrant is deployed
if not system_project.connected:
return False, f"Cluster {cluster.api_url} is not connected, or namespace {project} does not exist"
system_project = cluster.change_project(project)

with system_project.context:
if selector("kuadrant").count_existing() == 0:
return False, f"Cluster {cluster.api_url} does not have Kuadrant resource in project {project}"
Expand Down
7 changes: 7 additions & 0 deletions testsuite/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from dynaconf import Dynaconf, Validator

from testsuite.utils import hostname_to_ip
from testsuite.config.tools import fetch_route, fetch_service, fetch_secret, fetch_service_ip


Expand Down Expand Up @@ -59,6 +60,12 @@ def __init__(self, name, default, **kwargs) -> None:
Validator("letsencrypt.issuer.name", must_exist=True, ne=None)
& Validator("letsencrypt.issuer.kind", must_exist=True, is_in={"Issuer", "ClusterIssuer"})
),
(
Validator("dns.dns_server.address", must_exist=True, ne=None, cast=hostname_to_ip)
& Validator("dns.dns_server.geo_code", must_exist=True, ne=None)
& Validator("dns.dns_server2.address", must_exist=True, ne=None, cast=hostname_to_ip)
& Validator("dns.dns_server2.geo_code", must_exist=True, ne=None)
),
DefaultValueValidator("keycloak.url", default=fetch_service_ip("keycloak", force_http=True, port=8080)),
DefaultValueValidator("keycloak.password", default=fetch_secret("credential-sso", "ADMIN_PASSWORD")),
DefaultValueValidator("mockserver.url", default=fetch_service_ip("mockserver", force_http=True, port=1080)),
Expand Down
2 changes: 1 addition & 1 deletion testsuite/config/exposer.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
def load(obj, env=None, silent=True, key=None, filename=None):
"""Selects proper Exposes class"""
if "default_exposer" not in obj or not obj["default_exposer"]:
client = obj["cluster"]
client = obj["control_plane"]["cluster"]
if "route.openshift.io/v1" in client.do_action("api-versions").out():
obj["default_exposer"] = EXPOSERS["openshift"]
else:
Expand Down
14 changes: 10 additions & 4 deletions testsuite/config/openshift_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,19 @@ def inject_client(obj, base_client, path):
# pylint: disable=unused-argument, too-many-locals
def load(obj, env=None, silent=True, key=None, filename=None):
"""Creates all KubernetesClients"""
section = obj.setdefault("cluster", {})
control_plane = obj.setdefault("control_plane", {})

cluster = control_plane.setdefault("cluster", {})
client = KubernetesClient(
section.get("project"), section.get("api_url"), section.get("token"), section.get("kubeconfig_path")
cluster.get("project"), cluster.get("api_url"), cluster.get("token"), cluster.get("kubeconfig_path")
)
obj["cluster"] = client
obj["control_plane"]["cluster"] = client

tools = None
if "tools" in obj and "project" in obj["tools"]:
tools = client.change_project(obj["tools"]["project"])
obj["tools"] = tools

control_plane = obj.setdefault("control_plane", {})
clients = []
clusters = control_plane.setdefault("additional_clusters", [])
for value in clusters:
Expand All @@ -37,3 +38,8 @@ def load(obj, env=None, silent=True, key=None, filename=None):
)
if len(clients) > 0:
control_plane["additional_clusters"] = clients

if cluster2 := control_plane.setdefault("cluster2", {}):
obj["control_plane"]["cluster2"] = KubernetesClient(
cluster2.get("project"), cluster2.get("api_url"), cluster2.get("token"), cluster2.get("kubeconfig_path")
)
23 changes: 23 additions & 0 deletions testsuite/kuadrant/policy/dns.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
"""Module for DNSPolicy related classes"""

from dataclasses import dataclass

from testsuite.gateway import Referencable
from testsuite.kubernetes.client import KubernetesClient
from testsuite.kuadrant.policy import Policy
from testsuite.utils import asdict


@dataclass
class LoadBalancing:
"""Dataclass for DNSPolicy load-balancing spec"""

default_geo: str
default_weight: int

def asdict(self):
"""Custom asdict due to nested structure."""
return {
"geo": {"defaultGeo": self.default_geo},
"weighted": {"defaultWeight": self.default_weight},
}


class DNSPolicy(Policy):
Expand All @@ -15,6 +33,7 @@ def create_instance(
name: str,
parent: Referencable,
provider_secret_name: str,
load_balancing: LoadBalancing = None,
labels: dict[str, str] = None,
):
"""Creates new instance of DNSPolicy"""
Expand All @@ -30,4 +49,8 @@ def create_instance(
},
}

if load_balancing:
model["spec"]["routingStrategy"] = "loadbalanced"
model["spec"]["loadBalancing"] = asdict(load_balancing)

return cls(model, context=cluster.context)
2 changes: 1 addition & 1 deletion testsuite/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ def module_label(label):
def cluster(testconfig):
"""Kubernetes client for the primary namespace"""
project = testconfig["service_protection"]["project"]
client = testconfig["cluster"].change_project(testconfig["service_protection"]["project"])
client = testconfig["control_plane"]["cluster"].change_project(testconfig["service_protection"]["project"])
if not client.connected:
pytest.fail(f"You are not logged into Kubernetes or the {project} namespace doesn't exist")
return client
Expand Down
Loading

0 comments on commit b4f9624

Please sign in to comment.