Files
dns-sync/tests/test_projections.py
T

189 lines
5.1 KiB
Python

import unittest
from datetime import datetime, timezone
from dns_sync.adapters import (
CERTIFICATES,
PROXY_HOSTS,
NormalizedObject,
Observation,
)
from dns_sync.projections import project_proxy_hosts_to_dns
from dns_sync.reconciliation import reconcile_observations
NOW = datetime(2026, 9, 19, 23, 0, tzinfo=timezone.utc)
def proxy_host(
endpoint_id: str,
local_key: str,
domains: list[str],
forward_host: str,
*,
enabled: bool = True,
) -> Observation:
return Observation(
endpoint_id=endpoint_id,
object=NormalizedObject(
object_type=PROXY_HOSTS,
logical_key=",".join(sorted(domains)),
local_key=local_key,
payload={
"domain_names": domains,
"forward_scheme": "http",
"forward_host": forward_host,
"forward_port": 8080,
"enabled": enabled,
},
),
observed_at=NOW,
)
class ProxyHostDnsProjectionTests(unittest.TestCase):
def test_target_ip_replaces_npm_backend_address(self):
source = proxy_host(
"npm://192.168.1.3:81",
"12",
["app.example.com"],
forward_host="192.168.1.50",
)
projected = project_proxy_hosts_to_dns(
[source],
target_ip="192.168.1.101",
)
self.assertEqual(len(projected), 1)
record = projected[0]
self.assertEqual(record.object.logical_key, "app.example.com")
self.assertEqual(
record.object.payload["ip"],
"192.168.1.101",
)
self.assertNotEqual(
record.object.payload["ip"],
source.object.payload["forward_host"],
)
self.assertEqual(
record.endpoint_id,
"npm://192.168.1.3:81",
)
self.assertEqual(
record.object.local_key,
"12:app.example.com",
)
self.assertEqual(record.observed_at, NOW)
def test_domains_expand_to_individual_dns_records(self):
source = proxy_host(
"npm://192.168.1.3:81",
"12",
["app.example.com", "*.wild.example.com"],
forward_host="backend.internal",
)
projected = project_proxy_hosts_to_dns(
[source],
target_ip="192.168.1.101",
)
self.assertEqual(
tuple(item.object.logical_key for item in projected),
("*.wild.example.com", "app.example.com"),
)
wildcard = next(
item
for item in projected
if item.object.logical_key == "*.wild.example.com"
)
self.assertTrue(wildcard.object.payload["wildcard"])
self.assertTrue(
all(
item.object.payload["ip"] == "192.168.1.101"
for item in projected
)
)
def test_disabled_proxy_hosts_are_optional(self):
source = proxy_host(
"npm://192.168.1.3:81",
"12",
["disabled.example.com"],
forward_host="192.168.1.50",
enabled=False,
)
excluded = project_proxy_hosts_to_dns(
[source],
target_ip="192.168.1.101",
)
included = project_proxy_hosts_to_dns(
[source],
target_ip="192.168.1.101",
include_disabled=True,
)
self.assertEqual(excluded, [])
self.assertEqual(len(included), 1)
def test_non_proxy_observations_are_not_projected(self):
certificate = Observation(
endpoint_id="npm://192.168.1.3:81",
object=NormalizedObject(
object_type=CERTIFICATES,
logical_key="app.example.com",
local_key="67",
payload={"domain_names": ["app.example.com"]},
),
observed_at=NOW,
)
projected = project_proxy_hosts_to_dns(
[certificate],
target_ip="192.168.1.101",
)
self.assertEqual(projected, [])
def test_multiple_npm_nodes_form_one_dns_union(self):
observations = [
proxy_host(
"npm://192.168.1.3:81",
"12",
["one.example.com", "shared.example.com"],
forward_host="192.168.1.50",
),
proxy_host(
"npm://192.168.1.4:81",
"22",
["two.example.com", "shared.example.com"],
forward_host="192.168.1.60",
),
]
projected = project_proxy_hosts_to_dns(
observations,
target_ip="192.168.1.101",
)
desired = reconcile_observations(projected)
self.assertEqual(
tuple(item.logical_key for item in desired),
(
"one.example.com",
"shared.example.com",
"two.example.com",
),
)
self.assertTrue(
all(
item.payload["ip"] == "192.168.1.101"
for item in desired
)
)
if __name__ == "__main__":
unittest.main()