Update status when no zone is found

This commit is contained in:
Sander Steffann 2020-04-19 22:23:53 +02:00
parent 2bc5f9f204
commit cbc99e76c1
3 changed files with 36 additions and 27 deletions

View file

@ -9,7 +9,7 @@ from django_rq import job
from dns import rcode from dns import rcode
from netaddr import ip from netaddr import ip
from netbox_ddns.models import ACTION_CREATE, ACTION_DELETE, DNSStatus, ReverseZone, Zone from netbox_ddns.models import ACTION_CREATE, ACTION_DELETE, DNSStatus, RCODE_NO_ZONE, ReverseZone, Zone
from netbox_ddns.utils import get_soa from netbox_ddns.utils import get_soa
logger = logging.getLogger('netbox_ddns') logger = logging.getLogger('netbox_ddns')
@ -29,11 +29,12 @@ def status_update(output: List[str], operation: str, response) -> None:
def create_forward(dns_name: str, address: ip.IPAddress, status: Optional[DNSStatus], output: List[str]): def create_forward(dns_name: str, address: ip.IPAddress, status: Optional[DNSStatus], output: List[str]):
if status:
status.forward_action = ACTION_CREATE
zone = Zone.objects.find_for_dns_name(dns_name) zone = Zone.objects.find_for_dns_name(dns_name)
if zone: if zone:
logger.debug(f"Found zone {zone.name} for {dns_name}") logger.debug(f"Found zone {zone.name} for {dns_name}")
if status:
status.forward_action = ACTION_CREATE
# Check the SOA, we don't want to write to a parent zone if it has delegated authority # Check the SOA, we don't want to write to a parent zone if it has delegated authority
soa = get_soa(dns_name) soa = get_soa(dns_name)
@ -57,14 +58,17 @@ def create_forward(dns_name: str, address: ip.IPAddress, status: Optional[DNSSta
status.forward_rcode = rcode.NOTAUTH status.forward_rcode = rcode.NOTAUTH
else: else:
logger.debug(f"No zone found for {dns_name}") logger.debug(f"No zone found for {dns_name}")
if status:
status.forward_rcode = RCODE_NO_ZONE
def delete_forward(dns_name: str, address: ip.IPAddress, status: Optional[DNSStatus], output: List[str]): def delete_forward(dns_name: str, address: ip.IPAddress, status: Optional[DNSStatus], output: List[str]):
if status:
status.forward_action = ACTION_DELETE
zone = Zone.objects.find_for_dns_name(dns_name) zone = Zone.objects.find_for_dns_name(dns_name)
if zone: if zone:
logger.debug(f"Found zone {zone.name} for {dns_name}") logger.debug(f"Found zone {zone.name} for {dns_name}")
if status:
status.forward_action = ACTION_DELETE
# Check the SOA, we don't want to write to a parent zone if it has delegated authority # Check the SOA, we don't want to write to a parent zone if it has delegated authority
soa = get_soa(dns_name) soa = get_soa(dns_name)
@ -87,15 +91,18 @@ def delete_forward(dns_name: str, address: ip.IPAddress, status: Optional[DNSSta
status.forward_rcode = rcode.NOTAUTH status.forward_rcode = rcode.NOTAUTH
else: else:
logger.debug(f"No zone found for {dns_name}") logger.debug(f"No zone found for {dns_name}")
if status:
status.forward_rcode = RCODE_NO_ZONE
def create_reverse(dns_name: str, address: ip.IPAddress, status: Optional[DNSStatus], output: List[str]): def create_reverse(dns_name: str, address: ip.IPAddress, status: Optional[DNSStatus], output: List[str]):
if status:
status.reverse_action = ACTION_CREATE
zone = ReverseZone.objects.find_for_address(address) zone = ReverseZone.objects.find_for_address(address)
if zone and dns_name: if zone:
record_name = zone.record_name(address) record_name = zone.record_name(address)
logger.debug(f"Found zone {zone.name} for {record_name}") logger.debug(f"Found zone {zone.name} for {record_name}")
if status:
status.reverse_action = ACTION_CREATE
# Check the SOA, we don't want to write to a parent zone if it has delegated authority # Check the SOA, we don't want to write to a parent zone if it has delegated authority
soa = get_soa(record_name) soa = get_soa(record_name)
@ -118,15 +125,18 @@ def create_reverse(dns_name: str, address: ip.IPAddress, status: Optional[DNSSta
status.reverse_rcode = rcode.NOTAUTH status.reverse_rcode = rcode.NOTAUTH
else: else:
logger.debug(f"No zone found for {address}") logger.debug(f"No zone found for {address}")
if status:
status.reverse_rcode = RCODE_NO_ZONE
def delete_reverse(dns_name: str, address: ip.IPAddress, status: Optional[DNSStatus], output: List[str]): def delete_reverse(dns_name: str, address: ip.IPAddress, status: Optional[DNSStatus], output: List[str]):
if status:
status.reverse_action = ACTION_DELETE
zone = ReverseZone.objects.find_for_address(address) zone = ReverseZone.objects.find_for_address(address)
if zone and dns_name: if zone:
record_name = zone.record_name(address) record_name = zone.record_name(address)
logger.debug(f"Found zone {zone.name} for {record_name}") logger.debug(f"Found zone {zone.name} for {record_name}")
if status:
status.reverse_action = ACTION_DELETE
# Check the SOA, we don't want to write to a parent zone if it has delegated authority # Check the SOA, we don't want to write to a parent zone if it has delegated authority
soa = get_soa(record_name) soa = get_soa(record_name)
@ -148,6 +158,8 @@ def delete_reverse(dns_name: str, address: ip.IPAddress, status: Optional[DNSSta
status.reverse_rcode = rcode.NOTAUTH status.reverse_rcode = rcode.NOTAUTH
else: else:
logger.debug(f"No zone found for {address}") logger.debug(f"No zone found for {address}")
if status:
status.reverse_rcode = RCODE_NO_ZONE
@job @job

View file

@ -37,6 +37,9 @@ ACTION_CHOICES = (
(ACTION_DELETE, 'Delete'), (ACTION_DELETE, 'Delete'),
) )
# Use a private rcode for internal errors
RCODE_NO_ZONE = 4095
def get_rcode_display(code): def get_rcode_display(code):
if code is None: if code is None:
@ -53,6 +56,8 @@ def get_rcode_display(code):
return _('Refused') return _('Refused')
elif code == rcode.NOTAUTH: elif code == rcode.NOTAUTH:
return _('Server not authoritative') return _('Server not authoritative')
elif code == RCODE_NO_ZONE:
return _('No zone configured')
else: else:
return _('Unknown response: {}').format(code) return _('Unknown response: {}').format(code)

View file

@ -67,9 +67,8 @@ class IPAddressDNSNameRecreateView(PermissionRequiredMixin, View):
new_dns_name = normalize_fqdn(ip_address.dns_name) new_dns_name = normalize_fqdn(ip_address.dns_name)
updated_names = [] updated_names = []
zoneless_names = []
if new_dns_name and Zone.objects.find_for_dns_name(new_dns_name): if new_dns_name:
status, created = DNSStatus.objects.get_or_create(ip_address=ip_address) status, created = DNSStatus.objects.get_or_create(ip_address=ip_address)
dns_create.delay( dns_create.delay(
@ -79,28 +78,21 @@ class IPAddressDNSNameRecreateView(PermissionRequiredMixin, View):
) )
updated_names.append(new_dns_name) updated_names.append(new_dns_name)
else:
zoneless_names.append(new_dns_name)
for extra in ip_address.extradnsname_set.all(): for extra in ip_address.extradnsname_set.all():
new_address = extra.ip_address.address.ip new_address = extra.ip_address.address.ip
new_dns_name = extra.name new_dns_name = extra.name
if Zone.objects.find_for_dns_name(new_dns_name): dns_create.delay(
dns_create.delay( dns_name=new_dns_name,
dns_name=new_dns_name, address=new_address,
address=new_address, status=extra,
status=extra, reverse=False,
reverse=False, )
)
updated_names.append(new_dns_name) updated_names.append(new_dns_name)
else:
zoneless_names.append(new_dns_name)
if updated_names: if updated_names:
messages.info(request, _("Updating DNS for {names}").format(names=', '.join(updated_names))) messages.info(request, _("Updating DNS for {names}").format(names=', '.join(updated_names)))
if zoneless_names:
messages.warning(request, _("No DNS zone configured for {names}").format(names=', '.join(zoneless_names)))
return redirect('ipam:ipaddress', pk=ip_address.pk) return redirect('ipam:ipaddress', pk=ip_address.pk)