Files
timmy-home/tests/test_sovereign_dns.py
Alexander Whitestone 1fed477af6
Some checks failed
Smoke Test / smoke (pull_request) Failing after 19s
feat: sovereign DNS record management (#692)
2026-04-14 23:59:30 -04:00

164 lines
5.1 KiB
Python

import json
import sys
from pathlib import Path
from types import SimpleNamespace
sys.path.insert(0, str(Path(__file__).resolve().parent.parent / 'scripts'))
from sovereign_dns import (
CloudflareDNSProvider,
Route53DNSProvider,
build_sync_plan,
detect_public_ip,
load_domain_mapping,
resolve_domain_ip_map,
)
def test_load_domain_mapping_reads_ansible_style_domain_to_ip_map(tmp_path):
cfg = tmp_path / 'dns_records.yaml'
cfg.write_text(
"""
dns_provider: cloudflare
dns_zone_id: zone-123
domain_ip_map:
forge.example.com: 1.2.3.4
matrix.example.com: 5.6.7.8
"""
)
loaded = load_domain_mapping(cfg)
assert loaded['dns_provider'] == 'cloudflare'
assert loaded['dns_zone_id'] == 'zone-123'
assert loaded['domain_ip_map'] == {
'forge.example.com': '1.2.3.4',
'matrix.example.com': '5.6.7.8',
}
def test_build_sync_plan_updates_changed_ip_and_creates_missing_records():
current = {
'forge.example.com': {'id': 'rec-1', 'content': '1.1.1.1'},
'old.example.com': {'id': 'rec-2', 'content': '9.9.9.9'},
}
desired = {
'forge.example.com': '2.2.2.2',
'new.example.com': '3.3.3.3',
}
plan = build_sync_plan(current=current, desired=desired)
assert plan['update'] == [
{'name': 'forge.example.com', 'id': 'rec-1', 'content': '2.2.2.2'}
]
assert plan['create'] == [
{'name': 'new.example.com', 'content': '3.3.3.3'}
]
assert plan['delete'] == [
{'name': 'old.example.com', 'id': 'rec-2'}
]
def test_resolve_domain_ip_map_replaces_auto_values_with_detected_public_ip():
resolved = resolve_domain_ip_map(
{
'forge.example.com': 'auto',
'matrix.example.com': '5.6.7.8',
},
current_public_ip='8.8.4.4',
)
assert resolved == {
'forge.example.com': '8.8.4.4',
'matrix.example.com': '5.6.7.8',
}
def test_detect_public_ip_reads_provider_response():
class FakeResponse:
def __enter__(self):
return self
def __exit__(self, exc_type, exc, tb):
return False
def read(self):
return b'4.3.2.1\n'
ip = detect_public_ip(lambda req, timeout=10: FakeResponse())
assert ip == '4.3.2.1'
def test_cloudflare_upsert_calls_expected_http_methods():
calls = []
def fake_request(method, path, payload=None):
calls.append({'method': method, 'path': path, 'payload': payload})
if method == 'GET':
return {'success': True, 'result': []}
return {'success': True, 'result': {'id': 'created-id'}}
provider = CloudflareDNSProvider(
api_token='tok',
zone_id='zone-1',
request_fn=fake_request,
)
provider.upsert_a_record('forge.example.com', '1.2.3.4')
assert calls[0]['method'] == 'GET'
assert calls[0]['path'] == '/zones/zone-1/dns_records?type=A&name=forge.example.com'
assert calls[1]['method'] == 'POST'
assert calls[1]['path'] == '/zones/zone-1/dns_records'
assert calls[1]['payload']['name'] == 'forge.example.com'
assert calls[1]['payload']['content'] == '1.2.3.4'
assert calls[1]['payload']['type'] == 'A'
def test_cloudflare_upsert_updates_when_record_exists():
calls = []
def fake_request(method, path, payload=None):
calls.append({'method': method, 'path': path, 'payload': payload})
if method == 'GET':
return {'success': True, 'result': [{'id': 'rec-123', 'content': '1.1.1.1'}]}
return {'success': True, 'result': {'id': 'rec-123'}}
provider = CloudflareDNSProvider(
api_token='tok',
zone_id='zone-1',
request_fn=fake_request,
)
provider.upsert_a_record('forge.example.com', '2.2.2.2')
assert calls[1]['method'] == 'PUT'
assert calls[1]['path'] == '/zones/zone-1/dns_records/rec-123'
assert calls[1]['payload']['content'] == '2.2.2.2'
def test_route53_sync_uses_change_batches():
batches = []
class FakeClient:
def change_resource_record_sets(self, HostedZoneId, ChangeBatch):
batches.append({'HostedZoneId': HostedZoneId, 'ChangeBatch': ChangeBatch})
return {'ChangeInfo': {'Status': 'PENDING'}}
provider = Route53DNSProvider(hosted_zone_id='ZONE123', client=FakeClient())
provider.apply_plan(
create=[{'name': 'new.example.com', 'content': '3.3.3.3'}],
update=[{'name': 'forge.example.com', 'id': 'ignored', 'content': '2.2.2.2'}],
delete=[{'name': 'old.example.com', 'id': 'ignored'}],
current={'old.example.com': {'content': '9.9.9.9'}},
)
batch = batches[0]
assert batch['HostedZoneId'] == 'ZONE123'
changes = batch['ChangeBatch']['Changes']
assert changes[0]['Action'] == 'CREATE'
assert changes[0]['ResourceRecordSet']['Name'] == 'new.example.com'
assert changes[1]['Action'] == 'UPSERT'
assert changes[1]['ResourceRecordSet']['Name'] == 'forge.example.com'
assert changes[2]['Action'] == 'DELETE'
assert changes[2]['ResourceRecordSet']['Name'] == 'old.example.com'