vrfs.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. from django.db import models
  2. from django.urls import reverse
  3. from extras.utils import extras_features
  4. from ipam.constants import *
  5. from netbox.models import PrimaryModel
  6. from utilities.querysets import RestrictedQuerySet
  7. __all__ = (
  8. 'RouteTarget',
  9. 'VRF',
  10. )
  11. @extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks')
  12. class VRF(PrimaryModel):
  13. """
  14. A virtual routing and forwarding (VRF) table represents a discrete layer three forwarding domain (e.g. a routing
  15. table). Prefixes and IPAddresses can optionally be assigned to VRFs. (Prefixes and IPAddresses not assigned to a VRF
  16. are said to exist in the "global" table.)
  17. """
  18. name = models.CharField(
  19. max_length=100
  20. )
  21. rd = models.CharField(
  22. max_length=VRF_RD_MAX_LENGTH,
  23. unique=True,
  24. blank=True,
  25. null=True,
  26. verbose_name='Route distinguisher',
  27. help_text='Unique route distinguisher (as defined in RFC 4364)'
  28. )
  29. tenant = models.ForeignKey(
  30. to='tenancy.Tenant',
  31. on_delete=models.PROTECT,
  32. related_name='vrfs',
  33. blank=True,
  34. null=True
  35. )
  36. enforce_unique = models.BooleanField(
  37. default=True,
  38. verbose_name='Enforce unique space',
  39. help_text='Prevent duplicate prefixes/IP addresses within this VRF'
  40. )
  41. description = models.CharField(
  42. max_length=200,
  43. blank=True
  44. )
  45. import_targets = models.ManyToManyField(
  46. to='ipam.RouteTarget',
  47. related_name='importing_vrfs',
  48. blank=True
  49. )
  50. export_targets = models.ManyToManyField(
  51. to='ipam.RouteTarget',
  52. related_name='exporting_vrfs',
  53. blank=True
  54. )
  55. objects = RestrictedQuerySet.as_manager()
  56. csv_headers = ['name', 'rd', 'tenant', 'enforce_unique', 'description']
  57. clone_fields = [
  58. 'tenant', 'enforce_unique', 'description',
  59. ]
  60. class Meta:
  61. ordering = ('name', 'rd', 'pk') # (name, rd) may be non-unique
  62. verbose_name = 'VRF'
  63. verbose_name_plural = 'VRFs'
  64. def __str__(self):
  65. if self.rd:
  66. return f'{self.name} ({self.rd})'
  67. return self.name
  68. def get_absolute_url(self):
  69. return reverse('ipam:vrf', args=[self.pk])
  70. def to_csv(self):
  71. return (
  72. self.name,
  73. self.rd,
  74. self.tenant.name if self.tenant else None,
  75. self.enforce_unique,
  76. self.description,
  77. )
  78. @extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks')
  79. class RouteTarget(PrimaryModel):
  80. """
  81. A BGP extended community used to control the redistribution of routes among VRFs, as defined in RFC 4364.
  82. """
  83. name = models.CharField(
  84. max_length=VRF_RD_MAX_LENGTH, # Same format options as VRF RD (RFC 4360 section 4)
  85. unique=True,
  86. help_text='Route target value (formatted in accordance with RFC 4360)'
  87. )
  88. description = models.CharField(
  89. max_length=200,
  90. blank=True
  91. )
  92. tenant = models.ForeignKey(
  93. to='tenancy.Tenant',
  94. on_delete=models.PROTECT,
  95. related_name='route_targets',
  96. blank=True,
  97. null=True
  98. )
  99. objects = RestrictedQuerySet.as_manager()
  100. csv_headers = ['name', 'description', 'tenant']
  101. class Meta:
  102. ordering = ['name']
  103. def __str__(self):
  104. return self.name
  105. def get_absolute_url(self):
  106. return reverse('ipam:routetarget', args=[self.pk])
  107. def to_csv(self):
  108. return (
  109. self.name,
  110. self.description,
  111. self.tenant.name if self.tenant else None,
  112. )