fhrp.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
  2. from django.contrib.contenttypes.models import ContentType
  3. from django.core.validators import MaxValueValidator, MinValueValidator
  4. from django.db import models
  5. from django.urls import reverse
  6. from extras.utils import extras_features
  7. from netbox.models import ChangeLoggedModel, PrimaryModel
  8. from ipam.choices import *
  9. from ipam.constants import *
  10. __all__ = (
  11. 'FHRPGroup',
  12. 'FHRPGroupAssignment',
  13. )
  14. @extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks')
  15. class FHRPGroup(PrimaryModel):
  16. """
  17. A grouping of next hope resolution protocol (FHRP) peers. (For instance, VRRP or HSRP.)
  18. """
  19. group_id = models.PositiveSmallIntegerField(
  20. verbose_name='Group ID'
  21. )
  22. protocol = models.CharField(
  23. max_length=50,
  24. choices=FHRPGroupProtocolChoices
  25. )
  26. auth_type = models.CharField(
  27. max_length=50,
  28. choices=FHRPGroupAuthTypeChoices,
  29. blank=True,
  30. verbose_name='Authentication type'
  31. )
  32. auth_key = models.CharField(
  33. max_length=255,
  34. blank=True,
  35. verbose_name='Authentication key'
  36. )
  37. description = models.CharField(
  38. max_length=200,
  39. blank=True
  40. )
  41. ip_addresses = GenericRelation(
  42. to='ipam.IPAddress',
  43. content_type_field='assigned_object_type',
  44. object_id_field='assigned_object_id',
  45. related_query_name='fhrpgroup'
  46. )
  47. clone_fields = ('protocol', 'auth_type', 'auth_key')
  48. class Meta:
  49. ordering = ['protocol', 'group_id', 'pk']
  50. verbose_name = 'FHRP group'
  51. def __str__(self):
  52. name = f'{self.get_protocol_display()}: {self.group_id}'
  53. # Append the first assigned IP addresses (if any) to serve as an additional identifier
  54. if self.pk:
  55. ip_address = self.ip_addresses.first()
  56. if ip_address:
  57. return f"{name} ({ip_address})"
  58. return name
  59. def get_absolute_url(self):
  60. return reverse('ipam:fhrpgroup', args=[self.pk])
  61. @extras_features('webhooks')
  62. class FHRPGroupAssignment(ChangeLoggedModel):
  63. interface_type = models.ForeignKey(
  64. to=ContentType,
  65. on_delete=models.CASCADE
  66. )
  67. interface_id = models.PositiveIntegerField()
  68. interface = GenericForeignKey(
  69. ct_field='interface_type',
  70. fk_field='interface_id'
  71. )
  72. group = models.ForeignKey(
  73. to='ipam.FHRPGroup',
  74. on_delete=models.CASCADE
  75. )
  76. priority = models.PositiveSmallIntegerField(
  77. validators=(
  78. MinValueValidator(FHRPGROUPASSIGNMENT_PRIORITY_MIN),
  79. MaxValueValidator(FHRPGROUPASSIGNMENT_PRIORITY_MAX)
  80. )
  81. )
  82. clone_fields = ('interface_type', 'interface_id')
  83. class Meta:
  84. ordering = ('-priority', 'pk')
  85. unique_together = ('interface_type', 'interface_id', 'group')
  86. verbose_name = 'FHRP group assignment'
  87. def __str__(self):
  88. return f'{self.interface}: {self.group} ({self.priority})'
  89. def get_absolute_url(self):
  90. # Used primarily for redirection after creating a new assignment
  91. if self.interface:
  92. return self.interface.get_absolute_url()
  93. return None