import unittest from dataclasses import dataclass, field from datetime import datetime, timezone from dns_sync.adapters import ( CERTIFICATES, DNS_RECORDS, PROXY_HOSTS, Capability, CapabilityOperation, DiscoveredObject, Endpoint, NormalizedObject, ObjectReference, Observation, ) from dns_sync.orchestrator import discover_reconcile_plan from dns_sync.reconciliation import ReconciliationConflict from dns_sync.persistence import SQLiteStateStore T1 = datetime( 2026, 9, 20, 8, 0, tzinfo=timezone.utc ) T2 = datetime( 2026, 9, 20, 9, 0, tzinfo=timezone.utc ) @dataclass class FakeAdapter: endpoint: Endpoint capabilities: frozenset[Capability] discovered: dict[str, list[DiscoveredObject]] = field( default_factory=dict ) failures: dict[str, str] = field( default_factory=dict ) def connect(self) -> None: return None def discover( self, object_type: str, ) -> list[DiscoveredObject]: if object_type in self.failures: raise RuntimeError( self.failures[object_type] ) return list( self.discovered.get( object_type, [], ) ) def capability_set( *object_types: str, apply: bool = False, ) -> frozenset[Capability]: rows = { Capability( object_type, CapabilityOperation.DISCOVER, ) for object_type in object_types } if apply: rows.update( Capability( object_type, CapabilityOperation.APPLY, ) for object_type in object_types ) return frozenset(rows) def normalized_certificate( local_key: str, *, valid_from: str, expires_on: str, ) -> NormalizedObject: return NormalizedObject( object_type=CERTIFICATES, logical_key="app.example.com", local_key=local_key, payload={ "domain_names": ["app.example.com"], "provider": "other", "valid_from": valid_from, "expires_on": expires_on, }, ) def discovered_certificate( local_key: str, *, valid_from: str, expires_on: str, ) -> DiscoveredObject: return DiscoveredObject( object_type=CERTIFICATES, local_key=local_key, payload={ "domain_names": ["app.example.com"], "provider": "other", "valid_from": valid_from, "expires_on": expires_on, }, ) def normalized_proxy( local_key: str, ) -> NormalizedObject: return NormalizedObject( object_type=PROXY_HOSTS, logical_key="app.example.com", local_key=local_key, payload={ "domain_names": ["app.example.com"], "forward_scheme": "http", "forward_host": "backend.internal", "forward_port": 8080, "enabled": True, }, ) class ObservationAuthorityTests(unittest.TestCase): def test_failed_newer_certificate_cache_cannot_override_live_certificate(self): live_endpoint = Endpoint( "npm", "192.168.1.3:81", ) failed_endpoint = Endpoint( "npm", "192.168.1.4:81", ) live = FakeAdapter( endpoint=live_endpoint, capabilities=capability_set( CERTIFICATES, ), discovered={ CERTIFICATES: [ discovered_certificate( "20", valid_from=( "2026-09-15T00:00:00+00:00" ), expires_on=( "2026-12-15T00:00:00+00:00" ), ) ] }, ) failed = FakeAdapter( endpoint=failed_endpoint, capabilities=capability_set( CERTIFICATES, apply=True, ), failures={ CERTIFICATES: "offline" }, ) cached_newer = normalized_certificate( "99", valid_from=( "2026-09-19T00:00:00+00:00" ), expires_on=( "2026-12-19T00:00:00+00:00" ), ) with SQLiteStateStore(":memory:") as store: store.replace_observations( failed_endpoint.identity, CERTIFICATES, [ Observation( failed_endpoint.identity, cached_newer, T1, ) ], T1, ) result = discover_reconcile_plan( [ live, failed, ], store, target_ip="192.168.1.101", run_at=T2, ) certificates = [ object for object in result.desired if object.object_type == CERTIFICATES ] self.assertEqual( len(certificates), 1, ) self.assertEqual( certificates[0].payload["valid_from"], "2026-09-15T00:00:00+00:00", ) # The failed target advertised APPLY, but it must not # receive a certificate mutation plan this run. self.assertEqual( result.plans, (), ) self.assertTrue( any( observation.endpoint_id == failed_endpoint.identity and observation.object.local_key == "99" for observation in result.observations ) ) def test_persisted_newer_certificate_cannot_regress_to_older_live_certificate( self, ): endpoint = Endpoint( "npm", "192.168.1.3:81", ) live = FakeAdapter( endpoint=endpoint, capabilities=capability_set( CERTIFICATES, apply=True, ), discovered={ CERTIFICATES: [ discovered_certificate( "20", valid_from=( "2026-09-15T00:00:00+00:00" ), expires_on=( "2026-12-15T00:00:00+00:00" ), ) ] }, ) persisted = normalized_certificate( "99", valid_from=( "2026-09-19T00:00:00+00:00" ), expires_on=( "2026-12-19T00:00:00+00:00" ), ) persisted = NormalizedObject( object_type=persisted.object_type, logical_key=persisted.logical_key, payload=dict(persisted.payload), ) with SQLiteStateStore(":memory:") as store: store.replace_desired_state( CERTIFICATES, [persisted], T1, ) result = discover_reconcile_plan( [live], store, target_ip="192.168.1.101", run_at=T2, ) stored = store.load_desired_state( CERTIFICATES ) certificates = [ object for object in result.desired if object.object_type == CERTIFICATES ] self.assertEqual(len(certificates), 1) self.assertEqual( certificates[0].payload["valid_from"], "2026-09-19T00:00:00+00:00", ) self.assertEqual( certificates[0].payload["expires_on"], "2026-12-19T00:00:00+00:00", ) self.assertEqual(len(stored), 1) self.assertEqual( stored[0].object, persisted, ) self.assertEqual(len(result.plans), 1) self.assertEqual( result.plans[0].endpoint_id, endpoint.identity, ) self.assertEqual( len(result.plans[0].actions), 1, ) self.assertEqual( result.plans[0].actions[0].operation.value, "replace", ) self.assertEqual( result.plans[0].actions[0].desired, persisted, ) def test_expired_certificate_on_disabled_proxy_is_removed_from_desired( self, ): endpoint = Endpoint( "npm", "192.168.1.3:81", ) adapter = FakeAdapter( endpoint=endpoint, capabilities=capability_set( CERTIFICATES, PROXY_HOSTS, ), discovered={ CERTIFICATES: [ DiscoveredObject( object_type=CERTIFICATES, local_key="56", payload={ "domain_names": [ "admin.trunavigate.org" ], "provider": "letsencrypt", "valid_from": None, "expires_on": ( "2026-06-22T03:40:57.000Z" ), }, ) ], PROXY_HOSTS: [ DiscoveredObject( object_type=PROXY_HOSTS, local_key="29", payload={ "domain_names": [ "admin.trunavigate.org" ], "forward_scheme": "http", "forward_host": "192.168.1.4", "forward_port": 3283, "enabled": False, }, references=( ObjectReference( relation="certificate", object_type=CERTIFICATES, local_key="56", ), ), ) ], }, ) with SQLiteStateStore(":memory:") as store: result = discover_reconcile_plan( [adapter], store, target_ip="192.168.1.101", run_at=T2, ) certificates = [ object for object in result.desired if object.object_type == CERTIFICATES ] proxies = [ object for object in result.desired if object.object_type == PROXY_HOSTS ] self.assertEqual(certificates, []) self.assertEqual(len(proxies), 1) self.assertEqual( proxies[0].logical_key, "admin.trunavigate.org", ) self.assertEqual( proxies[0].references, (), ) def test_expired_certificate_on_enabled_proxy_fails_closed( self, ): endpoint = Endpoint( "npm", "192.168.1.3:81", ) adapter = FakeAdapter( endpoint=endpoint, capabilities=capability_set( CERTIFICATES, PROXY_HOSTS, ), discovered={ CERTIFICATES: [ DiscoveredObject( object_type=CERTIFICATES, local_key="56", payload={ "domain_names": [ "active.example.com" ], "provider": "letsencrypt", "valid_from": None, "expires_on": ( "2026-06-22T03:40:57.000Z" ), }, ) ], PROXY_HOSTS: [ DiscoveredObject( object_type=PROXY_HOSTS, local_key="29", payload={ "domain_names": [ "active.example.com" ], "forward_scheme": "http", "forward_host": "192.168.1.4", "forward_port": 3283, "enabled": True, }, references=( ObjectReference( relation="certificate", object_type=CERTIFICATES, local_key="56", ), ), ) ], }, ) with SQLiteStateStore(":memory:") as store: with self.assertRaisesRegex( ReconciliationConflict, "Enabled proxy host references an expired certificate", ): discover_reconcile_plan( [adapter], store, target_ip="192.168.1.101", run_at=T2, ) def test_all_failed_sources_preserve_persisted_desired_without_planning(self): npm_endpoint = Endpoint( "npm", "192.168.1.3:81", ) npm = FakeAdapter( endpoint=npm_endpoint, capabilities=capability_set( PROXY_HOSTS, apply=True, ), failures={ PROXY_HOSTS: "offline" }, ) cached_proxy = normalized_proxy("12") previous_dns = NormalizedObject( object_type=DNS_RECORDS, logical_key="app.example.com", payload={ "hostname": "app.example.com", "ip_address": "192.168.1.101", }, ) with SQLiteStateStore(":memory:") as store: store.replace_observations( npm_endpoint.identity, PROXY_HOSTS, [ Observation( npm_endpoint.identity, cached_proxy, T1, ) ], T1, ) store.replace_desired_state( DNS_RECORDS, [previous_dns], T1, ) result = discover_reconcile_plan( [npm], store, target_ip="192.168.1.101", run_at=T2, ) persisted_dns = store.load_desired_state( DNS_RECORDS ) self.assertEqual( result.desired, (), ) self.assertEqual( result.plans, (), ) self.assertEqual( len(persisted_dns), 1, ) self.assertEqual( persisted_dns[0].object, previous_dns, ) if __name__ == "__main__": unittest.main()