fhrp.py 3.3 KB

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