Skip to content

Commit 444b570

Browse files
committed
Add default dns provider & provider misconfig tests
Signed-off-by: averevki <[email protected]>
1 parent 054d4c8 commit 444b570

File tree

8 files changed

+245
-10
lines changed

8 files changed

+245
-10
lines changed

testsuite/kuadrant/policy/dns.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ def wait_for_ready(self):
114114
)
115115
assert success, f"DNSRecord {self.name()} did not get ready in time"
116116

117+
def get_authoritative_dns_record(self) -> str:
118+
"""Returns the authoritative DNS record created by dns operator controller"""
119+
with self.context:
120+
return oc.selector(f"dnsrecords.kuadrant.io/{self.model.status.zoneID}").object(cls=DNSRecord)
121+
117122

118123
class DNSPolicy(Policy):
119124
"""DNSPolicy object"""
@@ -124,7 +129,7 @@ def create_instance(
124129
cluster: KubernetesClient,
125130
name: str,
126131
parent: Referencable,
127-
provider_secret_name: str,
132+
provider_secret_name: str = None,
128133
delegate: bool = None,
129134
load_balancing: LoadBalancing = None,
130135
labels: dict[str, str] = None,
@@ -135,12 +140,12 @@ def create_instance(
135140
"apiVersion": "kuadrant.io/v1",
136141
"kind": "DNSPolicy",
137142
"metadata": {"name": name, "labels": labels},
138-
"spec": {
139-
"targetRef": parent.reference,
140-
"providerRefs": [{"name": provider_secret_name}],
141-
},
143+
"spec": {"targetRef": parent.reference},
142144
}
143145

146+
if provider_secret_name is not None:
147+
model["spec"]["providerRefs"] = [{"name": provider_secret_name}]
148+
144149
if delegate is not None:
145150
model["spec"]["delegate"] = delegate
146151

testsuite/kubernetes/secret.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,31 @@ def create_instance(
1515
cls,
1616
cluster,
1717
name,
18-
data: dict[str, str],
18+
stringData: dict[str, str] = None, # pylint: disable=invalid-name
19+
data: dict[str, str] = None,
1920
secret_type: Literal["kubernetes.io/tls", "kuadrant.io/aws", "kuadrant.io/coredns", "Opaque"] = "Opaque",
2021
labels: dict[str, str] = None,
2122
):
2223
"""Creates new Secret"""
24+
if not (stringData is None) ^ (data is None):
25+
raise AttributeError("Either `stringData` or `data` must be used for the secret creation")
26+
2327
model: dict = {
2428
"kind": "Secret",
2529
"apiVersion": "v1",
2630
"metadata": {
2731
"name": name,
2832
"labels": labels,
2933
},
30-
"stringData": data,
3134
"type": secret_type,
3235
}
36+
37+
if stringData:
38+
model["stringData"] = stringData
39+
40+
if data:
41+
model["data"] = data
42+
3343
return cls(model, context=cluster.context)
3444

3545
def __getitem__(self, name):
@@ -60,10 +70,10 @@ def create_instance( # type: ignore[override]
6070
return super().create_instance(
6171
cluster,
6272
name,
63-
{
73+
stringData={
6474
cert_name: certificate.chain,
6575
key_name: certificate.key,
6676
},
67-
secret_type,
68-
labels,
77+
secret_type=secret_type,
78+
labels=labels,
6979
)

testsuite/tests/singlecluster/gateway/dnspolicy/default_provider/__init__.py

Whitespace-only changes.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
"""Test default DNS provider secret"""
2+
3+
import pytest
4+
5+
import openshift_client as oc
6+
7+
from testsuite.gateway import GatewayListener
8+
from testsuite.kubernetes.secret import Secret
9+
from testsuite.gateway.gateway_api.gateway import KuadrantGateway
10+
from testsuite.kuadrant.policy.dns import DNSPolicy
11+
12+
pytestmark = [pytest.mark.kuadrant_only, pytest.mark.dnspolicy, pytest.mark.disruptive]
13+
14+
15+
@pytest.fixture(scope="module")
16+
def gateway(request, cluster, blame, wildcard_domain, module_label):
17+
"""Returns gateway without tls"""
18+
gw = KuadrantGateway.create_instance(
19+
cluster,
20+
blame("gw"),
21+
{"app": module_label},
22+
)
23+
gw.add_listener(GatewayListener(hostname=wildcard_domain))
24+
request.addfinalizer(gw.delete)
25+
gw.commit()
26+
gw.wait_for_ready()
27+
return gw
28+
29+
30+
@pytest.fixture(scope="module")
31+
def dns_provider_secret(request, dns_provider_secret, cluster, blame, module_label):
32+
"""Get existing DNS provider secret and create a copy with default-provider label"""
33+
provider_secret = oc.selector(f"secret/{dns_provider_secret}", static_context=cluster.context).object(cls=Secret)
34+
default_secret = Secret.create_instance(
35+
cluster,
36+
blame("dflt-dns"),
37+
data=provider_secret.model.data,
38+
secret_type=provider_secret.model.type,
39+
labels={"kuadrant.io/default-provider": "true", "app": module_label},
40+
)
41+
request.addfinalizer(default_secret.delete)
42+
default_secret.commit()
43+
44+
45+
@pytest.fixture(scope="module")
46+
def dns_policy(blame, gateway, module_label):
47+
"""Return DNSPolicy without proivderRefs configured"""
48+
return DNSPolicy.create_instance(gateway.cluster, blame("dns"), gateway, labels={"app": module_label})
49+
50+
51+
@pytest.fixture(scope="module", autouse=True)
52+
def commit(request, dns_provider_secret, dns_policy): # pylint: disable=unused-argument
53+
"""Commits all important stuff before tests"""
54+
request.addfinalizer(dns_policy.delete)
55+
dns_policy.commit()
56+
dns_policy.wait_for_ready()
57+
58+
59+
def test_default_dns_provider(gateway, dns_policy, client):
60+
"""Test if default DNS provider secret is picked up and used"""
61+
assert gateway.refresh().is_affected_by(dns_policy)
62+
response = client.get("/get")
63+
assert response.status_code == 200
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
"""Test what happens when 2 default DNS provider secrets exist at the same time"""
2+
3+
import pytest
4+
5+
import openshift_client as oc
6+
7+
from testsuite.kubernetes.secret import Secret
8+
from testsuite.kuadrant.policy import has_condition
9+
from testsuite.kuadrant.policy.dns import DNSPolicy, has_record_condition
10+
11+
pytestmark = [pytest.mark.kuadrant_only, pytest.mark.dnspolicy, pytest.mark.disruptive]
12+
13+
14+
@pytest.fixture(scope="module")
15+
def default_provider_secrets(request, dns_provider_secret, cluster, blame, module_label):
16+
"""Create two default DNS provider secrets from existing, non-default provider"""
17+
provider_secret = oc.selector(f"secret/{dns_provider_secret}", static_context=cluster.context).object(cls=Secret)
18+
for _ in range(2):
19+
default_secret = Secret.create_instance(
20+
cluster,
21+
blame("dflt-dns"),
22+
data=provider_secret.model.data,
23+
secret_type=provider_secret.model.type,
24+
labels={"kuadrant.io/default-provider": "true", "app": module_label},
25+
)
26+
request.addfinalizer(default_secret.delete)
27+
default_secret.commit()
28+
29+
30+
@pytest.fixture(scope="module")
31+
def dns_policy(blame, gateway, module_label):
32+
"""Return DNSPolicy with delegate true and providerRefs secret"""
33+
return DNSPolicy.create_instance(gateway.cluster, blame("dns"), gateway, labels={"app": module_label})
34+
35+
36+
@pytest.fixture(scope="module", autouse=True)
37+
def commit(request, route, default_provider_secrets, dns_policy): # pylint: disable=unused-argument
38+
"""Commits all important stuff before tests"""
39+
request.addfinalizer(dns_policy.delete)
40+
dns_policy.commit()
41+
42+
43+
def test_multiple_default_provider_secrets(dns_policy):
44+
"""Check that authoritative DNSRecord ends up in error state when multiple default provider secrets exist"""
45+
assert dns_policy.wait_until(
46+
has_condition("Enforced", "False", "Unknown", "not a single DNSRecord is ready")
47+
), f"DNSPolicy did not reach expected status, instead it was: {dns_policy.model.status.conditions}"
48+
assert dns_policy.wait_until(
49+
has_record_condition(
50+
"Ready", "False", "DNSProviderError", "Multiple default providers secrets found. Only one expected"
51+
)
52+
), f"Authoritative DNSRecord didn't reach expected status, instead it was: {dns_policy.model.status.conditions}"
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"""Test DNSPolicy behavior with no default DNS provider secret available"""
2+
3+
import pytest
4+
5+
from testsuite.kuadrant.policy import has_condition
6+
from testsuite.kuadrant.policy.dns import DNSPolicy, has_record_condition
7+
8+
pytestmark = [pytest.mark.kuadrant_only, pytest.mark.dnspolicy, pytest.mark.disruptive]
9+
10+
11+
@pytest.fixture(scope="module")
12+
def dns_policy(blame, gateway, module_label):
13+
"""Return DNSPolicy without proivderRefs configured"""
14+
return DNSPolicy.create_instance(gateway.cluster, blame("dns"), gateway, labels={"app": module_label})
15+
16+
17+
@pytest.fixture(scope="module", autouse=True)
18+
def commit(request, route, dns_policy): # pylint: disable=unused-argument
19+
"""Commits all important stuff before tests"""
20+
request.addfinalizer(dns_policy.delete)
21+
dns_policy.commit()
22+
23+
24+
def test_no_default_provider_secrets(dns_policy):
25+
"""Test that DNSPolicy and DNSRecord both end up in error state, when no default provider secret exists"""
26+
assert dns_policy.wait_until(
27+
has_condition("Enforced", "False", "Unknown", "not a single DNSRecord is ready")
28+
), f"DNSPolicy did not reach expected status, instead it was: {dns_policy.model.status.conditions}"
29+
assert dns_policy.wait_until(
30+
has_record_condition(
31+
"Ready",
32+
"False",
33+
"DNSProviderError",
34+
"No default provider secret labeled kuadrant.io/default-provider was found",
35+
)
36+
), f"DNSPolicy's DNSRecord didn't reach expected status, instead it was: {dns_policy.model.status.conditions}"
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""Test that server raises error when both delegate is true and providerRefs are set"""
2+
3+
import pytest
4+
5+
from openshift_client import OpenShiftPythonException
6+
7+
from testsuite.kuadrant.policy.dns import DNSPolicy
8+
9+
pytestmark = [pytest.mark.kuadrant_only, pytest.mark.dnspolicy]
10+
11+
12+
@pytest.fixture(scope="module")
13+
def dns_policy(blame, gateway, module_label, dns_provider_secret):
14+
"""Return DNSPolicy with delegate true and providerRefs secret"""
15+
return DNSPolicy.create_instance(
16+
gateway.cluster, blame("dns"), gateway, dns_provider_secret, delegate=True, labels={"app": module_label}
17+
)
18+
19+
20+
@pytest.fixture(scope="module", autouse=True)
21+
def commit():
22+
"""Commiting is done inside the test"""
23+
24+
25+
def test_delegate_true_and_provider_ref_are_mutually_exclusive(dns_policy):
26+
"""Test that server raises error when both delegate is true and providerRefs are set"""
27+
with pytest.raises(OpenShiftPythonException, match="delegate=true and providerRefs are mutually exclusive"):
28+
dns_policy.commit()
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""Test DNSPolicy behavior with a non-existing DNS provider secret"""
2+
3+
import pytest
4+
5+
from testsuite.kuadrant.policy import has_condition
6+
from testsuite.kuadrant.policy.dns import has_record_condition
7+
from testsuite.kuadrant.policy.dns import DNSPolicy
8+
9+
pytestmark = [pytest.mark.kuadrant_only, pytest.mark.dnspolicy]
10+
11+
NON_EXISTING_SECRET = "should-not-exist"
12+
13+
14+
@pytest.fixture(scope="module")
15+
def dns_policy(blame, gateway, module_label):
16+
"""Returns DNSPolicy fixture referencing a non-existing secret"""
17+
return DNSPolicy.create_instance(
18+
gateway.cluster, blame("dns"), gateway, NON_EXISTING_SECRET, labels={"app": module_label}
19+
)
20+
21+
22+
@pytest.fixture(scope="module", autouse=True)
23+
def commit(request, route, dns_policy): # pylint: disable=unused-argument
24+
"""Commits all important stuff before tests"""
25+
request.addfinalizer(dns_policy.delete)
26+
dns_policy.commit()
27+
28+
29+
def test_default_secret_provider_not_found(dns_policy):
30+
"""Assert DNSPolicy and DNSRecord both end up in error state, with DNS provider secret does not exist message"""
31+
assert dns_policy.wait_until(
32+
has_condition("Enforced", "False", "Unknown", "not a single DNSRecord is ready")
33+
), f"DNSPolicy did not reach expected status, instead it was: {dns_policy.model.status.conditions}"
34+
assert dns_policy.wait_until(
35+
has_record_condition(
36+
"Ready",
37+
"False",
38+
"DNSProviderError",
39+
f'The dns provider could not be loaded: Secret "{NON_EXISTING_SECRET}" not found',
40+
)
41+
), f"DNSPolicy did not reach expected record status, instead it was: {dns_policy.model.status.recordConditions}"

0 commit comments

Comments
 (0)