Coverage for ipam/tables/vlans.py: 100%
82 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
1import django_tables2 as tables
2from django.utils.safestring import mark_safe
3from django.utils.translation import gettext_lazy as _
5from dcim.models import Interface
6from dcim.tables.template_code import INTERFACE_LINKTERMINATION, LINKTERMINATION
7from ipam.models import *
8from netbox.tables import NetBoxTable, OrganizationalModelTable, PrimaryModelTable, columns
9from tenancy.tables import TenancyColumnsMixin
10from virtualization.models import VMInterface
12from .template_code import *
14__all__ = (
15 'VLANDevicesTable',
16 'VLANGroupTable',
17 'VLANMembersTable',
18 'VLANTable',
19 'VLANTranslationPolicyTable',
20 'VLANTranslationRuleTable',
21 'VLANVirtualMachinesTable',
22)
24AVAILABLE_LABEL = mark_safe('<span class="badge text-bg-success">Available</span>')
27#
28# VLAN groups
29#
31class VLANGroupTable(TenancyColumnsMixin, OrganizationalModelTable):
32 name = tables.Column(
33 verbose_name=_('Name'),
34 linkify=True
35 )
36 scope_type = columns.ContentTypeColumn(
37 verbose_name=_('Scope Type'),
38 )
39 scope = tables.Column(
40 verbose_name=_('Scope'),
41 linkify=True,
42 orderable=False
43 )
44 vid_ranges_list = columns.ArrayColumn(
45 accessor='vid_ranges_items',
46 verbose_name=_('VID Ranges'),
47 orderable=False
48 )
49 vlan_count = columns.LinkedCountColumn(
50 viewname='ipam:vlan_list',
51 url_params={'group_id': 'pk'},
52 verbose_name=_('VLANs')
53 )
54 total_vlan_ids = tables.Column(
55 verbose_name=_('Total VLAN IDs'),
56 )
57 utilization = columns.UtilizationColumn(
58 orderable=False,
59 verbose_name=_('Utilization')
60 )
61 tags = columns.TagColumn(
62 url_name='ipam:vlangroup_list'
63 )
64 actions = columns.ActionsColumn(
65 extra_buttons=VLANGROUP_BUTTONS
66 )
68 class Meta(OrganizationalModelTable.Meta):
69 model = VLANGroup
70 fields = (
71 'pk', 'id', 'name', 'slug', 'description', 'scope_type', 'scope', 'vid_ranges_list', 'vlan_count',
72 'total_vlan_ids', 'tenant', 'tenant_group', 'comments', 'tags', 'created', 'last_updated', 'actions',
73 'utilization',
74 )
75 default_columns = (
76 'pk', 'name', 'scope_type', 'scope', 'vlan_count', 'utilization', 'tenant', 'description'
77 )
80#
81# VLANs
82#
84class VLANTable(TenancyColumnsMixin, PrimaryModelTable):
85 vid = tables.TemplateColumn(
86 template_code=VLAN_LINK,
87 verbose_name=_('VID')
88 )
89 name = tables.Column(
90 verbose_name=_('Name'),
91 linkify=True
92 )
93 site = tables.Column(
94 verbose_name=_('Site'),
95 linkify=True
96 )
97 group = tables.Column(
98 verbose_name=_('Group'),
99 linkify=True
100 )
101 status = columns.ChoiceFieldColumn(
102 verbose_name=_('Status'),
103 default=AVAILABLE_LABEL
104 )
105 role = tables.Column(
106 verbose_name=_('Role'),
107 linkify=True
108 )
109 qinq_role = columns.ChoiceFieldColumn(
110 verbose_name=_('Q-in-Q role')
111 )
112 qinq_svlan = tables.Column(
113 verbose_name=_('Q-in-Q SVLAN'),
114 linkify=True
115 )
116 l2vpn = tables.Column(
117 accessor=tables.A('l2vpn_termination__l2vpn'),
118 linkify=True,
119 orderable=False,
120 verbose_name=_('L2VPN')
121 )
122 prefixes = columns.TemplateColumn(
123 template_code=VLAN_PREFIXES,
124 orderable=False,
125 verbose_name=_('Prefixes')
126 )
127 tags = columns.TagColumn(
128 url_name='ipam:vlan_list'
129 )
131 class Meta(PrimaryModelTable.Meta):
132 model = VLAN
133 fields = (
134 'pk', 'id', 'vid', 'name', 'site', 'group', 'prefixes', 'tenant', 'tenant_group', 'status', 'role',
135 'qinq_role', 'qinq_svlan', 'description', 'comments', 'tags', 'l2vpn', 'created', 'last_updated',
136 )
137 default_columns = ('pk', 'vid', 'name', 'site', 'group', 'prefixes', 'tenant', 'status', 'role', 'description')
138 row_attrs = {
139 'class': lambda record: 'success' if not isinstance(record, VLAN) else '',
140 }
143class VLANMembersTable(NetBoxTable):
144 """
145 Base table for Interface and VMInterface assignments
146 """
147 name = tables.Column(
148 linkify=True,
149 verbose_name=_('Interface')
150 )
151 tagged = tables.TemplateColumn(
152 verbose_name=_('Tagged'),
153 template_code=VLAN_MEMBER_TAGGED,
154 orderable=False
155 )
158class VLANDevicesTable(VLANMembersTable):
159 device = tables.Column(
160 verbose_name=_('Device'),
161 linkify=True
162 )
163 actions = columns.ActionsColumn(
164 actions=('edit',)
165 )
166 link_peer = columns.TemplateColumn(
167 accessor='link_peers',
168 template_code=LINKTERMINATION,
169 orderable=False,
170 verbose_name=_('Link Peers'),
171 )
173 # Override PathEndpointTable.connection to accommodate virtual circuits
174 connection = columns.TemplateColumn(
175 accessor='_path__destinations',
176 template_code=INTERFACE_LINKTERMINATION,
177 orderable=False,
178 verbose_name=_('Connection'),
179 )
181 class Meta(NetBoxTable.Meta):
182 model = Interface
183 fields = ('device', 'name', 'link_peer', 'connection', 'tagged', 'actions')
184 default_columns = ('device', 'name', 'connection', 'tagged', 'actions')
185 exclude = ('id',)
188class VLANVirtualMachinesTable(VLANMembersTable):
189 virtual_machine = tables.Column(
190 verbose_name=_('Virtual Machine'),
191 linkify=True
192 )
193 actions = columns.ActionsColumn(
194 actions=('edit',)
195 )
197 class Meta(NetBoxTable.Meta):
198 model = VMInterface
199 fields = ('virtual_machine', 'name', 'tagged', 'actions')
200 exclude = ('id', )
203#
204# VLAN Translation
205#
207class VLANTranslationPolicyTable(PrimaryModelTable):
208 name = tables.Column(
209 verbose_name=_('Name'),
210 linkify=True
211 )
212 rule_count = columns.LinkedCountColumn(
213 viewname='ipam:vlantranslationrule_list',
214 url_params={'policy_id': 'pk'},
215 verbose_name=_('Rules')
216 )
217 description = tables.Column(
218 verbose_name=_('Description'),
219 )
220 tags = columns.TagColumn(
221 url_name='ipam:vlantranslationpolicy_list'
222 )
224 class Meta(PrimaryModelTable.Meta):
225 model = VLANTranslationPolicy
226 fields = (
227 'pk', 'id', 'name', 'rule_count', 'description', 'tags', 'created', 'last_updated',
228 )
229 default_columns = ('pk', 'name', 'rule_count', 'description')
232class VLANTranslationRuleTable(NetBoxTable):
233 policy = tables.Column(
234 verbose_name=_('Policy'),
235 linkify=True
236 )
237 local_vid = tables.Column(
238 verbose_name=_('Local VID'),
239 linkify=True
240 )
241 remote_vid = tables.Column(
242 verbose_name=_('Remote VID'),
243 )
244 description = tables.Column(
245 verbose_name=_('Description'),
246 )
247 tags = columns.TagColumn(
248 url_name='ipam:vlantranslationrule_list'
249 )
251 class Meta(NetBoxTable.Meta):
252 model = VLANTranslationRule
253 fields = (
254 'pk', 'id', 'policy', 'local_vid', 'remote_vid', 'description', 'tags', 'created', 'last_updated',
255 )
256 default_columns = ('pk', 'policy', 'local_vid', 'remote_vid', 'description')