signals.py 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. from django.db.models.signals import post_delete, post_save, pre_delete
  2. from django.dispatch import receiver
  3. from dcim.models import Device
  4. from virtualization.models import VirtualMachine
  5. from .models import IPAddress, Prefix
  6. def update_parents_children(prefix):
  7. """
  8. Update depth on prefix & containing prefixes
  9. """
  10. parents = prefix.get_parents(include_self=True).annotate_hierarchy()
  11. for parent in parents:
  12. parent._children = parent.hierarchy_children
  13. Prefix.objects.bulk_update(parents, ['_children'], batch_size=100)
  14. def update_children_depth(prefix):
  15. """
  16. Update children count on prefix & contained prefixes
  17. """
  18. children = prefix.get_children(include_self=True).annotate_hierarchy()
  19. for child in children:
  20. child._depth = child.hierarchy_depth
  21. Prefix.objects.bulk_update(children, ['_depth'], batch_size=100)
  22. @receiver(post_save, sender=Prefix)
  23. def handle_prefix_saved(instance, created, **kwargs):
  24. # Prefix has changed (or new instance has been created)
  25. if created or instance.vrf != instance._vrf or instance.prefix != instance._prefix:
  26. update_parents_children(instance)
  27. update_children_depth(instance)
  28. # If this is not a new prefix, clean up parent/children of previous prefix
  29. if not created:
  30. old_prefix = Prefix(vrf=instance._vrf, prefix=instance._prefix)
  31. update_parents_children(old_prefix)
  32. update_children_depth(old_prefix)
  33. @receiver(post_delete, sender=Prefix)
  34. def handle_prefix_deleted(instance, **kwargs):
  35. update_parents_children(instance)
  36. update_children_depth(instance)
  37. @receiver(pre_delete, sender=IPAddress)
  38. def clear_primary_ip(instance, **kwargs):
  39. """
  40. When an IPAddress is deleted, trigger save() on any Devices/VirtualMachines for which it
  41. was a primary IP.
  42. """
  43. field_name = f'primary_ip{instance.family}'
  44. device = Device.objects.filter(**{field_name: instance}).first()
  45. if device:
  46. device.save()
  47. virtualmachine = VirtualMachine.objects.filter(**{field_name: instance}).first()
  48. if virtualmachine:
  49. virtualmachine.save()