new file: netbox_dns_bridge/jobs/__init__.py renamed: netbox_dns_bridge/signals/notify_handler.py -> netbox_dns_bridge/jobs/notify.py modified: netbox_dns_bridge/management/commands/dns_transfer_endpoint/catalog_zone_manager.py modified: netbox_dns_bridge/signals/netbox_dns_zones.py Restructuring modified: netbox_dns_bridge/tests/conftest.py renamed: netbox_dns_bridge/tests/test_notify_handler.py -> netbox_dns_bridge/tests/test_notify.py modified: netbox_dns_bridge/tests/test_signals.py AI updated tests, not manually verified.
97 lines
3.4 KiB
Python
97 lines
3.4 KiB
Python
from django.db.models.signals import pre_save, post_save, post_delete
|
|
from django.dispatch import receiver
|
|
from django.db import transaction
|
|
from netbox.context import current_request
|
|
from netbox_dns.models import Zone, View
|
|
from netbox_dns_bridge.management.commands.dns_transfer_endpoint import catalog_zone_manager as catzm
|
|
from netbox_dns_bridge.jobs import notify
|
|
|
|
|
|
@receiver(pre_save, sender=Zone)
|
|
def zone_pre_save(sender, instance, **kwargs):
|
|
zone = instance
|
|
if zone.pk:
|
|
try:
|
|
old = sender.objects.only("name", "soa_serial", "view_id").get(pk=zone.pk)
|
|
zone._old_name = old.name
|
|
zone._old_soa_serial = old.soa_serial
|
|
zone._old_view_id = old.view_id
|
|
except sender.DoesNotExist:
|
|
zone._old_name = None
|
|
zone._old_soa_serial = None
|
|
zone._old_view_id = None
|
|
else:
|
|
zone._old_name = None
|
|
zone._old_soa_serial = None
|
|
zone._old_view_id = None
|
|
|
|
|
|
@receiver(post_save, sender=Zone)
|
|
def zone_post_save(sender, instance, created, **kwargs):
|
|
zone = instance
|
|
|
|
# Quit if this is not the first signal in this session for this zone.
|
|
try:
|
|
request = current_request.get()
|
|
if request is None:
|
|
raise LookupError
|
|
handled_zones = getattr(request, "_handled_zones", set())
|
|
if zone.pk in handled_zones:
|
|
return
|
|
handled_zones.add(zone.pk)
|
|
request._handled_zones = handled_zones
|
|
except LookupError:
|
|
pass
|
|
|
|
# Determine whether the zone's SOA serial number changed with this save.
|
|
# A newly created zone is always considered to have a "changed" serial.
|
|
old_soa_serial = getattr(zone, "_old_soa_serial", None)
|
|
new_soa_serial = getattr(zone, "soa_serial", None)
|
|
soa_serial_changed = created or (old_soa_serial != new_soa_serial)
|
|
|
|
# Detect whether the zone moved between views. When it does, the old
|
|
# view's catalog zone loses a member and the new view's gains one, so
|
|
# both serials must be incremented.
|
|
old_view_id = getattr(zone, "_old_view_id", None)
|
|
view_changed = (
|
|
not created
|
|
and old_view_id is not None
|
|
and old_view_id != zone.view_id
|
|
)
|
|
|
|
# On commit, increment soa serial and schedule notify jobs. All settings
|
|
# gating happens inside the scheduling functions.
|
|
def _on_commit():
|
|
if view_changed:
|
|
try:
|
|
old_view = View.objects.get(pk=old_view_id)
|
|
catzm.increment_soa_serial(old_view)
|
|
except View.DoesNotExist:
|
|
pass
|
|
catzm.increment_soa_serial(zone.view)
|
|
|
|
if soa_serial_changed:
|
|
notify.schedule_client_notify(zone)
|
|
notify.schedule_ns_notify(zone)
|
|
|
|
transaction.on_commit(_on_commit)
|
|
|
|
if created:
|
|
# If zone was created, create catz member identifier record for this zone.
|
|
catzm.update_member_identifier(zone)
|
|
else:
|
|
# Re-create the catz member identifier when the zone name or its view
|
|
# changed. A view move leaves the identifier pointing at the wrong
|
|
# catalog zone, so it must be refreshed.
|
|
old_name = getattr(zone, "_old_name", None)
|
|
if (old_name and zone.name != old_name) or view_changed:
|
|
catzm.update_member_identifier(zone)
|
|
|
|
|
|
@receiver(post_delete, sender=Zone)
|
|
def zone_post_delete(sender, instance, **kwargs):
|
|
def _on_commit():
|
|
catzm.increment_soa_serial(instance.view)
|
|
|
|
transaction.on_commit(_on_commit)
|