netbox-ddns/netbox_ddns/admin.py

115 lines
3.9 KiB
Python

import logging
from django.contrib import admin, messages
from django.contrib.admin.filters import SimpleListFilter
from django.contrib.admin.options import ModelAdmin
from django.db.models import QuerySet
from django.http.request import HttpRequest
from django.utils.translation import gettext_lazy as _
from ipam.models import IPAddress
from netbox.admin import admin_site
from .background_tasks import update_dns
from .models import ReverseZone, Server, Zone
logger = logging.getLogger('netbox_ddns')
class IPFamilyFilter(SimpleListFilter):
title = _('Prefix family')
parameter_name = 'family'
def lookups(self, request: HttpRequest, model_admin: ModelAdmin):
return (
('ipv4', _('IPv4')),
('ipv6', _('IPv6')),
)
def queryset(self, request: HttpRequest, queryset: QuerySet):
if self.value() == 'ipv4':
return queryset.filter(prefix__family=4)
if self.value() == 'ipv6':
return queryset.filter(prefix__family=6)
class ZoneInlineAdmin(admin.TabularInline):
model = Zone
class ReverseZoneInlineAdmin(admin.TabularInline):
model = ReverseZone
@admin.register(Server, site=admin_site)
class ServerAdmin(admin.ModelAdmin):
list_display = ('server', 'tsig_key_name', 'tsig_algorithm')
inlines = [
ZoneInlineAdmin,
ReverseZoneInlineAdmin,
]
@admin.register(Zone, site=admin_site)
class ZoneAdmin(admin.ModelAdmin):
list_display = ('name', 'server')
actions = [
'update_all_records'
]
def update_all_records(self, request: HttpRequest, queryset: QuerySet):
for zone in queryset:
counter = 0
# Find all more-specific zones
more_specifics = Zone.objects.filter(name__endswith=zone.name).exclude(pk=zone.pk)
# Find all IPAddress objects in this zone but not in the more-specifics
addresses = IPAddress.objects.filter(dns_name__endswith=zone.name)
for more_specific in more_specifics:
addresses = addresses.exclude(dns_name__endswith=more_specific.name)
for address in addresses:
if address.dns_name:
update_dns.delay(
new_address=address.address.ip,
new_dns_name=address.dns_name,
skip_reverse=True
)
counter += 1
messages.info(request, _("Updating {count} forward records in {name}").format(count=counter,
name=zone.name))
@admin.register(ReverseZone, site=admin_site)
class ReverseZoneAdmin(admin.ModelAdmin):
list_display = ('prefix', 'name', 'server')
list_filter = [IPFamilyFilter]
actions = [
'update_all_records'
]
def update_all_records(self, request: HttpRequest, queryset: QuerySet):
for zone in queryset:
counter = 0
# Find all more-specific zones
more_specifics = ReverseZone.objects.filter(prefix__net_contained=zone.prefix).exclude(pk=zone.pk)
# Find all IPAddress objects in this zone but not in the more-specifics
addresses = IPAddress.objects.filter(address__net_contained=zone.prefix)
for more_specific in more_specifics:
addresses = addresses.exclude(address__net_contained=more_specific.prefix)
for address in addresses:
if address.dns_name:
update_dns.delay(
new_address=address.address.ip,
new_dns_name=address.dns_name,
skip_forward=True
)
counter += 1
messages.info(request, _("Updating {count} reverse records in {name}").format(count=counter,
name=zone.name))