vlans.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. import django_tables2 as tables
  2. from django.utils.safestring import mark_safe
  3. from django_tables2.utils import Accessor
  4. from dcim.models import Interface
  5. from ipam.models import *
  6. from netbox.tables import NetBoxTable, columns
  7. from tenancy.tables import TenancyColumnsMixin, TenantColumn
  8. from virtualization.models import VMInterface
  9. __all__ = (
  10. 'InterfaceVLANTable',
  11. 'VLANDevicesTable',
  12. 'VLANGroupTable',
  13. 'VLANMembersTable',
  14. 'VLANTable',
  15. 'VLANVirtualMachinesTable',
  16. )
  17. AVAILABLE_LABEL = mark_safe('<span class="badge bg-success">Available</span>')
  18. VLAN_LINK = """
  19. {% if record.pk %}
  20. <a href="{{ record.get_absolute_url }}">{{ record.vid }}</a>
  21. {% elif perms.ipam.add_vlan %}
  22. <a href="{% url 'ipam:vlan_add' %}?vid={{ record.vid }}{% if record.vlan_group %}&group={{ record.vlan_group.pk }}{% endif %}" class="btn btn-sm btn-success">{{ record.available }} VLAN{{ record.available|pluralize }} available</a>
  23. {% else %}
  24. {{ record.available }} VLAN{{ record.available|pluralize }} available
  25. {% endif %}
  26. """
  27. VLAN_PREFIXES = """
  28. {% for prefix in value.all %}
  29. <a href="{% url 'ipam:prefix' pk=prefix.pk %}">{{ prefix }}</a>{% if not forloop.last %}<br />{% endif %}
  30. {% endfor %}
  31. """
  32. VLANGROUP_BUTTONS = """
  33. {% with next_vid=record.get_next_available_vid %}
  34. {% if next_vid and perms.ipam.add_vlan %}
  35. <a href="{% url 'ipam:vlan_add' %}?group={{ record.pk }}&vid={{ next_vid }}" title="Add VLAN" class="btn btn-sm btn-success">
  36. <i class="mdi mdi-plus-thick" aria-hidden="true"></i>
  37. </a>
  38. {% endif %}
  39. {% endwith %}
  40. """
  41. VLAN_MEMBER_TAGGED = """
  42. {% if record.untagged_vlan_id == object.pk %}
  43. <span class="text-danger"><i class="mdi mdi-close-thick"></i></span>
  44. {% else %}
  45. <span class="text-success"><i class="mdi mdi-check-bold"></i></span>
  46. {% endif %}
  47. """
  48. #
  49. # VLAN groups
  50. #
  51. class VLANGroupTable(NetBoxTable):
  52. name = tables.Column(linkify=True)
  53. scope_type = columns.ContentTypeColumn()
  54. scope = tables.Column(
  55. linkify=True,
  56. orderable=False
  57. )
  58. vlan_count = columns.LinkedCountColumn(
  59. viewname='ipam:vlan_list',
  60. url_params={'group_id': 'pk'},
  61. verbose_name='VLANs'
  62. )
  63. tags = columns.TagColumn(
  64. url_name='ipam:vlangroup_list'
  65. )
  66. actions = columns.ActionsColumn(
  67. extra_buttons=VLANGROUP_BUTTONS
  68. )
  69. class Meta(NetBoxTable.Meta):
  70. model = VLANGroup
  71. fields = (
  72. 'pk', 'id', 'name', 'scope_type', 'scope', 'min_vid', 'max_vid', 'vlan_count', 'slug', 'description',
  73. 'tags', 'created', 'last_updated', 'actions',
  74. )
  75. default_columns = ('pk', 'name', 'scope_type', 'scope', 'vlan_count', 'description')
  76. #
  77. # VLANs
  78. #
  79. class VLANTable(TenancyColumnsMixin, NetBoxTable):
  80. vid = tables.TemplateColumn(
  81. template_code=VLAN_LINK,
  82. verbose_name='VID'
  83. )
  84. name = tables.Column(
  85. linkify=True
  86. )
  87. site = tables.Column(
  88. linkify=True
  89. )
  90. group = tables.Column(
  91. linkify=True
  92. )
  93. status = columns.ChoiceFieldColumn(
  94. default=AVAILABLE_LABEL
  95. )
  96. role = tables.Column(
  97. linkify=True
  98. )
  99. l2vpn = tables.Column(
  100. accessor=tables.A('l2vpn_termination__l2vpn'),
  101. linkify=True,
  102. orderable=False,
  103. verbose_name='L2VPN'
  104. )
  105. prefixes = columns.TemplateColumn(
  106. template_code=VLAN_PREFIXES,
  107. orderable=False,
  108. verbose_name='Prefixes'
  109. )
  110. tags = columns.TagColumn(
  111. url_name='ipam:vlan_list'
  112. )
  113. class Meta(NetBoxTable.Meta):
  114. model = VLAN
  115. fields = (
  116. 'pk', 'id', 'vid', 'name', 'site', 'group', 'prefixes', 'tenant', 'tenant_group', 'status', 'role',
  117. 'description', 'tags', 'l2vpn', 'created', 'last_updated',
  118. )
  119. default_columns = ('pk', 'vid', 'name', 'site', 'group', 'prefixes', 'tenant', 'status', 'role', 'description')
  120. row_attrs = {
  121. 'class': lambda record: 'success' if not isinstance(record, VLAN) else '',
  122. }
  123. class VLANMembersTable(NetBoxTable):
  124. """
  125. Base table for Interface and VMInterface assignments
  126. """
  127. name = tables.Column(
  128. linkify=True,
  129. verbose_name='Interface'
  130. )
  131. tagged = tables.TemplateColumn(
  132. template_code=VLAN_MEMBER_TAGGED,
  133. orderable=False
  134. )
  135. class VLANDevicesTable(VLANMembersTable):
  136. device = tables.Column(
  137. linkify=True
  138. )
  139. actions = columns.ActionsColumn(
  140. actions=('edit',)
  141. )
  142. class Meta(NetBoxTable.Meta):
  143. model = Interface
  144. fields = ('device', 'name', 'tagged', 'actions')
  145. exclude = ('id', )
  146. class VLANVirtualMachinesTable(VLANMembersTable):
  147. virtual_machine = tables.Column(
  148. linkify=True
  149. )
  150. actions = columns.ActionsColumn(
  151. actions=('edit',)
  152. )
  153. class Meta(NetBoxTable.Meta):
  154. model = VMInterface
  155. fields = ('virtual_machine', 'name', 'tagged', 'actions')
  156. exclude = ('id', )
  157. class InterfaceVLANTable(NetBoxTable):
  158. """
  159. List VLANs assigned to a specific Interface.
  160. """
  161. vid = tables.Column(
  162. linkify=True,
  163. verbose_name='ID'
  164. )
  165. tagged = columns.BooleanColumn()
  166. site = tables.Column(
  167. linkify=True
  168. )
  169. group = tables.Column(
  170. accessor=Accessor('group__name'),
  171. verbose_name='Group'
  172. )
  173. tenant = TenantColumn()
  174. status = columns.ChoiceFieldColumn()
  175. role = tables.Column(
  176. linkify=True
  177. )
  178. class Meta(NetBoxTable.Meta):
  179. model = VLAN
  180. fields = ('vid', 'tagged', 'site', 'group', 'name', 'tenant', 'status', 'role', 'description')
  181. exclude = ('id', )
  182. def __init__(self, interface, *args, **kwargs):
  183. self.interface = interface
  184. super().__init__(*args, **kwargs)