From a3882885eb59d34392b210cd189fbb1428f77141 Mon Sep 17 00:00:00 2001 From: Igor Korotchenkov <32979193+iDebugAll@users.noreply.github.com> Date: Sun, 18 Dec 2022 14:40:52 +0400 Subject: [PATCH] NetBox 3.3 compatibility (#114) * NetBox 3.3 compatibility fix NetBox Cable model has changed. Updating object filtering and handling accordingly. * v0.10.0 --- nextbox_ui_plugin/__init__.py | 2 +- nextbox_ui_plugin/views.py | 72 +++++++++++++++++++++++++---------- setup.py | 4 +- 3 files changed, 55 insertions(+), 23 deletions(-) diff --git a/nextbox_ui_plugin/__init__.py b/nextbox_ui_plugin/__init__.py index 04e26cd..69616e4 100644 --- a/nextbox_ui_plugin/__init__.py +++ b/nextbox_ui_plugin/__init__.py @@ -4,7 +4,7 @@ class NextBoxUIConfig(PluginConfig): name = 'nextbox_ui_plugin' verbose_name = 'NextBox UI' description = 'A topology visualization plugin for Netbox powered by NextUI Toolkit.' - version = '0.9.2' + version = '0.10.0' author = 'Igor Korotchenkov' author_email = 'iDebugAll@gmail.com' base_url = 'nextbox-ui' diff --git a/nextbox_ui_plugin/views.py b/nextbox_ui_plugin/views.py index 3e6187c..d0f77c2 100644 --- a/nextbox_ui_plugin/views.py +++ b/nextbox_ui_plugin/views.py @@ -2,7 +2,7 @@ from django.shortcuts import render from django.views.generic import View -from dcim.models import Cable, Device, Interface, DeviceRole +from dcim.models import Cable, Device, Interface, DeviceRole, PowerFeed from ipam.models import VLAN from .models import SavedTopology from . import forms, filters @@ -334,22 +334,42 @@ def get_topology(nb_devices_qs): tags = filter_tags(tags) for tag in tags: all_device_tags.add((tag, not tag_is_hidden(tag))) - links_from_device = Cable.objects.filter(_termination_a_device_id=nb_device.id) - links_to_device = Cable.objects.filter(_termination_b_device_id=nb_device.id) - if links_from_device: - # Device is considered passive if it has no linked Interfaces. - # Passive cabling devices use Rear and Front Ports. - for link in links_from_device: - if isinstance(link.termination_a, Interface) and link.termination_a.device.id == nb_device.id: - break - else: - device_is_passive = True - if links_to_device: - for link in links_to_device: - if isinstance(link.termination_b, Interface) and link.termination_b.device.id == nb_device.id: - break - else: - device_is_passive = True + # Device is considered passive if it has no linked Interfaces. + # Passive cabling devices use Rear and Front Ports. + if NETBOX_CURRENT_VERSION < version.parse("3.3"): + links_from_device = Cable.objects.filter(_termination_a_device_id=nb_device.id) + links_to_device = Cable.objects.filter(_termination_b_device_id=nb_device.id) + if links_from_device: + for link in links_from_device: + if isinstance(link.termination_a, Interface) and link.termination_a.device.id == nb_device.id: + break + else: + device_is_passive = True + if links_to_device: + for link in links_to_device: + if isinstance(link.termination_b, Interface) and link.termination_b.device.id == nb_device.id: + break + else: + device_is_passive = True + else: + links_from_device = Cable.objects.filter(terminations__cable_end='A', terminations___device_id=nb_device.id) + links_to_device = Cable.objects.filter(terminations__cable_end='B', terminations___device_id=nb_device.id) + interfaces_found = False + if links_from_device: + for link in links_from_device: + for ab_link in link.a_terminations + link.b_terminations: + if isinstance(ab_link, Interface) and ab_link.device.id == nb_device.id: + interfaces_found = True + break + if links_to_device: + for link in links_to_device: + for ab_link in link.a_terminations + link.b_terminations: + if isinstance(ab_link, Interface) and ab_link.device.id == nb_device.id: + interfaces_found = True + break + if links_to_device or links_from_device: + device_is_passive = not interfaces_found + topology_dict['nodes'].append({ 'id': nb_device.id, 'name': nb_device.name, @@ -372,9 +392,18 @@ def get_topology(nb_devices_qs): if not links_from_device: continue for link in links_from_device: - # Include links to discovered devices only - if link._termination_b_device_id in device_ids: - links.append(link) + if NETBOX_CURRENT_VERSION < version.parse("3.3"): + # Include links to discovered devices only + if link._termination_b_device_id in device_ids: + links.append(link) + else: + # Exclude PowerFeed-connected links + if (isinstance(link.a_terminations[0], PowerFeed) or (isinstance(link.b_terminations[0], PowerFeed))): + continue + # Include links to discovered devices only + if link.b_terminations[0].device_id in device_ids: + links.append(link) + device_roles = list(device_roles) device_roles.sort(key=lambda i: get_node_layer_sort_preference(i[0])) all_device_tags = list(all_device_tags) @@ -384,6 +413,9 @@ def get_topology(nb_devices_qs): link_ids = set() for link in links: link_ids.add(link.id) + if NETBOX_CURRENT_VERSION > version.parse("3.3"): + link.termination_a = link.a_terminations[0] + link.termination_b = link.b_terminations[0] topology_dict['links'].append({ 'id': link.id, 'source': link.termination_a.device.id, diff --git a/setup.py b/setup.py index cff0061..df5b4bf 100644 --- a/setup.py +++ b/setup.py @@ -7,9 +7,9 @@ setup( name='nextbox_ui_plugin', - version='0.9.2', + version='0.10.0', url='https://github.com/iDebugAll/nextbox-ui-plugin', - download_url='https://github.com/iDebugAll/nextbox-ui-plugin/archive/v0.9.2.tar.gz', + download_url='https://github.com/iDebugAll/nextbox-ui-plugin/archive/v0.10.0.tar.gz', description='A topology visualization plugin for Netbox powered by NextUI Toolkit.', long_description=long_description, long_description_content_type='text/markdown',