diff --git a/docs/release-notes/version-3.3.md b/docs/release-notes/version-3.3.md index 6e8846e4a..741fdc8d5 100644 --- a/docs/release-notes/version-3.3.md +++ b/docs/release-notes/version-3.3.md @@ -21,6 +21,7 @@ * [#10057](https://github.com/netbox-community/netbox/issues/10057) - Fix AttributeError exception when global search results include rack reservations * [#10059](https://github.com/netbox-community/netbox/issues/10059) - Add identifier column to L2VPN table * [#10070](https://github.com/netbox-community/netbox/issues/10070) - Add unique constraint for L2VPN slug +* [#10087](https://github.com/netbox-community/netbox/issues/10087) - Correct display of far end in console/power/interface connections tables * [#10089](https://github.com/netbox-community/netbox/issues/10089) - `linkify` template filter should escape object representation * [#10094](https://github.com/netbox-community/netbox/issues/10094) - Fix 404 when using "create and add another" to add contact assignments * [#10108](https://github.com/netbox-community/netbox/issues/10108) - Linkify inside NAT IPs for primary device IPs in UI diff --git a/netbox/dcim/tables/__init__.py b/netbox/dcim/tables/__init__.py index e3b2a42ba..843b612b1 100644 --- a/netbox/dcim/tables/__init__.py +++ b/netbox/dcim/tables/__init__.py @@ -1,109 +1,8 @@ -import django_tables2 as tables -from django_tables2.utils import Accessor - -from netbox.tables import BaseTable, columns -from dcim.models import ConsolePort, Interface, PowerPort from .cables import * +from .connections import * from .devices import * from .devicetypes import * from .modules import * from .power import * from .racks import * from .sites import * - - -# -# Device connections -# - -class ConsoleConnectionTable(BaseTable): - console_server = tables.Column( - accessor=Accessor('_path__destination__device'), - orderable=False, - linkify=True, - verbose_name='Console Server' - ) - console_server_port = tables.Column( - accessor=Accessor('_path__destination'), - orderable=False, - linkify=True, - verbose_name='Port' - ) - device = tables.Column( - linkify=True - ) - name = tables.Column( - linkify=True, - verbose_name='Console Port' - ) - reachable = columns.BooleanColumn( - accessor=Accessor('_path__is_active'), - verbose_name='Reachable' - ) - - class Meta(BaseTable.Meta): - model = ConsolePort - fields = ('device', 'name', 'console_server', 'console_server_port', 'reachable') - - -class PowerConnectionTable(BaseTable): - pdu = tables.Column( - accessor=Accessor('_path__destination__device'), - orderable=False, - linkify=True, - verbose_name='PDU' - ) - outlet = tables.Column( - accessor=Accessor('_path__destination'), - orderable=False, - linkify=True, - verbose_name='Outlet' - ) - device = tables.Column( - linkify=True - ) - name = tables.Column( - linkify=True, - verbose_name='Power Port' - ) - reachable = columns.BooleanColumn( - accessor=Accessor('_path__is_active'), - verbose_name='Reachable' - ) - - class Meta(BaseTable.Meta): - model = PowerPort - fields = ('device', 'name', 'pdu', 'outlet', 'reachable') - - -class InterfaceConnectionTable(BaseTable): - device_a = tables.Column( - accessor=Accessor('device'), - linkify=True, - verbose_name='Device A' - ) - interface_a = tables.Column( - accessor=Accessor('name'), - linkify=True, - verbose_name='Interface A' - ) - device_b = tables.Column( - accessor=Accessor('_path__destination__device'), - orderable=False, - linkify=True, - verbose_name='Device B' - ) - interface_b = tables.Column( - accessor=Accessor('_path__destination'), - orderable=False, - linkify=True, - verbose_name='Interface B' - ) - reachable = columns.BooleanColumn( - accessor=Accessor('_path__is_active'), - verbose_name='Reachable' - ) - - class Meta(BaseTable.Meta): - model = Interface - fields = ('device_a', 'interface_a', 'device_b', 'interface_b', 'reachable') diff --git a/netbox/dcim/tables/connections.py b/netbox/dcim/tables/connections.py new file mode 100644 index 000000000..f9f78f3a6 --- /dev/null +++ b/netbox/dcim/tables/connections.py @@ -0,0 +1,71 @@ +import django_tables2 as tables +from django_tables2.utils import Accessor + +from netbox.tables import BaseTable, columns +from dcim.models import ConsolePort, Interface, PowerPort +from .devices import PathEndpointTable + +__all__ = ( + 'ConsoleConnectionTable', + 'InterfaceConnectionTable', + 'PowerConnectionTable', +) + + +# +# Device connections +# + +class ConsoleConnectionTable(PathEndpointTable): + device = tables.Column( + linkify=True + ) + name = tables.Column( + linkify=True, + verbose_name='Console Port' + ) + reachable = columns.BooleanColumn( + accessor=Accessor('_path__is_active'), + verbose_name='Reachable' + ) + + class Meta(BaseTable.Meta): + model = ConsolePort + fields = ('device', 'name', 'connection', 'reachable') + + +class PowerConnectionTable(PathEndpointTable): + device = tables.Column( + linkify=True + ) + name = tables.Column( + linkify=True, + verbose_name='Power Port' + ) + reachable = columns.BooleanColumn( + accessor=Accessor('_path__is_active'), + verbose_name='Reachable' + ) + + class Meta(BaseTable.Meta): + model = PowerPort + fields = ('device', 'name', 'connection', 'reachable') + + +class InterfaceConnectionTable(PathEndpointTable): + device = tables.Column( + accessor=Accessor('device'), + linkify=True + ) + interface = tables.Column( + accessor=Accessor('name'), + linkify=True + ) + reachable = columns.BooleanColumn( + accessor=Accessor('_path__is_active'), + verbose_name='Reachable' + ) + + class Meta(BaseTable.Meta): + model = Interface + fields = ('device', 'interface', 'connection', 'reachable') diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index a31eabc5e..39b2340e1 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -2893,7 +2893,7 @@ class CableBulkDeleteView(generic.BulkDeleteView): # class ConsoleConnectionsListView(generic.ObjectListView): - queryset = ConsolePort.objects.filter(_path__isnull=False).order_by('device') + queryset = ConsolePort.objects.filter(_path__is_complete=True) filterset = filtersets.ConsoleConnectionFilterSet filterset_form = forms.ConsoleConnectionFilterForm table = tables.ConsoleConnectionTable @@ -2907,7 +2907,7 @@ class ConsoleConnectionsListView(generic.ObjectListView): class PowerConnectionsListView(generic.ObjectListView): - queryset = PowerPort.objects.filter(_path__isnull=False).order_by('device') + queryset = PowerPort.objects.filter(_path__is_complete=True) filterset = filtersets.PowerConnectionFilterSet filterset_form = forms.PowerConnectionFilterForm table = tables.PowerConnectionTable @@ -2921,7 +2921,7 @@ class PowerConnectionsListView(generic.ObjectListView): class InterfaceConnectionsListView(generic.ObjectListView): - queryset = Interface.objects.filter(_path__isnull=False).order_by('device') + queryset = Interface.objects.filter(_path__is_complete=True) filterset = filtersets.InterfaceConnectionFilterSet filterset_form = forms.InterfaceConnectionFilterForm table = tables.InterfaceConnectionTable