diff --git a/netbox/dcim/api/serializers_/device_components.py b/netbox/dcim/api/serializers_/device_components.py index ded51e5c2..3cb8eef70 100644 --- a/netbox/dcim/api/serializers_/device_components.py +++ b/netbox/dcim/api/serializers_/device_components.py @@ -1,5 +1,5 @@ -from django.utils.translation import gettext as _ from django.contrib.contenttypes.models import ContentType +from django.utils.translation import gettext as _ from drf_spectacular.utils import extend_schema_field from rest_framework import serializers @@ -183,6 +183,7 @@ class InterfaceSerializer(NetBoxModelSerializer, CabledObjectSerializer, Connect type = ChoiceField(choices=InterfaceTypeChoices) parent = NestedInterfaceSerializer(required=False, allow_null=True) bridge = NestedInterfaceSerializer(required=False, allow_null=True) + bridge_interfaces = NestedInterfaceSerializer(many=True, read_only=True) lag = NestedInterfaceSerializer(required=False, allow_null=True) mode = ChoiceField(choices=InterfaceModeChoices, required=False, allow_blank=True) duplex = ChoiceField(choices=InterfaceDuplexChoices, required=False, allow_blank=True, allow_null=True) @@ -222,13 +223,13 @@ class InterfaceSerializer(NetBoxModelSerializer, CabledObjectSerializer, Connect model = Interface fields = [ 'id', 'url', 'display_url', 'display', 'device', 'vdcs', 'module', 'name', 'label', 'type', 'enabled', - 'parent', 'bridge', 'lag', 'mtu', 'mac_address', 'primary_mac_address', 'mac_addresses', 'speed', 'duplex', - 'wwn', 'mgmt_only', 'description', 'mode', 'rf_role', 'rf_channel', 'poe_mode', 'poe_type', - 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'untagged_vlan', 'tagged_vlans', 'qinq_svlan', - 'vlan_translation_policy', 'mark_connected', 'cable', 'cable_end', 'wireless_link', 'link_peers', - 'link_peers_type', 'wireless_lans', 'vrf', 'l2vpn_termination', 'connected_endpoints', - 'connected_endpoints_type', 'connected_endpoints_reachable', 'tags', 'custom_fields', 'created', - 'last_updated', 'count_ipaddresses', 'count_fhrp_groups', '_occupied', + 'parent', 'bridge', 'bridge_interfaces', 'lag', 'mtu', 'mac_address', 'primary_mac_address', + 'mac_addresses', 'speed', 'duplex', 'wwn', 'mgmt_only', 'description', 'mode', 'rf_role', 'rf_channel', + 'poe_mode', 'poe_type', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'untagged_vlan', + 'tagged_vlans', 'qinq_svlan', 'vlan_translation_policy', 'mark_connected', 'cable', 'cable_end', + 'wireless_link', 'link_peers', 'link_peers_type', 'wireless_lans', 'vrf', 'l2vpn_termination', + 'connected_endpoints', 'connected_endpoints_type', 'connected_endpoints_reachable', 'tags', 'custom_fields', + 'created', 'last_updated', 'count_ipaddresses', 'count_fhrp_groups', '_occupied', ] brief_fields = ('id', 'url', 'display', 'device', 'name', 'description', 'cable', '_occupied') diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index dc64d2503..cc3a5df9c 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -13,7 +13,7 @@ from django.views.generic import View from circuits.models import Circuit, CircuitTermination from extras.views import ObjectConfigContextView, ObjectRenderConfigView -from ipam.models import ASN, IPAddress, Prefix, VLANGroup, VLAN +from ipam.models import ASN, IPAddress, Prefix, VLAN, VLANGroup from ipam.tables import InterfaceVLANTable, VLANTranslationRuleTable from netbox.object_actions import * from netbox.views import generic @@ -2900,6 +2900,7 @@ class InterfaceView(generic.ObjectView): return { 'vdc_table': vdc_table, + 'bridge_interfaces': bridge_interfaces, 'bridge_interfaces_table': bridge_interfaces_table, 'child_interfaces_table': child_interfaces_table, 'vlan_table': vlan_table, diff --git a/netbox/templates/dcim/interface.html b/netbox/templates/dcim/interface.html index f6e34e355..b53d239b4 100644 --- a/netbox/templates/dcim/interface.html +++ b/netbox/templates/dcim/interface.html @@ -112,6 +112,19 @@ {% trans "Bridge" %} {{ object.bridge|linkify|placeholder }} + + {% trans "Bridged Interfaces" %} + + {% if bridge_interfaces %} + {% for interface in bridge_interfaces %} + {{ interface|linkify }} + {% if not forloop.last %}
{% endif %} + {% endfor %} + {% else %} + {{ ''|placeholder }} + {% endif %} + + {% trans "LAG" %} {{ object.lag|linkify|placeholder }} @@ -435,13 +448,11 @@ {% endif %} - {% if object.is_bridge %} -
-
- {% include 'inc/panel_table.html' with table=bridge_interfaces_table heading="Bridge Interfaces" %} -
+
+
+ {% include 'inc/panel_table.html' with table=bridge_interfaces_table heading="Bridged Interfaces" %}
- {% endif %} +
{% include 'inc/panel_table.html' with table=child_interfaces_table heading="Child Interfaces" %}