mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Record wireless links as part of cable path
This commit is contained in:
@ -379,7 +379,7 @@ class CablePath(BigIDModel):
|
|||||||
"""
|
"""
|
||||||
from circuits.models import CircuitTermination
|
from circuits.models import CircuitTermination
|
||||||
|
|
||||||
if origin is None or origin.cable is None:
|
if origin is None or origin.link is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
destination = None
|
destination = None
|
||||||
@ -389,12 +389,12 @@ class CablePath(BigIDModel):
|
|||||||
is_split = False
|
is_split = False
|
||||||
|
|
||||||
node = origin
|
node = origin
|
||||||
while node.cable is not None:
|
while node.link is not None:
|
||||||
if node.cable.status != CableStatusChoices.STATUS_CONNECTED:
|
if hasattr(node.link, 'status') and node.link.status != CableStatusChoices.STATUS_CONNECTED:
|
||||||
is_active = False
|
is_active = False
|
||||||
|
|
||||||
# Follow the cable to its far-end termination
|
# Follow the link to its far-end termination
|
||||||
path.append(object_to_path_node(node.cable))
|
path.append(object_to_path_node(node.link))
|
||||||
peer_termination = node.get_cable_peer()
|
peer_termination = node.get_cable_peer()
|
||||||
|
|
||||||
# Follow a FrontPort to its corresponding RearPort
|
# Follow a FrontPort to its corresponding RearPort
|
||||||
|
@ -157,6 +157,13 @@ class CableTermination(models.Model):
|
|||||||
def parent_object(self):
|
def parent_object(self):
|
||||||
raise NotImplementedError("CableTermination models must implement parent_object()")
|
raise NotImplementedError("CableTermination models must implement parent_object()")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def link(self):
|
||||||
|
"""
|
||||||
|
Generic wrapper for a Cable, WirelessLink, or some other relation to a connected termination.
|
||||||
|
"""
|
||||||
|
return self.cable
|
||||||
|
|
||||||
|
|
||||||
class PathEndpoint(models.Model):
|
class PathEndpoint(models.Model):
|
||||||
"""
|
"""
|
||||||
@ -657,6 +664,10 @@ class Interface(ComponentModel, BaseInterface, CableTermination, PathEndpoint):
|
|||||||
def is_lag(self):
|
def is_lag(self):
|
||||||
return self.type == InterfaceTypeChoices.TYPE_LAG
|
return self.type == InterfaceTypeChoices.TYPE_LAG
|
||||||
|
|
||||||
|
@property
|
||||||
|
def link(self):
|
||||||
|
return self.cable or self.wireless_link
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Pass-through ports
|
# Pass-through ports
|
||||||
|
@ -2,37 +2,11 @@ import logging
|
|||||||
|
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.db.models.signals import post_save, post_delete, pre_delete
|
from django.db.models.signals import post_save, post_delete, pre_delete
|
||||||
from django.db import transaction
|
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
|
||||||
from .choices import CableStatusChoices
|
from .choices import CableStatusChoices
|
||||||
from .models import Cable, CablePath, Device, PathEndpoint, PowerPanel, Rack, Location, VirtualChassis
|
from .models import Cable, CablePath, Device, PathEndpoint, PowerPanel, Rack, Location, VirtualChassis
|
||||||
|
from .utils import create_cablepath, rebuild_paths
|
||||||
|
|
||||||
def create_cablepath(node):
|
|
||||||
"""
|
|
||||||
Create CablePaths for all paths originating from the specified node.
|
|
||||||
"""
|
|
||||||
cp = CablePath.from_origin(node)
|
|
||||||
if cp:
|
|
||||||
try:
|
|
||||||
cp.save()
|
|
||||||
except Exception as e:
|
|
||||||
print(node, node.pk)
|
|
||||||
raise e
|
|
||||||
|
|
||||||
|
|
||||||
def rebuild_paths(obj):
|
|
||||||
"""
|
|
||||||
Rebuild all CablePaths which traverse the specified node
|
|
||||||
"""
|
|
||||||
cable_paths = CablePath.objects.filter(path__contains=obj)
|
|
||||||
|
|
||||||
with transaction.atomic():
|
|
||||||
for cp in cable_paths:
|
|
||||||
cp.delete()
|
|
||||||
if cp.origin:
|
|
||||||
create_cablepath(cp.origin)
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
from django.db import transaction
|
||||||
|
|
||||||
|
|
||||||
def compile_path_node(ct_id, object_id):
|
def compile_path_node(ct_id, object_id):
|
||||||
@ -26,3 +27,29 @@ def path_node_to_object(repr):
|
|||||||
ct_id, object_id = decompile_path_node(repr)
|
ct_id, object_id = decompile_path_node(repr)
|
||||||
ct = ContentType.objects.get_for_id(ct_id)
|
ct = ContentType.objects.get_for_id(ct_id)
|
||||||
return ct.model_class().objects.get(pk=object_id)
|
return ct.model_class().objects.get(pk=object_id)
|
||||||
|
|
||||||
|
|
||||||
|
def create_cablepath(node):
|
||||||
|
"""
|
||||||
|
Create CablePaths for all paths originating from the specified node.
|
||||||
|
"""
|
||||||
|
from dcim.models import CablePath
|
||||||
|
|
||||||
|
cp = CablePath.from_origin(node)
|
||||||
|
if cp:
|
||||||
|
cp.save()
|
||||||
|
|
||||||
|
|
||||||
|
def rebuild_paths(obj):
|
||||||
|
"""
|
||||||
|
Rebuild all CablePaths which traverse the specified node
|
||||||
|
"""
|
||||||
|
from dcim.models import CablePath
|
||||||
|
|
||||||
|
cable_paths = CablePath.objects.filter(path__contains=obj)
|
||||||
|
|
||||||
|
with transaction.atomic():
|
||||||
|
for cp in cable_paths:
|
||||||
|
cp.delete()
|
||||||
|
if cp.origin:
|
||||||
|
create_cablepath(cp.origin)
|
||||||
|
@ -3,7 +3,8 @@ import logging
|
|||||||
from django.db.models.signals import post_save, post_delete
|
from django.db.models.signals import post_save, post_delete
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
|
||||||
from dcim.models import Interface
|
from dcim.models import CablePath, Interface
|
||||||
|
from dcim.utils import create_cablepath
|
||||||
from .models import WirelessLink
|
from .models import WirelessLink
|
||||||
|
|
||||||
|
|
||||||
@ -12,11 +13,10 @@ from .models import WirelessLink
|
|||||||
#
|
#
|
||||||
|
|
||||||
@receiver(post_save, sender=WirelessLink)
|
@receiver(post_save, sender=WirelessLink)
|
||||||
def update_connected_interfaces(instance, raw=False, **kwargs):
|
def update_connected_interfaces(instance, created, raw=False, **kwargs):
|
||||||
"""
|
"""
|
||||||
When a WirelessLink is saved, save a reference to it on each connected interface.
|
When a WirelessLink is saved, save a reference to it on each connected interface.
|
||||||
"""
|
"""
|
||||||
print('update_connected_interfaces')
|
|
||||||
logger = logging.getLogger('netbox.wireless.wirelesslink')
|
logger = logging.getLogger('netbox.wireless.wirelesslink')
|
||||||
if raw:
|
if raw:
|
||||||
logger.debug(f"Skipping endpoint updates for imported wireless link {instance}")
|
logger.debug(f"Skipping endpoint updates for imported wireless link {instance}")
|
||||||
@ -25,21 +25,25 @@ def update_connected_interfaces(instance, raw=False, **kwargs):
|
|||||||
if instance.interface_a.wireless_link != instance:
|
if instance.interface_a.wireless_link != instance:
|
||||||
logger.debug(f"Updating interface A for wireless link {instance}")
|
logger.debug(f"Updating interface A for wireless link {instance}")
|
||||||
instance.interface_a.wireless_link = instance
|
instance.interface_a.wireless_link = instance
|
||||||
# instance.interface_a._cable_peer = instance.interface_b # TODO: Rename _cable_peer field
|
instance.interface_a._cable_peer = instance.interface_b # TODO: Rename _cable_peer field
|
||||||
instance.interface_a.save()
|
instance.interface_a.save()
|
||||||
if instance.interface_b.cable != instance:
|
if instance.interface_b.cable != instance:
|
||||||
logger.debug(f"Updating interface B for wireless link {instance}")
|
logger.debug(f"Updating interface B for wireless link {instance}")
|
||||||
instance.interface_b.wireless_link = instance
|
instance.interface_b.wireless_link = instance
|
||||||
# instance.interface_b._cable_peer = instance.interface_a
|
instance.interface_b._cable_peer = instance.interface_a
|
||||||
instance.interface_b.save()
|
instance.interface_b.save()
|
||||||
|
|
||||||
|
# Create/update cable paths
|
||||||
|
if created:
|
||||||
|
for interface in (instance.interface_a, instance.interface_b):
|
||||||
|
create_cablepath(interface)
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_delete, sender=WirelessLink)
|
@receiver(post_delete, sender=WirelessLink)
|
||||||
def nullify_connected_interfaces(instance, **kwargs):
|
def nullify_connected_interfaces(instance, **kwargs):
|
||||||
"""
|
"""
|
||||||
When a WirelessLink is deleted, update its two connected Interfaces
|
When a WirelessLink is deleted, update its two connected Interfaces
|
||||||
"""
|
"""
|
||||||
print('nullify_connected_interfaces')
|
|
||||||
logger = logging.getLogger('netbox.wireless.wirelesslink')
|
logger = logging.getLogger('netbox.wireless.wirelesslink')
|
||||||
|
|
||||||
if instance.interface_a is not None:
|
if instance.interface_a is not None:
|
||||||
@ -56,3 +60,8 @@ def nullify_connected_interfaces(instance, **kwargs):
|
|||||||
_cable_peer_type=None,
|
_cable_peer_type=None,
|
||||||
_cable_peer_id=None
|
_cable_peer_id=None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Delete and retrace any dependent cable paths
|
||||||
|
for cablepath in CablePath.objects.filter(path__contains=instance):
|
||||||
|
print(f'Deleting cable path {cablepath.pk}')
|
||||||
|
cablepath.delete()
|
||||||
|
Reference in New Issue
Block a user