* Add option to show neighbors * Updated documentation and help text * Added newlines at end of files where they where missing * Updated options screenshot * fix function vars ---------
This commit is contained in:
@@ -99,15 +99,13 @@ Go to the plugins tab in the navbar and click topology or go to `$NETBOX_URL/plu
|
|||||||
|
|
||||||
Select your options for the topology view:
|
Select your options for the topology view:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
<dl>
|
<dl>
|
||||||
<dt>Save Coordinates</dt>
|
<dt>Save Coordinates</dt>
|
||||||
<dd>Save the coordinates of devices in the topology view.</dd>
|
<dd>Save the coordinates of devices in the topology view.</dd>
|
||||||
<dt>Show Unconnected</dt>
|
<dt>Show Unconnected</dt>
|
||||||
<dd>Show devices that have no connections or for which no connection is displayed. This option depends on other parameters like 'Show Cables' and 'Show Logical Connections'.</dd>
|
<dd>Show devices that have no connections or for which no connection is displayed. This option depends on other parameters like 'Show Cables' and 'Show Logical Connections'.</dd>
|
||||||
<dt>Show Circuit Terminations</dt>
|
|
||||||
<dd>Show connections which end at a circuit termination in the topology view. These connections are displayed as blue dashed lines.</dd>
|
|
||||||
<dt>Show Cables</dt>
|
<dt>Show Cables</dt>
|
||||||
<dd>Show connections between interfaces, front / rear ports, etc., that are connected with one or more cables. These connections are displayed as solid lines in the color of the cable.</dd>
|
<dd>Show connections between interfaces, front / rear ports, etc., that are connected with one or more cables. These connections are displayed as solid lines in the color of the cable.</dd>
|
||||||
<dt>Show Logical Connections</dt>
|
<dt>Show Logical Connections</dt>
|
||||||
@@ -116,6 +114,10 @@ Select your options for the topology view:
|
|||||||
intermediate front / rear port connections, etc. This is similar to what was referred to as 'end-to-end' connections in previous versions. These connections are displayed as yellow dotted lines.</dd>
|
intermediate front / rear port connections, etc. This is similar to what was referred to as 'end-to-end' connections in previous versions. These connections are displayed as yellow dotted lines.</dd>
|
||||||
<dt>Show redundant Cable and Locigal Connection</dt>
|
<dt>Show redundant Cable and Locigal Connection</dt>
|
||||||
<dd>Shows a logical connection (in addition to a cable), even if a cable is directly connected. Leaving this option disabled prevents that redundant display. This option only has an effect if 'Show Logical Connections' is activated.</dd>
|
<dd>Shows a logical connection (in addition to a cable), even if a cable is directly connected. Leaving this option disabled prevents that redundant display. This option only has an effect if 'Show Logical Connections' is activated.</dd>
|
||||||
|
<dt>Show Neighbors</dt>
|
||||||
|
<dd>Adds neighbors to the filter result set automatically. Link peers will be added if 'Show Cables' is ticked, far-end terminations will be added if 'Show Logical Connections' is ticked.</dd>
|
||||||
|
<dt>Show Circuit Terminations</dt>
|
||||||
|
<dd>Show connections which end at a circuit termination in the topology view. These connections are displayed as blue dashed lines.</dd>
|
||||||
<dt>Show Power Feeds</dt>
|
<dt>Show Power Feeds</dt>
|
||||||
<dd>Displays connections between power outlets and power ports. These connections are displayed as solid lines in the color of the cable. This option depends on 'Show Cables'.</dd>
|
<dd>Displays connections between power outlets and power ports. These connections are displayed as solid lines in the color of the cable. This option depends on 'Show Cables'.</dd>
|
||||||
<dt>Show Wireless Links</dt>
|
<dt>Show Wireless Links</dt>
|
||||||
|
|||||||
@@ -25,4 +25,5 @@ class DeviceRoleSerializer(ModelSerializer):
|
|||||||
class IndividualOptionsSerializer(NetBoxModelSerializer):
|
class IndividualOptionsSerializer(NetBoxModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IndividualOptions
|
model = IndividualOptions
|
||||||
fields = ("ignore_cable_type", "show_unconnected", "show_cables", "show_logical_connections", "show_single_cable_logical_conns", "show_circuit", "show_power", "show_wireless", "draw_default_layout")
|
fields = ("ignore_cable_type", "show_unconnected", "show_cables", "show_logical_connections", "show_single_cable_logical_conns", "show_neighbors", "show_circuit", "show_power", "show_wireless", "draw_default_layout")
|
||||||
|
|
||||||
@@ -80,23 +80,29 @@ class ExportTopoToXML(PermissionRequiredMixin, ViewSet):
|
|||||||
user_id=request.user.id,
|
user_id=request.user.id,
|
||||||
)
|
)
|
||||||
|
|
||||||
save_coords, show_unconnected, show_power, show_circuit, show_logical_connections, show_single_cable_logical_conns, show_cables, show_wireless = get_query_settings(request)
|
if request.GET:
|
||||||
topo_data = get_topology_data(
|
|
||||||
self.queryset,
|
|
||||||
individualOptions,
|
|
||||||
show_unconnected,
|
|
||||||
save_coords,
|
|
||||||
show_cables,
|
|
||||||
show_circuit,
|
|
||||||
show_logical_connections,
|
|
||||||
show_single_cable_logical_conns,
|
|
||||||
show_power,
|
|
||||||
show_wireless,
|
|
||||||
)
|
|
||||||
xml_data = export_data_to_xml(topo_data).decode('utf-8')
|
|
||||||
|
|
||||||
return HttpResponse(xml_data, content_type="application/xml; charset=utf-8")
|
save_coords, show_unconnected, show_power, show_circuit, show_logical_connections, show_single_cable_logical_conns, show_cables, show_wireless, show_neighbors = get_query_settings(request)
|
||||||
|
topo_data = get_topology_data(
|
||||||
|
queryset=self.queryset,
|
||||||
|
individualOptions=individualOptions,
|
||||||
|
save_coords=save_coords,
|
||||||
|
show_unconnected=show_unconnected,
|
||||||
|
show_cables=show_cables,
|
||||||
|
show_logical_connections=show_logical_connections,
|
||||||
|
show_single_cable_logical_conns=show_single_cable_logical_conns,
|
||||||
|
show_neighbors=show_neighbors,
|
||||||
|
show_circuit=show_circuit,
|
||||||
|
show_power=show_power,
|
||||||
|
show_wireless=show_wireless,
|
||||||
|
)
|
||||||
|
xml_data = export_data_to_xml(topo_data).decode('utf-8')
|
||||||
|
|
||||||
|
return HttpResponse(xml_data, content_type="application/xml; charset=utf-8")
|
||||||
|
else:
|
||||||
|
return JsonResponse(
|
||||||
|
{"status": "Missing or malformed request parameters"}, status=400
|
||||||
|
)
|
||||||
|
|
||||||
class SaveRoleImageViewSet(PermissionRequiredMixin, ViewSet):
|
class SaveRoleImageViewSet(PermissionRequiredMixin, ViewSet):
|
||||||
queryset = DeviceRole.objects.none()
|
queryset = DeviceRole.objects.none()
|
||||||
|
|||||||
@@ -33,9 +33,10 @@ class DeviceFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|||||||
"save_coords",
|
"save_coords",
|
||||||
"show_unconnected",
|
"show_unconnected",
|
||||||
"show_cables",
|
"show_cables",
|
||||||
"show_circuit",
|
|
||||||
"show_logical_connections",
|
"show_logical_connections",
|
||||||
"show_single_cable_logical_conns",
|
"show_single_cable_logical_conns",
|
||||||
|
"show_neighbors",
|
||||||
|
"show_circuit",
|
||||||
"show_power",
|
"show_power",
|
||||||
"show_wireless",
|
"show_wireless",
|
||||||
),
|
),
|
||||||
@@ -118,17 +119,17 @@ class DeviceFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|||||||
show_unconnected = forms.BooleanField(
|
show_unconnected = forms.BooleanField(
|
||||||
label=_("Show Unconnected"), required=False, initial=False
|
label=_("Show Unconnected"), required=False, initial=False
|
||||||
)
|
)
|
||||||
|
show_cables = forms.BooleanField(
|
||||||
|
label =_("Show Cables"), required=False, initial=False
|
||||||
|
)
|
||||||
show_logical_connections = forms.BooleanField(
|
show_logical_connections = forms.BooleanField(
|
||||||
label =_("Show Logical Connections"), required=False, initial=False
|
label =_("Show Logical Connections"), required=False, initial=False
|
||||||
)
|
)
|
||||||
show_single_cable_logical_conns = forms.BooleanField(
|
show_single_cable_logical_conns = forms.BooleanField(
|
||||||
label =_("Show redundant Cable and Locigal Connection"), required=False, initial=False
|
label =_("Show redundant Cable and Locigal Connection"), required=False, initial=False
|
||||||
)
|
)
|
||||||
show_cables = forms.BooleanField(
|
show_neighbors = forms.BooleanField(
|
||||||
label =_("Show Cables"), required=False, initial=False
|
label =_("Show Neighbors"), required=False, initial=False
|
||||||
)
|
|
||||||
show_wireless = forms.BooleanField(
|
|
||||||
label =_("Show Wireless Links"), required=False, initial=False
|
|
||||||
)
|
)
|
||||||
show_circuit = forms.BooleanField(
|
show_circuit = forms.BooleanField(
|
||||||
label=_("Show Circuit Terminations"), required=False, initial=False
|
label=_("Show Circuit Terminations"), required=False, initial=False
|
||||||
@@ -136,6 +137,9 @@ class DeviceFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
|
|||||||
show_power = forms.BooleanField(
|
show_power = forms.BooleanField(
|
||||||
label=_("Show Power Feeds"), required=False, initial=False
|
label=_("Show Power Feeds"), required=False, initial=False
|
||||||
)
|
)
|
||||||
|
show_wireless = forms.BooleanField(
|
||||||
|
label =_("Show Wireless Links"), required=False, initial=False
|
||||||
|
)
|
||||||
|
|
||||||
class IndividualOptionsForm(NetBoxModelForm):
|
class IndividualOptionsForm(NetBoxModelForm):
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
@@ -148,9 +152,10 @@ class IndividualOptionsForm(NetBoxModelForm):
|
|||||||
"preselected_tags",
|
"preselected_tags",
|
||||||
"show_unconnected",
|
"show_unconnected",
|
||||||
"show_cables",
|
"show_cables",
|
||||||
"show_circuit",
|
|
||||||
"show_logical_connections",
|
"show_logical_connections",
|
||||||
"show_single_cable_logical_conns",
|
"show_single_cable_logical_conns",
|
||||||
|
"show_neighbors",
|
||||||
|
"show_circuit",
|
||||||
"show_power",
|
"show_power",
|
||||||
"show_wireless",
|
"show_wireless",
|
||||||
"draw_default_layout",
|
"draw_default_layout",
|
||||||
@@ -215,6 +220,14 @@ class IndividualOptionsForm(NetBoxModelForm):
|
|||||||
"disabled prevents that redundant display. This option only "
|
"disabled prevents that redundant display. This option only "
|
||||||
"has an effect if 'Show Logical Connections' is activated.")
|
"has an effect if 'Show Logical Connections' is activated.")
|
||||||
)
|
)
|
||||||
|
show_neighbors = forms.BooleanField(
|
||||||
|
label =_("Show Neighbors"),
|
||||||
|
required=False,
|
||||||
|
initial=False,
|
||||||
|
help_text=_("Adds neighbors to the filter result set automatically. "
|
||||||
|
"Link peers will be added if 'Show Cables' is ticked, far-end "
|
||||||
|
"terminations will be added if 'Show Logical Connections' is ticked.")
|
||||||
|
)
|
||||||
show_circuit = forms.BooleanField(
|
show_circuit = forms.BooleanField(
|
||||||
label=_("Show Circuit Terminations"),
|
label=_("Show Circuit Terminations"),
|
||||||
required=False,
|
required=False,
|
||||||
@@ -248,5 +261,6 @@ class IndividualOptionsForm(NetBoxModelForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = IndividualOptions
|
model = IndividualOptions
|
||||||
fields = [
|
fields = [
|
||||||
'user_id', 'ignore_cable_type', 'preselected_device_roles', 'preselected_tags', 'show_unconnected', 'show_cables', 'show_logical_connections', 'show_single_cable_logical_conns', 'show_circuit', 'show_power', 'show_wireless', 'draw_default_layout'
|
'user_id', 'ignore_cable_type', 'preselected_device_roles', 'preselected_tags', 'show_unconnected', 'show_cables', 'show_logical_connections', 'show_single_cable_logical_conns', 'show_neighbors', 'show_circuit', 'show_power', 'show_wireless', 'draw_default_layout'
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 4.1.8 on 2023-04-29 09:17
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('netbox_topology_views', '0002_individualoptions'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='individualoptions',
|
||||||
|
name='show_neighbors',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -137,6 +137,9 @@ class IndividualOptions(NetBoxModel):
|
|||||||
show_single_cable_logical_conns = models.BooleanField(
|
show_single_cable_logical_conns = models.BooleanField(
|
||||||
default=False
|
default=False
|
||||||
)
|
)
|
||||||
|
show_neighbors = models.BooleanField(
|
||||||
|
default=False
|
||||||
|
)
|
||||||
show_circuit = models.BooleanField(
|
show_circuit = models.BooleanField(
|
||||||
default=False
|
default=False
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -154,8 +154,13 @@ def get_query_settings(request):
|
|||||||
if "show_wireless" in request.GET:
|
if "show_wireless" in request.GET:
|
||||||
if request.GET["show_wireless"] == "on" :
|
if request.GET["show_wireless"] == "on" :
|
||||||
show_wireless = True
|
show_wireless = True
|
||||||
|
|
||||||
|
show_neighbors = False
|
||||||
|
if "show_neighbors" in request.GET:
|
||||||
|
if request.GET["show_neighbors"] == "on" :
|
||||||
|
show_neighbors = True
|
||||||
|
|
||||||
return save_coords, show_unconnected, show_power, show_circuit, show_logical_connections, show_single_cable_logical_conns, show_cables, show_wireless
|
return save_coords, show_unconnected, show_power, show_circuit, show_logical_connections, show_single_cable_logical_conns, show_cables, show_wireless, show_neighbors
|
||||||
|
|
||||||
class LinePattern():
|
class LinePattern():
|
||||||
wireless = [2, 10, 2, 10]
|
wireless = [2, 10, 2, 10]
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import json
|
|||||||
from functools import reduce
|
from functools import reduce
|
||||||
from typing import DefaultDict, Dict, Optional, Union
|
from typing import DefaultDict, Dict, Optional, Union
|
||||||
import time
|
import time
|
||||||
|
from itertools import chain
|
||||||
|
|
||||||
from utilities.htmx import is_htmx
|
from utilities.htmx import is_htmx
|
||||||
from circuits.models import Circuit, CircuitTermination
|
from circuits.models import Circuit, CircuitTermination
|
||||||
@@ -263,6 +264,7 @@ def get_topology_data(
|
|||||||
show_circuit: bool,
|
show_circuit: bool,
|
||||||
show_logical_connections: bool,
|
show_logical_connections: bool,
|
||||||
show_single_cable_logical_conns: bool,
|
show_single_cable_logical_conns: bool,
|
||||||
|
show_neighbors: bool,
|
||||||
show_power: bool,
|
show_power: bool,
|
||||||
show_wireless: bool,
|
show_wireless: bool,
|
||||||
):
|
):
|
||||||
@@ -290,6 +292,31 @@ def get_topology_data(
|
|||||||
device_ids = [d.pk for d in queryset]
|
device_ids = [d.pk for d in queryset]
|
||||||
site_ids = [d.site_id for d in queryset]
|
site_ids = [d.site_id for d in queryset]
|
||||||
|
|
||||||
|
if show_neighbors:
|
||||||
|
interfaces = Interface.objects.filter(
|
||||||
|
Q(device_id__in=device_ids)
|
||||||
|
)
|
||||||
|
frontports = FrontPort.objects.filter(
|
||||||
|
Q(device_id__in=device_ids)
|
||||||
|
)
|
||||||
|
rearports = RearPort.objects.filter(
|
||||||
|
Q(device_id__in=device_ids)
|
||||||
|
)
|
||||||
|
|
||||||
|
ports = chain(interfaces, frontports, rearports)
|
||||||
|
for port in ports:
|
||||||
|
for link_peer in port.link_peers:
|
||||||
|
if link_peer.device.id not in device_ids:
|
||||||
|
device_ids.append(link_peer.device.id)
|
||||||
|
|
||||||
|
if show_logical_connections:
|
||||||
|
path_complete_interfaces = Interface.objects.filter(
|
||||||
|
Q(_path__is_complete=True) & Q(device_id__in=device_ids)
|
||||||
|
)
|
||||||
|
for path_complete_interface in path_complete_interfaces:
|
||||||
|
for connected_endpoint in path_complete_interface.connected_endpoints:
|
||||||
|
device_ids.append(connected_endpoint.device.id)
|
||||||
|
|
||||||
if show_circuit:
|
if show_circuit:
|
||||||
circuit_terminations = CircuitTermination.objects.filter(
|
circuit_terminations = CircuitTermination.objects.filter(
|
||||||
Q(site_id__in=site_ids) | Q(provider_network__isnull=False)
|
Q(site_id__in=site_ids) | Q(provider_network__isnull=False)
|
||||||
@@ -600,20 +627,21 @@ class TopologyHomeView(PermissionRequiredMixin, View):
|
|||||||
|
|
||||||
if request.GET:
|
if request.GET:
|
||||||
|
|
||||||
save_coords, show_unconnected, show_power, show_circuit, show_logical_connections, show_single_cable_logical_conns, show_cables, show_wireless = get_query_settings(request)
|
save_coords, show_unconnected, show_power, show_circuit, show_logical_connections, show_single_cable_logical_conns, show_cables, show_wireless, show_neighbors = get_query_settings(request)
|
||||||
|
|
||||||
if not "draw_init" in request.GET or "draw_init" in request.GET and request.GET["draw_init"].lower() == "true":
|
if not "draw_init" in request.GET or "draw_init" in request.GET and request.GET["draw_init"].lower() == "true":
|
||||||
topo_data = get_topology_data(
|
topo_data = get_topology_data(
|
||||||
self.queryset,
|
queryset=self.queryset,
|
||||||
individualOptions,
|
individualOptions=individualOptions,
|
||||||
show_unconnected,
|
save_coords=save_coords,
|
||||||
save_coords,
|
show_unconnected=show_unconnected,
|
||||||
show_cables,
|
show_cables=show_cables,
|
||||||
show_circuit,
|
show_logical_connections=show_logical_connections,
|
||||||
show_logical_connections,
|
show_single_cable_logical_conns=show_single_cable_logical_conns,
|
||||||
show_single_cable_logical_conns,
|
show_neighbors=show_neighbors,
|
||||||
show_power,
|
show_circuit=show_circuit,
|
||||||
show_wireless,
|
show_power=show_power,
|
||||||
|
show_wireless=show_wireless,
|
||||||
)
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@@ -629,6 +657,7 @@ class TopologyHomeView(PermissionRequiredMixin, View):
|
|||||||
if individualOptions.show_cables: q['show_cables'] = "on"
|
if individualOptions.show_cables: q['show_cables'] = "on"
|
||||||
if individualOptions.show_logical_connections: q['show_logical_connections'] = "on"
|
if individualOptions.show_logical_connections: q['show_logical_connections'] = "on"
|
||||||
if individualOptions.show_single_cable_logical_conns: q['show_single_cable_logical_conns'] = "on"
|
if individualOptions.show_single_cable_logical_conns: q['show_single_cable_logical_conns'] = "on"
|
||||||
|
if individualOptions.show_neighbors: q['show_neighbors'] = "on"
|
||||||
if individualOptions.show_circuit: q['show_circuit'] = "on"
|
if individualOptions.show_circuit: q['show_circuit'] = "on"
|
||||||
if individualOptions.show_power: q['show_power'] = "on"
|
if individualOptions.show_power: q['show_power'] = "on"
|
||||||
if individualOptions.show_wireless: q['show_wireless'] = "on"
|
if individualOptions.show_wireless: q['show_wireless'] = "on"
|
||||||
@@ -751,6 +780,7 @@ class TopologyIndividualOptionsView(PermissionRequiredMixin, View):
|
|||||||
'show_cables': queryset.show_cables,
|
'show_cables': queryset.show_cables,
|
||||||
'show_logical_connections': queryset.show_logical_connections,
|
'show_logical_connections': queryset.show_logical_connections,
|
||||||
'show_single_cable_logical_conns': queryset.show_single_cable_logical_conns,
|
'show_single_cable_logical_conns': queryset.show_single_cable_logical_conns,
|
||||||
|
'show_neighbors': queryset.show_neighbors,
|
||||||
'show_circuit': queryset.show_circuit,
|
'show_circuit': queryset.show_circuit,
|
||||||
'show_power': queryset.show_power,
|
'show_power': queryset.show_power,
|
||||||
'show_wireless': queryset.show_wireless,
|
'show_wireless': queryset.show_wireless,
|
||||||
|
|||||||
Reference in New Issue
Block a user