From 98dfb84ca42a3b96d7ed37437a5b90f9c163f009 Mon Sep 17 00:00:00 2001 From: averevki Date: Thu, 2 Nov 2023 14:58:47 +0100 Subject: [PATCH 1/3] Make tls in MGC gateway plugable --- .../openshift/objects/gateway_api/gateway.py | 29 ++++++++++--------- testsuite/tests/mgc/conftest.py | 1 + 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/testsuite/openshift/objects/gateway_api/gateway.py b/testsuite/openshift/objects/gateway_api/gateway.py index e8f75e13..325328de 100644 --- a/testsuite/openshift/objects/gateway_api/gateway.py +++ b/testsuite/openshift/objects/gateway_api/gateway.py @@ -85,6 +85,7 @@ def create_instance( gateway_class: str, hostname: str, labels: dict[str, str] = None, + tls: bool = False, placement: typing.Optional[str] = None, ): """Creates new instance of Gateway""" @@ -95,19 +96,21 @@ def create_instance( labels["cluster.open-cluster-management.io/placement"] = placement instance = super(MGCGateway, cls).create_instance(openshift, name, gateway_class, hostname, labels) - instance.model["spec"]["listeners"] = [ - { - "name": "api", - "port": 443, - "protocol": "HTTPS", - "hostname": hostname, - "allowedRoutes": {"namespaces": {"from": "All"}}, - "tls": { - "mode": "Terminate", - "certificateRefs": [{"name": f"{name}-tls", "kind": "Secret"}], - }, - } - ] + + if tls: + instance.model["spec"]["listeners"] = [ + { + "name": "api", + "port": 443, + "protocol": "HTTPS", + "hostname": hostname, + "allowedRoutes": {"namespaces": {"from": "All"}}, + "tls": { + "mode": "Terminate", + "certificateRefs": [{"name": f"{name}-tls", "kind": "Secret"}], + }, + } + ] return instance diff --git a/testsuite/tests/mgc/conftest.py b/testsuite/tests/mgc/conftest.py index 3ba82ba5..4b8e12b9 100644 --- a/testsuite/tests/mgc/conftest.py +++ b/testsuite/tests/mgc/conftest.py @@ -38,6 +38,7 @@ def upstream_gateway(request, openshift, blame, hostname, module_label): name=blame("mgc-gateway"), gateway_class="kuadrant-multi-cluster-gateway-instance-per-cluster", hostname=f"*.{hostname}", + tls=True, placement="http-gateway", labels={"app": module_label}, ) From 91b33c3cc42714aca74ad022d83bbb467c7447e9 Mon Sep 17 00:00:00 2001 From: averevki Date: Thu, 2 Nov 2023 14:59:31 +0100 Subject: [PATCH 2/3] Add DNSHealthCheckProbe object --- testsuite/openshift/objects/dnspolicy.py | 40 ++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/testsuite/openshift/objects/dnspolicy.py b/testsuite/openshift/objects/dnspolicy.py index 8d228b16..03b1b14e 100644 --- a/testsuite/openshift/objects/dnspolicy.py +++ b/testsuite/openshift/objects/dnspolicy.py @@ -1,9 +1,36 @@ """Module for DNSPolicy related classes""" +from dataclasses import dataclass +from typing import Optional, Literal + +import openshift as oc + +from testsuite.objects import asdict from testsuite.openshift.client import OpenShiftClient from testsuite.openshift.objects import OpenShiftObject from testsuite.openshift.objects.gateway_api import Referencable +@dataclass +class HealthCheck: # pylint: disable=invalid-name + """Object representing DNSPolicy health check specification""" + + allowInsecureCertificates: Optional[bool] = None + endpoint: Optional[str] = None + expectedResponses: Optional[list[int]] = None + failureThreshold: Optional[int] = None + interval: Optional[str] = None + port: Optional[int] = None + protocol: Literal["http", "https"] = "https" + + +class DNSHealthCheckProbe(OpenShiftObject): + """DNSHealthCheckProbe object""" + + def is_healthy(self) -> bool: + """Returns True if DNSHealthCheckProbe endpoint is healthy""" + return self.model.status.healthy + + class DNSPolicy(OpenShiftObject): """DNSPolicy object""" @@ -13,15 +40,24 @@ def create_instance( openshift: OpenShiftClient, name: str, parent: Referencable, + healthCheck: HealthCheck = None, labels: dict[str, str] = None, - ): + ): # pylint: disable=invalid-name """Creates new instance of DNSPolicy""" - model = { + model: dict = { "apiVersion": "kuadrant.io/v1alpha1", "kind": "DNSPolicy", "metadata": {"name": name, "labels": labels}, "spec": {"targetRef": parent.reference}, } + if healthCheck: + model["spec"]["healthCheck"] = asdict(healthCheck) + return cls(model, context=openshift.context) + + def get_dns_health_probe(self) -> oc.APIObject: + """Returns DNSHealthCheckProbe object for the created DNSPolicy""" + dns_probe = oc.selector("DNSHealthCheckProbe", labels={"kuadrant.io/dnspolicy": self.name()}).object() + return DNSHealthCheckProbe(dns_probe.model, context=self.context) From 4d5238aacc8580c1e5e1e99c2669cd02e8267268 Mon Sep 17 00:00:00 2001 From: averevki Date: Thu, 2 Nov 2023 14:59:52 +0100 Subject: [PATCH 3/3] Add basic tests for DNSPolicy health checks --- testsuite/openshift/objects/dnspolicy.py | 13 +++--- testsuite/tests/mgc/dnspolicy/__init__.py | 0 testsuite/tests/mgc/dnspolicy/conftest.py | 28 +++++++++++++ .../mgc/dnspolicy/health_check/__init__.py | 0 .../mgc/dnspolicy/health_check/conftest.py | 40 +++++++++++++++++++ .../health_check/test_healthy_endpoint.py | 23 +++++++++++ .../health_check/test_unhealthy_endpoint.py | 23 +++++++++++ 7 files changed, 121 insertions(+), 6 deletions(-) create mode 100644 testsuite/tests/mgc/dnspolicy/__init__.py create mode 100644 testsuite/tests/mgc/dnspolicy/conftest.py create mode 100644 testsuite/tests/mgc/dnspolicy/health_check/__init__.py create mode 100644 testsuite/tests/mgc/dnspolicy/health_check/conftest.py create mode 100644 testsuite/tests/mgc/dnspolicy/health_check/test_healthy_endpoint.py create mode 100644 testsuite/tests/mgc/dnspolicy/health_check/test_unhealthy_endpoint.py diff --git a/testsuite/openshift/objects/dnspolicy.py b/testsuite/openshift/objects/dnspolicy.py index 03b1b14e..f45da305 100644 --- a/testsuite/openshift/objects/dnspolicy.py +++ b/testsuite/openshift/objects/dnspolicy.py @@ -40,9 +40,8 @@ def create_instance( openshift: OpenShiftClient, name: str, parent: Referencable, - healthCheck: HealthCheck = None, labels: dict[str, str] = None, - ): # pylint: disable=invalid-name + ): """Creates new instance of DNSPolicy""" model: dict = { @@ -52,12 +51,14 @@ def create_instance( "spec": {"targetRef": parent.reference}, } - if healthCheck: - model["spec"]["healthCheck"] = asdict(healthCheck) - return cls(model, context=openshift.context) + def set_health_check(self, health_check: HealthCheck): + """Sets health check for DNSPolicy""" + self.model["spec"]["healthCheck"] = asdict(health_check) + def get_dns_health_probe(self) -> oc.APIObject: """Returns DNSHealthCheckProbe object for the created DNSPolicy""" - dns_probe = oc.selector("DNSHealthCheckProbe", labels={"kuadrant.io/dnspolicy": self.name()}).object() + with self.context: + dns_probe = oc.selector("DNSHealthCheckProbe", labels={"kuadrant.io/dnspolicy": self.name()}).object() return DNSHealthCheckProbe(dns_probe.model, context=self.context) diff --git a/testsuite/tests/mgc/dnspolicy/__init__.py b/testsuite/tests/mgc/dnspolicy/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/testsuite/tests/mgc/dnspolicy/conftest.py b/testsuite/tests/mgc/dnspolicy/conftest.py new file mode 100644 index 00000000..8d0540db --- /dev/null +++ b/testsuite/tests/mgc/dnspolicy/conftest.py @@ -0,0 +1,28 @@ +"""Conftest for DNSPolicy tests""" +import pytest + +from testsuite.openshift.objects.gateway_api.gateway import MGCGateway + + +@pytest.fixture(scope="module") +def upstream_gateway(request, openshift, blame, hostname, module_label): + """Creates and returns configured and ready upstream Gateway with disabled tls""" + upstream_gateway = MGCGateway.create_instance( + openshift=openshift, + name=blame("mgc-gateway"), + gateway_class="kuadrant-multi-cluster-gateway-instance-per-cluster", + hostname=f"*.{hostname}", + tls=False, + placement="http-gateway", + labels={"app": module_label}, + ) + request.addfinalizer(upstream_gateway.delete) + upstream_gateway.commit() + + return upstream_gateway + + +@pytest.fixture(scope="module") +def tls_policy(): + """Don't need TLSPolicy in the DNSPolicy only tests""" + return None diff --git a/testsuite/tests/mgc/dnspolicy/health_check/__init__.py b/testsuite/tests/mgc/dnspolicy/health_check/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/testsuite/tests/mgc/dnspolicy/health_check/conftest.py b/testsuite/tests/mgc/dnspolicy/health_check/conftest.py new file mode 100644 index 00000000..a2d9dea4 --- /dev/null +++ b/testsuite/tests/mgc/dnspolicy/health_check/conftest.py @@ -0,0 +1,40 @@ +"""Conftest for DNSPolicy health checks""" +import time +import pytest + +from testsuite.openshift.objects.gateway_api.gateway import MGCGateway + + +@pytest.fixture(scope="module") +def upstream_gateway(request, openshift, blame, module_label, initial_host): + """ + Creates and returns configured and ready upstream Gateway with FQDN hostname + Health checks available only with Fully Qualified Domain Names in gateway (no wildcards are allowed) + """ + upstream_gateway = MGCGateway.create_instance( + openshift=openshift, + name=blame("mgc-gateway"), + gateway_class="kuadrant-multi-cluster-gateway-instance-per-cluster", + hostname=initial_host, + tls=False, + placement="http-gateway", + labels={"app": module_label}, + ) + request.addfinalizer(upstream_gateway.delete) + upstream_gateway.commit() + + return upstream_gateway + + +@pytest.fixture(scope="module") +def dns_policy(dns_policy, health_check): + """Add health check to DNSPolicy""" + dns_policy.set_health_check(health_check) + return dns_policy + + +@pytest.fixture(scope="module") +def dns_health_probe(dns_policy, route): # pylint: disable=unused-argument + """Wait for health check to start monitoring endpoint and return according DNSHealthCheckProbe object""" + time.sleep(10) + return dns_policy.get_dns_health_probe() diff --git a/testsuite/tests/mgc/dnspolicy/health_check/test_healthy_endpoint.py b/testsuite/tests/mgc/dnspolicy/health_check/test_healthy_endpoint.py new file mode 100644 index 00000000..c8334039 --- /dev/null +++ b/testsuite/tests/mgc/dnspolicy/health_check/test_healthy_endpoint.py @@ -0,0 +1,23 @@ +"""Tests for DNSPolicy health checks - healthy endpoint""" +import pytest + +from testsuite.openshift.objects.dnspolicy import HealthCheck + +pytestmark = [pytest.mark.mgc] + + +@pytest.fixture(scope="module") +def health_check(): + """Returns healthy endpoint specification for DNSPolicy health check""" + return HealthCheck( + allowInsecureCertificates=True, + endpoint="/get", + interval="5s", + port=80, + protocol="http", + ) + + +def test_healthy_endpoint(dns_health_probe): + """Test healthy endpoint check""" + assert dns_health_probe.is_healthy() diff --git a/testsuite/tests/mgc/dnspolicy/health_check/test_unhealthy_endpoint.py b/testsuite/tests/mgc/dnspolicy/health_check/test_unhealthy_endpoint.py new file mode 100644 index 00000000..72554ddd --- /dev/null +++ b/testsuite/tests/mgc/dnspolicy/health_check/test_unhealthy_endpoint.py @@ -0,0 +1,23 @@ +"""Tests for DNSPolicy health checks - unhealthy endpoint""" +import pytest + +from testsuite.openshift.objects.dnspolicy import HealthCheck + +pytestmark = [pytest.mark.mgc] + + +@pytest.fixture(scope="module") +def health_check(): + """Returns unhealthy endpoint specification for DNSPolicy health check""" + return HealthCheck( + allowInsecureCertificates=True, + endpoint="/unknown-endpoint", + interval="5s", + port=80, + protocol="http", + ) + + +def test_unhealthy_endpoint(dns_health_probe): + """Test unhealthy endpoint check""" + assert not dns_health_probe.is_healthy()