2
0

signals.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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_id != instance._vrf_id 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_id=instance._vrf_id, 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 was a primary IP.
  41. """
  42. field_name = f'primary_ip{instance.family}'
  43. if device := Device.objects.filter(**{field_name: instance}).first():
  44. device.snapshot()
  45. setattr(device, field_name, None)
  46. device.save()
  47. if virtualmachine := VirtualMachine.objects.filter(**{field_name: instance}).first():
  48. virtualmachine.snapshot()
  49. setattr(virtualmachine, field_name, None)
  50. virtualmachine.save()
  51. @receiver(pre_delete, sender=IPAddress)
  52. def clear_oob_ip(instance, **kwargs):
  53. """
  54. When an IPAddress is deleted, trigger save() on any Devices for which it was a OOB IP.
  55. """
  56. if device := Device.objects.filter(oob_ip=instance).first():
  57. device.snapshot()
  58. device.oob_ip = None
  59. device.save()