Compare commits

..
10 Commits
Author SHA1 Message Date
Mattijs Vanhaverbeke 9ce13cd1d2 bump version 2022-09-16 16:14:42 +02:00
mattieserver b4e2f2418e added extra checks (#166) 2022-09-16 16:13:32 +02:00
mattieserver 5563e3c084 added device filter option (#165) 2022-09-16 16:07:14 +02:00
mattieserver 77a8a2c0d6 Removed print 2022-09-16 14:52:00 +02:00
mattieserver 010179742c 159 fix power filter (#164)
* fix site_ids var

* fixed power cable name + change power filter name
2022-09-16 14:50:24 +02:00
mattieserver f2bbaed317 added console cable support (#157)
* added console cable support

* removed print
2022-09-14 14:50:10 +02:00
mattieserver 8c56f21f16 Update README.md 2022-09-13 08:46:05 +02:00
mattieserver eb627bdedc Update README.md 2022-09-12 18:36:27 +02:00
mattieserver 291c033e34 Update README.md 2022-09-12 18:23:33 +02:00
mattieserver 1f389b3faa Update README.md 2022-09-12 18:20:18 +02:00
6 changed files with 49 additions and 26 deletions
+13 -2
View File
@@ -29,7 +29,15 @@ Once installed, the plugin needs to be enabled in your `configuration.py`
PLUGINS = ["netbox_topology_views"]
```
Then run `python3 manage.py collectstatic --no-input`
First run `source /opt/netbox/venv/bin/activate` to enter the Python virtual environment.
Then run
```bash
cd /opt/netbox/netbox
pip3 install netbox-topology-views
python3 manage.py collectstatic --no-input
```
### Versions
@@ -48,7 +56,10 @@ There is also support for custom fields.
If you create a custom field "coordinates" for "dcim > device" and "Circuits > circuit" with type "text" and name "coordinates" you will see the same layout every time.
The coordinates can then be provided as: "X;Y"
The coordinates can then be provided as: "X;Y".
Please read the "Configure" chapter to set the `allow_coordinates_saving` option to True.
You might also set the `always_save_coordinates` option to True.
## Configure
+1 -1
View File
@@ -4,7 +4,7 @@ class TopologyViewsConfig(PluginConfig):
name = 'netbox_topology_views'
verbose_name = 'Topology views'
description = 'An plugin to render topology maps'
version = '3.0.0'
version = '3.0.1'
author = 'Mattijs Vanhaverbeke'
author_email = 'author@example.com'
base_url = 'netbox_topology_views'
+2 -3
View File
@@ -41,10 +41,9 @@ class DeviceFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
)
status = django_filters.MultipleChoiceFilter(
choices=DeviceStatusChoices,
null_value=None
null_value=None,
)
class Meta:
model = Device
fields = ['id', 'name']
+16 -5
View File
@@ -22,10 +22,10 @@ class DeviceFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = Device
fieldsets = (
(None, ('q', 'hide_unconnected', 'save_coords', 'show_circuit', 'show_power' ,)),
(None, ('tenant_group_id', 'tenant_id')),
(None, ('region_id', 'site_id', 'location_id')),
(None, ('device_role_id', )),
(None, ('tag', 'status')),
(None, ('tenant_group_id', 'tenant_id',)),
(None, ('region_id', 'site_id', 'location_id',)),
(None, ('device_role_id','id','status', )),
(None, ('tag', )),
)
region_id = DynamicModelMultipleChoiceField(
@@ -38,6 +38,17 @@ class DeviceFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
required=False,
label=_('Device Role')
)
id = DynamicModelMultipleChoiceField(
queryset=Device.objects.all(),
required=False,
label=_('Device'),
query_params={
'location_id' : '$location_id',
'region_id': '$region_id',
'site_id': '$site_id',
'role_id': '$device_role_id',
},
)
site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(),
required=False,
@@ -66,7 +77,7 @@ class DeviceFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
initial=False
)
show_power = forms.BooleanField(
label=_("Show Power panel/feed"),
label=_("Show Power Feeds"),
required=False,
initial=False
)
+16 -14
View File
@@ -1,5 +1,4 @@
from platform import node
from django.shortcuts import get_object_or_404, render
from django.shortcuts import render
from django.db.models import Q
from django.views.generic import View
from django.contrib.auth.mixins import PermissionRequiredMixin
@@ -7,18 +6,17 @@ from django.conf import settings
from django.http import QueryDict
from django.http import HttpResponseRedirect
from .forms import DeviceFilterForm
from .filters import DeviceFilterSet
import json
from dcim.models import Device, Cable, CableTermination, DeviceRole, PathEndpoint, Interface, FrontPort, RearPort, PowerPanel, PowerFeed
from circuits.models import CircuitTermination, ProviderNetwork
from dcim.models import Device, CableTermination, DeviceRole, Interface, FrontPort, RearPort, PowerPanel, PowerFeed
from circuits.models import CircuitTermination
from wireless.models import WirelessLink
from extras.models import Tag
supported_termination_types = ["interface", "front port", "rear port", "power outlet", "power port"]
supported_termination_types = ["interface", "front port", "rear port", "power outlet", "power port", "console port", "console server port"]
def create_node(device, save_coords, circuit = None, powerpanel = None, powerfeed= None):
@@ -170,9 +168,9 @@ def get_topology_data(queryset, hide_unconnected, save_coords, show_circuit, sho
ignore_cable_type = settings.PLUGINS_CONFIG["netbox_topology_views"]["ignore_cable_type"]
device_ids = [d.id for d in queryset]
site_ids = [d.site.id for d in queryset]
if show_circuit:
site_ids = [d.site.id for d in queryset]
circuits = CircuitTermination.objects.filter( Q(site_id__in=site_ids) | Q( provider_network__isnull=False) ).prefetch_related("provider_network", "circuit")
for circuit in circuits:
if not hide_unconnected and circuit.circuit.id not in nodes_circuits:
@@ -224,16 +222,18 @@ def get_topology_data(queryset, hide_unconnected, save_coords, show_circuit, sho
if power_feed.power_panel.id not in nodes_powerpanel:
nodes_powerpanel[power_feed.power_panel.id] = power_feed.power_panel
power_link_name = ""
if power_feed.id not in nodes_powerfeed:
if hide_unconnected:
if power_feed.link_peers[0].device.id in device_ids:
nodes_powerfeed[power_feed.id] = power_feed
power_link_name =power_feed.link_peers[0].name
else:
nodes_powerfeed[power_feed.id] = power_feed
edge_ids += 1
termination_a = { "termination_name": power_feed.power_panel.name, "termination_device_name": str(power_feed.power_panel.id), "device_id": "p{}".format(power_feed.power_panel.id) }
termination_b = { "termination_name": power_feed.name, "termination_device_name": str(termination.id), "device_id": "f{}".format(power_feed.id) }
termination_a = { "termination_name": power_feed.power_panel.name, "termination_device_name": "", "device_id": "p{}".format(power_feed.power_panel.id) }
termination_b = { "termination_name": power_feed.name, "termination_device_name": power_link_name, "device_id": "f{}".format(power_feed.id) }
edges.append(create_edge(edge_id=edge_ids, termination_a=termination_a, termination_b=termination_b, power=True))
if power_feed.cable_id is not None:
@@ -259,14 +259,16 @@ def get_topology_data(queryset, hide_unconnected, save_coords, show_circuit, sho
if link.cable.id not in cable_ids:
cable_ids[link.cable.id] = {}
else:
if cable_ids[link.cable.id]['B'] is not None:
complete_link = True
if 'B' in cable_ids[link.cable.id]:
if cable_ids[link.cable.id]['B'] is not None:
complete_link = True
elif link.cable_end == "B":
if link.cable.id not in cable_ids:
cable_ids[link.cable.id] = {}
else:
if cable_ids[link.cable.id]['A'] is not None:
complete_link = True
if 'A' in cable_ids[link.cable.id]:
if cable_ids[link.cable.id]['A'] is not None:
complete_link = True
else:
print("Unkown cable end")
cable_ids[link.cable.id][link.cable_end] = link
@@ -288,7 +290,7 @@ def get_topology_data(queryset, hide_unconnected, save_coords, show_circuit, sho
termination_a = cable_ids[link.cable.id]["A"]
edges.append(create_edge(edge_id=edge_ids, cable=link.cable, termination_a=termination_a, termination_b=termination_b))
for wlan_link in wlan_links:
if wlan_link.interface_a.device.id not in nodes_devices:
nodes_devices[wlan_link.interface_a.device.id] = wlan_link.interface_a.device
+1 -1
View File
@@ -7,7 +7,7 @@ with open(path.join(top_level_directory, 'README.md'), encoding='utf-8') as file
setup(
name='netbox-topology-views',
version='3.0.0',
version='3.0.1',
description='An NetBox plugin to create Topology maps',
long_description=long_description,
long_description_content_type='text/markdown',