This repository has been archived on 2026-10-28. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
karldns.de/karldns/dns/base.py
T

97 lines
3.3 KiB
Python
Raw Normal View History

2026-05-20 23:55:27 +02:00
from __future__ import annotations
2026-05-21 17:23:08 +02:00
from ..models import UpdateResult
from ..settings import DdnsSettings
2026-05-20 23:55:27 +02:00
SUPPORTED_DNS_PROVIDERS = {"", "cloudflare", "rfc2136"}
class DnsProviderError(RuntimeError):
"""Raised for expected DNS provider publish/delete failures."""
2026-05-21 10:05:40 +02:00
class DnsReconciliationError(DnsProviderError):
"""Raised when provider read-back does not match the requested DNS state."""
2026-05-20 23:55:27 +02:00
class DnsConfigurationError(RuntimeError):
"""Raised when DNS provider settings are invalid at startup."""
def publish_dns(result: UpdateResult, settings: DdnsSettings) -> None:
validate_dns_provider_settings(settings)
provider = _normalized_provider(settings)
if provider == "cloudflare":
from .cloudflare import publish_cloudflare
publish_cloudflare(result, settings)
return
if settings.rfc2136_server or provider == "rfc2136":
from .rfc2136 import publish_rfc2136
publish_rfc2136(result, settings)
return
if settings.require_dns_provider:
raise DnsProviderError("DNS provider is required but not configured")
def delete_dns_records(hostname: str, settings: DdnsSettings) -> None:
validate_dns_provider_settings(settings)
provider = _normalized_provider(settings)
if provider == "cloudflare":
from .cloudflare import delete_cloudflare_records
delete_cloudflare_records(hostname, settings)
return
if settings.rfc2136_server or provider == "rfc2136":
from .rfc2136 import delete_rfc2136_records
delete_rfc2136_records(hostname, settings)
return
if settings.require_dns_provider:
raise DnsProviderError("DNS provider is required but not configured")
def dns_backend_configured(settings: DdnsSettings) -> bool:
validate_dns_provider_settings(settings)
provider = _normalized_provider(settings)
return _dns_backend_enabled(provider, settings)
2026-05-20 23:55:27 +02:00
def validate_dns_provider_settings(settings: DdnsSettings) -> None:
provider = _normalized_provider(settings)
if provider not in SUPPORTED_DNS_PROVIDERS:
raise DnsConfigurationError(f"Unsupported DDNS_DNS_PROVIDER: {settings.dns_provider}")
if not settings.require_dns_provider:
return
if provider == "cloudflare":
_validate_cloudflare_settings(settings)
2026-05-20 23:55:27 +02:00
return
if _dns_backend_enabled(provider, settings):
_validate_rfc2136_settings(settings)
2026-05-20 23:55:27 +02:00
return
raise DnsConfigurationError("DDNS_REQUIRE_DNS_PROVIDER is set but no DNS backend is configured")
def _dns_backend_enabled(provider: str, settings: DdnsSettings) -> bool:
return provider == "cloudflare" or provider == "rfc2136" or bool(settings.rfc2136_server)
def _validate_cloudflare_settings(settings: DdnsSettings) -> None:
if settings.cloudflare_api_token and settings.cloudflare_zone_id:
return
raise DnsConfigurationError(
"DDNS_CLOUDFLARE_API_TOKEN and DDNS_CLOUDFLARE_ZONE_ID are required when DDNS_DNS_PROVIDER=cloudflare"
)
def _validate_rfc2136_settings(settings: DdnsSettings) -> None:
if settings.rfc2136_server and settings.rfc2136_zone:
return
raise DnsConfigurationError(
"DDNS_RFC2136_SERVER and DDNS_RFC2136_ZONE are required when RFC2136 DNS publishing is enabled"
)
2026-05-20 23:55:27 +02:00
def _normalized_provider(settings: DdnsSettings) -> str:
return settings.dns_provider.strip().lower()