mirror of
https://github.com/netbox-community/netbox.git
synced 2026-02-05 14:56:24 -06:00
* WIP * Add API tests * Add remaining tests * Add model docs * Show virtual circuit connections on interfaces * Misc cleanup per PR feedback * Renumber migration * Support nested terminations for virtual circuit bulk import
This commit is contained in:
@@ -4,7 +4,7 @@ from django.utils.translation import gettext as _
|
||||
from drf_spectacular.types import OpenApiTypes
|
||||
from drf_spectacular.utils import extend_schema_field
|
||||
|
||||
from circuits.models import CircuitTermination
|
||||
from circuits.models import CircuitTermination, VirtualCircuit, VirtualCircuitTermination
|
||||
from extras.filtersets import LocalConfigContextFilterSet
|
||||
from extras.models import ConfigTemplate
|
||||
from ipam.filtersets import PrimaryIPFilterSet
|
||||
@@ -1842,6 +1842,16 @@ class InterfaceFilterSet(
|
||||
queryset=WirelessLink.objects.all(),
|
||||
label=_('Wireless link')
|
||||
)
|
||||
virtual_circuit_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='virtual_circuit_termination__virtual_circuit',
|
||||
queryset=VirtualCircuit.objects.all(),
|
||||
label=_('Virtual circuit (ID)'),
|
||||
)
|
||||
virtual_circuit_termination_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='virtual_circuit_termination',
|
||||
queryset=VirtualCircuitTermination.objects.all(),
|
||||
label=_('Virtual circuit termination (ID)'),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = Interface
|
||||
|
||||
@@ -998,6 +998,14 @@ class Interface(ModularComponentModel, BaseInterface, CabledObjectModel, PathEnd
|
||||
def l2vpn_termination(self):
|
||||
return self.l2vpn_terminations.first()
|
||||
|
||||
@cached_property
|
||||
def connected_endpoints(self):
|
||||
# If this is a virtual interface, return the remote endpoint of the connected
|
||||
# virtual circuit, if any.
|
||||
if self.is_virtual and hasattr(self, 'virtual_circuit_termination'):
|
||||
return self.virtual_circuit_termination.peer_terminations
|
||||
return super().connected_endpoints
|
||||
|
||||
|
||||
#
|
||||
# Pass-through ports
|
||||
|
||||
@@ -649,6 +649,14 @@ class InterfaceTable(BaseInterfaceTable, ModularDeviceComponentTable, PathEndpoi
|
||||
url_name='dcim:interface_list'
|
||||
)
|
||||
|
||||
# Override PathEndpointTable.connection to accommodate virtual circuits
|
||||
connection = columns.TemplateColumn(
|
||||
accessor='_path__destinations',
|
||||
template_code=INTERFACE_LINKTERMINATION,
|
||||
verbose_name=_('Connection'),
|
||||
orderable=False
|
||||
)
|
||||
|
||||
class Meta(DeviceComponentTable.Meta):
|
||||
model = models.Interface
|
||||
fields = (
|
||||
|
||||
@@ -10,6 +10,20 @@ LINKTERMINATION = """
|
||||
{% endfor %}
|
||||
"""
|
||||
|
||||
INTERFACE_LINKTERMINATION = """
|
||||
{% load i18n %}
|
||||
{% if record.is_virtual and record.virtual_circuit_termination %}
|
||||
{% for termination in record.connected_endpoints %}
|
||||
<a href="{{ termination.interface.parent_object.get_absolute_url }}">{{ termination.interface.parent_object }}</a>
|
||||
<i class="mdi mdi-chevron-right"></i>
|
||||
<a href="{{ termination.interface.get_absolute_url }}">{{ termination.interface }}</a>
|
||||
{% trans "via" %}
|
||||
<a href="{{ termination.parent_object.get_absolute_url }}">{{ termination.parent_object }}</a>
|
||||
{% if not forloop.last %}<br />{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}""" + LINKTERMINATION + """{% endif %}
|
||||
"""
|
||||
|
||||
CABLE_LENGTH = """
|
||||
{% load helpers %}
|
||||
{% if record.length %}{{ record.length|floatformat:"-2" }} {{ record.length_unit }}{% endif %}
|
||||
|
||||
Reference in New Issue
Block a user