from .models import DesiredRecord, ProviderRecord, SyncAction def hostname_matches_domain(hostname: str, domain: str) -> bool: """Match a domain apex and any subdomain, without suffix false positives.""" candidate = hostname.lower().rstrip(".") if candidate.startswith("*."): candidate = candidate[2:] base = domain.lower().rstrip(".") return candidate == base or candidate.endswith("." + base) def filter_desired_by_domain( records: list[DesiredRecord], domain: str | None, enabled: bool, ) -> tuple[list[DesiredRecord], int]: if not enabled: return records, 0 if not domain: raise RuntimeError( "Domain filtering enabled without a configured DOMAIN" ) matched = [ record for record in records if hostname_matches_domain(record.hostname, domain) ] return matched, len(records) - len(matched) def validate_desired(records: list[DesiredRecord]) -> tuple[dict[str, DesiredRecord], list[str]]: desired: dict[str, DesiredRecord] = {} warnings: list[str] = [] for record in records: key = record.hostname.lower() if key in desired: warnings.append( f"DUPLICATE {record.hostname} from {record.source}" + (f" id={record.source_id}" if record.source_id else "") + "; keeping first occurrence" ) continue desired[key] = record return dict(sorted(desired.items())), warnings def build_sync_plan(desired, current: dict[str, ProviderRecord], capabilities): plan: list[SyncAction] = [] for hostname, record in desired.items(): if record.record_type not in capabilities.record_types: plan.append(SyncAction("SKIP", record, reason=f"record type {record.record_type} unsupported")) continue if record.wildcard and not capabilities.wildcard_records: plan.append(SyncAction("SKIP", record, reason="wildcard records unsupported")) continue existing = current.get(hostname.lower()) if existing is None: if not capabilities.supports_create: plan.append(SyncAction("SKIP", record, reason="provider cannot create records")) else: plan.append(SyncAction("ADD", record)) elif existing.ip == record.ip and existing.record_type == record.record_type: plan.append(SyncAction("UNCHANGED", record, current=existing)) elif not capabilities.supports_update: plan.append(SyncAction("SKIP", record, current=existing, reason="provider cannot update records")) else: plan.append(SyncAction("UPDATE", record, current=existing)) return plan def summarize_plan(plan): counts = {name: 0 for name in ("ADD", "UPDATE", "UNCHANGED", "SKIP")} for item in plan: counts[item.action] = counts.get(item.action, 0) + 1 return counts def execute_sync(provider, plan): counts = summarize_plan(plan) for item in plan: if item.action in {"UNCHANGED", "SKIP"}: continue if item.action == "ADD": detail = provider.add_record(item.desired) elif item.action == "UPDATE": detail = provider.update_record(item.desired) else: raise RuntimeError(f"Unknown sync action: {item.action}") if not provider.verify_record(item.desired): raise RuntimeError(f"{item.desired.hostname}: {item.action.lower()} did not verify") suffix = f" ({detail})" if detail else "" print(f"APPLIED {item.action:<6} {item.desired.hostname} -> {item.desired.ip}{suffix}") return counts