diff --git a/src/octodns_netbox_dns/__init__.py b/src/octodns_netbox_dns/__init__.py index 9f99416..4873f02 100644 --- a/src/octodns_netbox_dns/__init__.py +++ b/src/octodns_netbox_dns/__init__.py @@ -2,23 +2,20 @@ import logging from typing import Any, Literal import dns.rdata -import octodns.provider.base -import octodns.provider.plan import octodns.record +import octodns.source.base import octodns.zone import pynetbox.core.api import pynetbox.core.response -class NetBoxDNSSource(octodns.provider.base.BaseProvider): +class NetBoxDNSSource(octodns.source.base.BaseSource): """ OctoDNS provider for NetboxDNS """ SUPPORTS_GEO = False SUPPORTS_DYNAMIC = False - SUPPORTS_ROOT_NS = True - SUPPORTS_MULTIVALUE_PTR = True SUPPORTS: set[str] = { # noqa "A", "AAAA", @@ -59,15 +56,13 @@ class NetBoxDNSSource(octodns.provider.base.BaseProvider): ttl=3600, replace_duplicates=False, make_absolute=False, - *args, - **kwargs, ): """ Initialize the NetboxDNSSource """ self.log = logging.getLogger(f"NetboxDNSSource[{id}]") self.log.debug(f"__init__: {id=}, {url=}, {view=}, {replace_duplicates=}, {make_absolute=}") - super().__init__(id, *args, **kwargs) + super().__init__(id) self.api = pynetbox.core.api.Api(url, token) self.nb_view = self._get_nb_view(view) @@ -198,7 +193,7 @@ class NetBoxDNSSource(octodns.provider.base.BaseProvider): } case "SPF" | "TXT": - value = raw_value.replace(";", "\\;") + value = raw_value.replace(";", r"\;") case "SRV": value = { @@ -272,7 +267,7 @@ class NetBoxDNSSource(octodns.provider.base.BaseProvider): def populate( self, zone: octodns.zone.Zone, target: bool = False, lenient: bool = False - ) -> bool: + ) -> None: """ Get all the records of a zone from NetBox and add them to the OctoDNS zone @@ -282,17 +277,10 @@ class NetBoxDNSSource(octodns.provider.base.BaseProvider): """ self.log.info(f"populate -> '{zone.name}', target={target}, lenient={lenient}") - try: - records = self._format_nb_records(zone) - except LookupError: - return False - + records = self._format_nb_records(zone) for data in records: if len(data["values"]) == 1: data["value"] = data.pop("values")[0] - if target and data["type"] in ["NS", "SOA", "PTR"]: - self.log.debug(f"{data['type']} type not supported in target mode") - continue record = octodns.record.Record.new( zone=zone, name=data["name"], @@ -303,121 +291,3 @@ class NetBoxDNSSource(octodns.provider.base.BaseProvider): zone.add_record(record, lenient=lenient, replace=self.replace_duplicates) self.log.info(f"populate -> found {len(zone.records)} records for zone '{zone.name}'") - - return True - - def _include_change(self, change: octodns.record.change.Change) -> bool: - """Filter out record types which the provider can't create in netbox""" - if change.new._type in ["SOA", "PTR", "NS"]: - return False - - return True - - def _apply(self, plan: octodns.provider.plan.Plan) -> None: - """Apply the changes to the NetBox DNS zone.""" - self.log.debug(f"_apply: zone={plan.desired.name}, len(changes)={len(plan.changes)}") - - nb_zone = self._get_nb_zone(plan.desired.name, view=self.nb_view) - - for change in plan.changes: - match change: - case octodns.record.Create(): - name = change.new.name - if name == "": - name = "@" - - match change.new: - case octodns.record.ValueMixin(): - new = {repr(change.new.value)[1:-1]} - case octodns.record.ValuesMixin(): - new = {repr(v)[1:-1] for v in change.new.values} - case _: - raise ValueError - - for value in new: - nb_record = self.api.plugins.netbox_dns.records.create( - zone=nb_zone.id, - name=name, - type=change.new._type, - ttl=change.new.ttl, - value=value.replace("\\\\", "\\").replace("\\;", ";"), - disable_ptr=True, - ) - self.log.debug(f"{nb_record!r}") - - case octodns.record.Delete(): - name = change.existing.name - if name == "": - name = "@" - - nb_records = self.api.plugins.netbox_dns.records.filter( - zone_id=nb_zone.id, - name=change.existing.name, - type=change.existing._type, - ) - - match change.existing: - case octodns.record.ValueMixin(): - existing = {repr(change.existing.value)[1:-1]} - case octodns.record.ValuesMixin(): - existing = {repr(v)[1:-1] for v in change.existing.values} - case _: - raise ValueError - - for nb_record in nb_records: - for value in existing: - if nb_record.value == value: - self.log.debug( - f"{nb_record.id} {nb_record.name} {nb_record.type} {nb_record.value} {value}" - ) - self.log.debug(f"{nb_record.url} {nb_record.endpoint.url}") - nb_record.delete() - - case octodns.record.Update(): - name = change.existing.name - if name == "": - name = "@" - - nb_records = self.api.plugins.netbox_dns.records.filter( - zone_id=nb_zone.id, - name=name, - type=change.existing._type, - ) - - match change.existing: - case octodns.record.ValueMixin(): - existing = {repr(change.existing.value)[1:-1]} - case octodns.record.ValuesMixin(): - existing = {repr(v)[1:-1] for v in change.existing.values} - case _: - raise ValueError - - match change.new: - case octodns.record.ValueMixin(): - new = {repr(change.new.value)[1:-1]} - case octodns.record.ValuesMixin(): - new = {repr(v)[1:-1] for v in change.new.values} - case _: - raise ValueError - - delete = existing.difference(new) - update = existing.intersection(new) - create = new.difference(existing) - - for nb_record in nb_records: - if nb_record.value in delete: - nb_record.delete() - if nb_record.value in update: - nb_record.ttl = change.new.ttl - nb_record.save() - - for value in create: - nb_record = self.api.plugins.netbox_dns.records.create( - zone=nb_zone.id, - name=name, - type=change.new._type, - ttl=change.new.ttl, - value=value.replace("\\\\", "\\").replace("\\;", ";"), - disable_ptr=True, - ) - self.log.debug(f"{nb_record!r}")