mirror of
https://github.com/netbox-community/netbox.git
synced 2026-04-21 00:11:39 +02:00
Fixes #21012: Ensure all tagged VLANs assigned to an interface are listed under the interface detail UI view
This commit is contained in:
@@ -16,7 +16,7 @@ from circuits.models import Circuit, CircuitTermination
|
|||||||
from extras.ui.panels import CustomFieldsPanel, ImageAttachmentsPanel, TagsPanel
|
from extras.ui.panels import CustomFieldsPanel, ImageAttachmentsPanel, TagsPanel
|
||||||
from extras.views import ObjectConfigContextView, ObjectRenderConfigView
|
from extras.views import ObjectConfigContextView, ObjectRenderConfigView
|
||||||
from ipam.models import ASN, VLAN, IPAddress, Prefix, VLANGroup
|
from ipam.models import ASN, VLAN, IPAddress, Prefix, VLANGroup
|
||||||
from ipam.tables import InterfaceVLANTable, VLANTranslationRuleTable
|
from ipam.tables import VLANTranslationRuleTable
|
||||||
from netbox.object_actions import *
|
from netbox.object_actions import *
|
||||||
from netbox.ui import actions, layout
|
from netbox.ui import actions, layout
|
||||||
from netbox.ui.panels import (
|
from netbox.ui.panels import (
|
||||||
@@ -3230,21 +3230,6 @@ class InterfaceView(generic.ObjectView):
|
|||||||
)
|
)
|
||||||
lag_interfaces_table.configure(request)
|
lag_interfaces_table.configure(request)
|
||||||
|
|
||||||
# Get assigned VLANs and annotate whether each is tagged or untagged
|
|
||||||
vlans = []
|
|
||||||
if instance.untagged_vlan is not None:
|
|
||||||
vlans.append(instance.untagged_vlan)
|
|
||||||
vlans[0].tagged = False
|
|
||||||
for vlan in instance.tagged_vlans.restrict(request.user).prefetch_related('site', 'group', 'tenant', 'role'):
|
|
||||||
vlan.tagged = True
|
|
||||||
vlans.append(vlan)
|
|
||||||
vlan_table = InterfaceVLANTable(
|
|
||||||
interface=instance,
|
|
||||||
data=vlans,
|
|
||||||
orderable=False
|
|
||||||
)
|
|
||||||
vlan_table.configure(request)
|
|
||||||
|
|
||||||
# Get VLAN translation rules
|
# Get VLAN translation rules
|
||||||
vlan_translation_table = None
|
vlan_translation_table = None
|
||||||
if instance.vlan_translation_policy:
|
if instance.vlan_translation_policy:
|
||||||
@@ -3260,7 +3245,6 @@ class InterfaceView(generic.ObjectView):
|
|||||||
'bridge_interfaces_table': bridge_interfaces_table,
|
'bridge_interfaces_table': bridge_interfaces_table,
|
||||||
'child_interfaces_table': child_interfaces_table,
|
'child_interfaces_table': child_interfaces_table,
|
||||||
'lag_interfaces_table': lag_interfaces_table,
|
'lag_interfaces_table': lag_interfaces_table,
|
||||||
'vlan_table': vlan_table,
|
|
||||||
'vlan_translation_table': vlan_translation_table,
|
'vlan_translation_table': vlan_translation_table,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django_tables2.utils import Accessor
|
|
||||||
|
|
||||||
from dcim.models import Interface
|
from dcim.models import Interface
|
||||||
from dcim.tables.template_code import INTERFACE_LINKTERMINATION, LINKTERMINATION
|
from dcim.tables.template_code import INTERFACE_LINKTERMINATION, LINKTERMINATION
|
||||||
from ipam.models import *
|
from ipam.models import *
|
||||||
from netbox.tables import NetBoxTable, OrganizationalModelTable, PrimaryModelTable, columns
|
from netbox.tables import NetBoxTable, OrganizationalModelTable, PrimaryModelTable, columns
|
||||||
from tenancy.tables import TenancyColumnsMixin, TenantColumn
|
from tenancy.tables import TenancyColumnsMixin
|
||||||
from virtualization.models import VMInterface
|
from virtualization.models import VMInterface
|
||||||
|
|
||||||
from .template_code import *
|
from .template_code import *
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'InterfaceVLANTable',
|
|
||||||
'VLANDevicesTable',
|
'VLANDevicesTable',
|
||||||
'VLANGroupTable',
|
'VLANGroupTable',
|
||||||
'VLANMembersTable',
|
'VLANMembersTable',
|
||||||
@@ -198,47 +196,6 @@ class VLANVirtualMachinesTable(VLANMembersTable):
|
|||||||
exclude = ('id', )
|
exclude = ('id', )
|
||||||
|
|
||||||
|
|
||||||
class InterfaceVLANTable(NetBoxTable):
|
|
||||||
"""
|
|
||||||
List VLANs assigned to a specific Interface.
|
|
||||||
"""
|
|
||||||
vid = tables.Column(
|
|
||||||
linkify=True,
|
|
||||||
verbose_name=_('VID')
|
|
||||||
)
|
|
||||||
tagged = columns.BooleanColumn(
|
|
||||||
verbose_name=_('Tagged'),
|
|
||||||
false_mark=None
|
|
||||||
)
|
|
||||||
site = tables.Column(
|
|
||||||
verbose_name=_('Site'),
|
|
||||||
linkify=True
|
|
||||||
)
|
|
||||||
group = tables.Column(
|
|
||||||
accessor=Accessor('group__name'),
|
|
||||||
verbose_name=_('Group')
|
|
||||||
)
|
|
||||||
tenant = TenantColumn(
|
|
||||||
verbose_name=_('Tenant'),
|
|
||||||
)
|
|
||||||
status = columns.ChoiceFieldColumn(
|
|
||||||
verbose_name=_('Status'),
|
|
||||||
)
|
|
||||||
role = tables.Column(
|
|
||||||
verbose_name=_('Role'),
|
|
||||||
linkify=True
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta(NetBoxTable.Meta):
|
|
||||||
model = VLAN
|
|
||||||
fields = ('vid', 'tagged', 'site', 'group', 'name', 'tenant', 'status', 'role', 'description')
|
|
||||||
exclude = ('id', )
|
|
||||||
|
|
||||||
def __init__(self, interface, *args, **kwargs):
|
|
||||||
self.interface = interface
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# VLAN Translation
|
# VLAN Translation
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -411,7 +411,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<div class="col col-md-12">
|
<div class="col col-md-12">
|
||||||
{% include 'inc/panel_table.html' with table=vlan_table heading="VLANs" %}
|
<div class="card">
|
||||||
|
<h2 class="card-header">{% trans "VLANs" %}</h2>
|
||||||
|
{% htmx_table 'ipam:vlan_list' interface_id=object.pk %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if object.is_lag %}
|
{% if object.is_lag %}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from dcim.tables import DeviceTable
|
|||||||
from extras.ui.panels import CustomFieldsPanel, ImageAttachmentsPanel, TagsPanel
|
from extras.ui.panels import CustomFieldsPanel, ImageAttachmentsPanel, TagsPanel
|
||||||
from extras.views import ObjectConfigContextView, ObjectRenderConfigView
|
from extras.views import ObjectConfigContextView, ObjectRenderConfigView
|
||||||
from ipam.models import IPAddress, VLANGroup
|
from ipam.models import IPAddress, VLANGroup
|
||||||
from ipam.tables import InterfaceVLANTable, VLANTranslationRuleTable
|
from ipam.tables import VLANTranslationRuleTable
|
||||||
from ipam.ui.panels import FHRPGroupAssignmentsPanel
|
from ipam.ui.panels import FHRPGroupAssignmentsPanel
|
||||||
from netbox.object_actions import (
|
from netbox.object_actions import (
|
||||||
AddObject,
|
AddObject,
|
||||||
@@ -594,7 +594,11 @@ class VMInterfaceView(generic.ObjectView):
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
ContextTablePanel('vlan_table', title=_('Assigned VLANs')),
|
ObjectsTablePanel(
|
||||||
|
model='ipam.VLAN',
|
||||||
|
title=_('Assigned VLANs'),
|
||||||
|
filters={'vminterface_id': lambda ctx: ctx['object'].pk},
|
||||||
|
),
|
||||||
ContextTablePanel('vlan_translation_table', title=_('VLAN Translation')),
|
ContextTablePanel('vlan_translation_table', title=_('VLAN Translation')),
|
||||||
ContextTablePanel('child_interfaces_table', title=_('Child Interfaces')),
|
ContextTablePanel('child_interfaces_table', title=_('Child Interfaces')),
|
||||||
],
|
],
|
||||||
@@ -620,24 +624,8 @@ class VMInterfaceView(generic.ObjectView):
|
|||||||
)
|
)
|
||||||
vlan_translation_table.configure(request)
|
vlan_translation_table.configure(request)
|
||||||
|
|
||||||
# Get assigned VLANs and annotate whether each is tagged or untagged
|
|
||||||
vlans = []
|
|
||||||
if instance.untagged_vlan is not None:
|
|
||||||
vlans.append(instance.untagged_vlan)
|
|
||||||
vlans[0].tagged = False
|
|
||||||
for vlan in instance.tagged_vlans.restrict(request.user).prefetch_related('site', 'group', 'tenant', 'role'):
|
|
||||||
vlan.tagged = True
|
|
||||||
vlans.append(vlan)
|
|
||||||
vlan_table = InterfaceVLANTable(
|
|
||||||
interface=instance,
|
|
||||||
data=vlans,
|
|
||||||
orderable=False
|
|
||||||
)
|
|
||||||
vlan_table.configure(request)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'child_interfaces_table': child_interfaces_tables,
|
'child_interfaces_table': child_interfaces_tables,
|
||||||
'vlan_table': vlan_table,
|
|
||||||
'vlan_translation_table': vlan_translation_table,
|
'vlan_translation_table': vlan_translation_table,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user