1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Rename cable_peer fields to link_peer

This commit is contained in:
jeremystretch
2021-10-13 14:04:53 -04:00
parent 1c73bd5079
commit ac2cd552b9
19 changed files with 236 additions and 114 deletions

View File

@ -3,7 +3,7 @@ from rest_framework import serializers
from circuits.choices import CircuitStatusChoices from circuits.choices import CircuitStatusChoices
from circuits.models import * from circuits.models import *
from dcim.api.nested_serializers import NestedCableSerializer, NestedSiteSerializer from dcim.api.nested_serializers import NestedCableSerializer, NestedSiteSerializer
from dcim.api.serializers import CableTerminationSerializer from dcim.api.serializers import LinkTerminationSerializer
from netbox.api import ChoiceField from netbox.api import ChoiceField
from netbox.api.serializers import ( from netbox.api.serializers import (
OrganizationalModelSerializer, PrimaryModelSerializer, ValidatedModelSerializer, WritableNestedSerializer OrganizationalModelSerializer, PrimaryModelSerializer, ValidatedModelSerializer, WritableNestedSerializer
@ -90,7 +90,7 @@ class CircuitSerializer(PrimaryModelSerializer):
] ]
class CircuitTerminationSerializer(ValidatedModelSerializer, CableTerminationSerializer): class CircuitTerminationSerializer(ValidatedModelSerializer, LinkTerminationSerializer):
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuittermination-detail') url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuittermination-detail')
circuit = NestedCircuitSerializer() circuit = NestedCircuitSerializer()
site = NestedSiteSerializer(required=False, allow_null=True) site = NestedSiteSerializer(required=False, allow_null=True)
@ -101,6 +101,6 @@ class CircuitTerminationSerializer(ValidatedModelSerializer, CableTerminationSer
model = CircuitTermination model = CircuitTermination
fields = [ fields = [
'id', 'url', 'display', 'circuit', 'term_side', 'site', 'provider_network', 'port_speed', 'upstream_speed', 'id', 'url', 'display', 'circuit', 'term_side', 'site', 'provider_network', 'port_speed', 'upstream_speed',
'xconnect_id', 'pp_info', 'description', 'mark_connected', 'cable', 'cable_peer', 'cable_peer_type', 'xconnect_id', 'pp_info', 'description', 'mark_connected', 'cable', 'link_peer', 'link_peer_type',
'_occupied', '_occupied',
] ]

View File

@ -0,0 +1,23 @@
# Generated by Django 3.2.8 on 2021-10-13 17:47
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('circuits', '0002_squashed_0029'),
]
operations = [
migrations.RenameField(
model_name='circuittermination',
old_name='_cable_peer_id',
new_name='_link_peer_id',
),
migrations.RenameField(
model_name='circuittermination',
old_name='_cable_peer_type',
new_name='_link_peer_type',
),
]

View File

@ -4,7 +4,7 @@ from django.db import models
from django.urls import reverse from django.urls import reverse
from dcim.fields import ASNField from dcim.fields import ASNField
from dcim.models import CableTermination, PathEndpoint from dcim.models import LinkTermination, PathEndpoint
from extras.models import ObjectChange from extras.models import ObjectChange
from extras.utils import extras_features from extras.utils import extras_features
from netbox.models import BigIDModel, ChangeLoggedModel, OrganizationalModel, PrimaryModel from netbox.models import BigIDModel, ChangeLoggedModel, OrganizationalModel, PrimaryModel
@ -246,7 +246,7 @@ class Circuit(PrimaryModel):
@extras_features('webhooks') @extras_features('webhooks')
class CircuitTermination(ChangeLoggedModel, CableTermination): class CircuitTermination(ChangeLoggedModel, LinkTermination):
circuit = models.ForeignKey( circuit = models.ForeignKey(
to='circuits.Circuit', to='circuits.Circuit',
on_delete=models.CASCADE, on_delete=models.CASCADE,

View File

@ -22,25 +22,25 @@ from virtualization.api.nested_serializers import NestedClusterSerializer
from .nested_serializers import * from .nested_serializers import *
class CableTerminationSerializer(serializers.ModelSerializer): class LinkTerminationSerializer(serializers.ModelSerializer):
cable_peer_type = serializers.SerializerMethodField(read_only=True) link_peer_type = serializers.SerializerMethodField(read_only=True)
cable_peer = serializers.SerializerMethodField(read_only=True) link_peer = serializers.SerializerMethodField(read_only=True)
_occupied = serializers.SerializerMethodField(read_only=True) _occupied = serializers.SerializerMethodField(read_only=True)
def get_cable_peer_type(self, obj): def get_link_peer_type(self, obj):
if obj._cable_peer is not None: if obj._link_peer is not None:
return f'{obj._cable_peer._meta.app_label}.{obj._cable_peer._meta.model_name}' return f'{obj._link_peer._meta.app_label}.{obj._link_peer._meta.model_name}'
return None return None
@swagger_serializer_method(serializer_or_field=serializers.DictField) @swagger_serializer_method(serializer_or_field=serializers.DictField)
def get_cable_peer(self, obj): def get_link_peer(self, obj):
""" """
Return the appropriate serializer for the cable termination model. Return the appropriate serializer for the link termination model.
""" """
if obj._cable_peer is not None: if obj._link_peer is not None:
serializer = get_serializer_for_model(obj._cable_peer, prefix='Nested') serializer = get_serializer_for_model(obj._link_peer, prefix='Nested')
context = {'request': self.context['request']} context = {'request': self.context['request']}
return serializer(obj._cable_peer, context=context).data return serializer(obj._link_peer, context=context).data
return None return None
@swagger_serializer_method(serializer_or_field=serializers.BooleanField) @swagger_serializer_method(serializer_or_field=serializers.BooleanField)
@ -529,7 +529,7 @@ class DeviceNAPALMSerializer(serializers.Serializer):
# Device components # Device components
# #
class ConsoleServerPortSerializer(PrimaryModelSerializer, CableTerminationSerializer, ConnectedEndpointSerializer): class ConsoleServerPortSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverport-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverport-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
type = ChoiceField( type = ChoiceField(
@ -548,12 +548,12 @@ class ConsoleServerPortSerializer(PrimaryModelSerializer, CableTerminationSerial
model = ConsoleServerPort model = ConsoleServerPort
fields = [ fields = [
'id', 'url', 'display', 'device', 'name', 'label', 'type', 'speed', 'description', 'mark_connected', 'id', 'url', 'display', 'device', 'name', 'label', 'type', 'speed', 'description', 'mark_connected',
'cable', 'cable_peer', 'cable_peer_type', 'connected_endpoint', 'connected_endpoint_type', 'cable', 'link_peer', 'link_peer_type', 'connected_endpoint', 'connected_endpoint_type',
'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied', 'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
] ]
class ConsolePortSerializer(PrimaryModelSerializer, CableTerminationSerializer, ConnectedEndpointSerializer): class ConsolePortSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleport-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleport-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
type = ChoiceField( type = ChoiceField(
@ -572,12 +572,12 @@ class ConsolePortSerializer(PrimaryModelSerializer, CableTerminationSerializer,
model = ConsolePort model = ConsolePort
fields = [ fields = [
'id', 'url', 'display', 'device', 'name', 'label', 'type', 'speed', 'description', 'mark_connected', 'id', 'url', 'display', 'device', 'name', 'label', 'type', 'speed', 'description', 'mark_connected',
'cable', 'cable_peer', 'cable_peer_type', 'connected_endpoint', 'connected_endpoint_type', 'cable', 'link_peer', 'link_peer_type', 'connected_endpoint', 'connected_endpoint_type',
'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied', 'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
] ]
class PowerOutletSerializer(PrimaryModelSerializer, CableTerminationSerializer, ConnectedEndpointSerializer): class PowerOutletSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:poweroutlet-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:poweroutlet-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
type = ChoiceField( type = ChoiceField(
@ -601,12 +601,12 @@ class PowerOutletSerializer(PrimaryModelSerializer, CableTerminationSerializer,
model = PowerOutlet model = PowerOutlet
fields = [ fields = [
'id', 'url', 'display', 'device', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description', 'id', 'url', 'display', 'device', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description',
'mark_connected', 'cable', 'cable_peer', 'cable_peer_type', 'connected_endpoint', 'connected_endpoint_type', 'mark_connected', 'cable', 'link_peer', 'link_peer_type', 'connected_endpoint', 'connected_endpoint_type',
'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied', 'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
] ]
class PowerPortSerializer(PrimaryModelSerializer, CableTerminationSerializer, ConnectedEndpointSerializer): class PowerPortSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerport-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerport-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
type = ChoiceField( type = ChoiceField(
@ -620,12 +620,12 @@ class PowerPortSerializer(PrimaryModelSerializer, CableTerminationSerializer, Co
model = PowerPort model = PowerPort
fields = [ fields = [
'id', 'url', 'display', 'device', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description', 'id', 'url', 'display', 'device', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description',
'mark_connected', 'cable', 'cable_peer', 'cable_peer_type', 'connected_endpoint', 'connected_endpoint_type', 'mark_connected', 'cable', 'link_peer', 'link_peer_type', 'connected_endpoint', 'connected_endpoint_type',
'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied', 'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
] ]
class InterfaceSerializer(PrimaryModelSerializer, CableTerminationSerializer, ConnectedEndpointSerializer): class InterfaceSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
type = ChoiceField(choices=InterfaceTypeChoices) type = ChoiceField(choices=InterfaceTypeChoices)
@ -649,7 +649,7 @@ class InterfaceSerializer(PrimaryModelSerializer, CableTerminationSerializer, Co
fields = [ fields = [
'id', 'url', 'display', 'device', 'name', 'label', 'type', 'enabled', 'parent', 'lag', 'mtu', 'mac_address', 'id', 'url', 'display', 'device', 'name', 'label', 'type', 'enabled', 'parent', 'lag', 'mtu', 'mac_address',
'wwn', 'mgmt_only', 'description', 'mode', 'rf_channel', 'rf_channel_width', 'untagged_vlan', 'wwn', 'mgmt_only', 'description', 'mode', 'rf_channel', 'rf_channel_width', 'untagged_vlan',
'tagged_vlans', 'mark_connected', 'cable', 'cable_peer', 'cable_peer_type', 'connected_endpoint', 'tagged_vlans', 'mark_connected', 'cable', 'link_peer', 'link_peer_type', 'connected_endpoint',
'connected_endpoint_type', 'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'connected_endpoint_type', 'connected_endpoint_reachable', 'tags', 'custom_fields', 'created',
'last_updated', 'count_ipaddresses', '_occupied', 'last_updated', 'count_ipaddresses', '_occupied',
] ]
@ -668,7 +668,7 @@ class InterfaceSerializer(PrimaryModelSerializer, CableTerminationSerializer, Co
return super().validate(data) return super().validate(data)
class RearPortSerializer(PrimaryModelSerializer, CableTerminationSerializer): class RearPortSerializer(PrimaryModelSerializer, LinkTerminationSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearport-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearport-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
type = ChoiceField(choices=PortTypeChoices) type = ChoiceField(choices=PortTypeChoices)
@ -678,7 +678,7 @@ class RearPortSerializer(PrimaryModelSerializer, CableTerminationSerializer):
model = RearPort model = RearPort
fields = [ fields = [
'id', 'url', 'display', 'device', 'name', 'label', 'type', 'color', 'positions', 'description', 'id', 'url', 'display', 'device', 'name', 'label', 'type', 'color', 'positions', 'description',
'mark_connected', 'cable', 'cable_peer', 'cable_peer_type', 'tags', 'custom_fields', 'created', 'mark_connected', 'cable', 'link_peer', 'link_peer_type', 'tags', 'custom_fields', 'created',
'last_updated', '_occupied', 'last_updated', '_occupied',
] ]
@ -694,7 +694,7 @@ class FrontPortRearPortSerializer(WritableNestedSerializer):
fields = ['id', 'url', 'display', 'name', 'label'] fields = ['id', 'url', 'display', 'name', 'label']
class FrontPortSerializer(PrimaryModelSerializer, CableTerminationSerializer): class FrontPortSerializer(PrimaryModelSerializer, LinkTerminationSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:frontport-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:frontport-detail')
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
type = ChoiceField(choices=PortTypeChoices) type = ChoiceField(choices=PortTypeChoices)
@ -705,7 +705,7 @@ class FrontPortSerializer(PrimaryModelSerializer, CableTerminationSerializer):
model = FrontPort model = FrontPort
fields = [ fields = [
'id', 'url', 'display', 'device', 'name', 'label', 'type', 'color', 'rear_port', 'rear_port_position', 'id', 'url', 'display', 'device', 'name', 'label', 'type', 'color', 'rear_port', 'rear_port_position',
'description', 'mark_connected', 'cable', 'cable_peer', 'cable_peer_type', 'tags', 'custom_fields', 'description', 'mark_connected', 'cable', 'link_peer', 'link_peer_type', 'tags', 'custom_fields',
'created', 'last_updated', '_occupied', 'created', 'last_updated', '_occupied',
] ]
@ -881,7 +881,7 @@ class PowerPanelSerializer(PrimaryModelSerializer):
fields = ['id', 'url', 'display', 'site', 'location', 'name', 'tags', 'custom_fields', 'powerfeed_count'] fields = ['id', 'url', 'display', 'site', 'location', 'name', 'tags', 'custom_fields', 'powerfeed_count']
class PowerFeedSerializer(PrimaryModelSerializer, CableTerminationSerializer, ConnectedEndpointSerializer): class PowerFeedSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerfeed-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerfeed-detail')
power_panel = NestedPowerPanelSerializer() power_panel = NestedPowerPanelSerializer()
rack = NestedRackSerializer( rack = NestedRackSerializer(
@ -911,7 +911,7 @@ class PowerFeedSerializer(PrimaryModelSerializer, CableTerminationSerializer, Co
model = PowerFeed model = PowerFeed
fields = [ fields = [
'id', 'url', 'display', 'power_panel', 'rack', 'name', 'status', 'type', 'supply', 'phase', 'voltage', 'id', 'url', 'display', 'power_panel', 'rack', 'name', 'status', 'type', 'supply', 'phase', 'voltage',
'amperage', 'max_utilization', 'comments', 'mark_connected', 'cable', 'cable_peer', 'cable_peer_type', 'amperage', 'max_utilization', 'comments', 'mark_connected', 'cable', 'link_peer', 'link_peer_type',
'connected_endpoint', 'connected_endpoint_type', 'connected_endpoint_reachable', 'tags', 'custom_fields', 'connected_endpoint', 'connected_endpoint_type', 'connected_endpoint_reachable', 'tags', 'custom_fields',
'created', 'last_updated', '_occupied', 'created', 'last_updated', '_occupied',
] ]

View File

@ -513,7 +513,7 @@ class DeviceViewSet(ConfigContextQuerySetMixin, CustomFieldModelViewSet):
# #
class ConsolePortViewSet(PathEndpointMixin, ModelViewSet): class ConsolePortViewSet(PathEndpointMixin, ModelViewSet):
queryset = ConsolePort.objects.prefetch_related('device', '_path__destination', 'cable', '_cable_peer', 'tags') queryset = ConsolePort.objects.prefetch_related('device', '_path__destination', 'cable', '_link_peer', 'tags')
serializer_class = serializers.ConsolePortSerializer serializer_class = serializers.ConsolePortSerializer
filterset_class = filtersets.ConsolePortFilterSet filterset_class = filtersets.ConsolePortFilterSet
brief_prefetch_fields = ['device'] brief_prefetch_fields = ['device']
@ -521,7 +521,7 @@ class ConsolePortViewSet(PathEndpointMixin, ModelViewSet):
class ConsoleServerPortViewSet(PathEndpointMixin, ModelViewSet): class ConsoleServerPortViewSet(PathEndpointMixin, ModelViewSet):
queryset = ConsoleServerPort.objects.prefetch_related( queryset = ConsoleServerPort.objects.prefetch_related(
'device', '_path__destination', 'cable', '_cable_peer', 'tags' 'device', '_path__destination', 'cable', '_link_peer', 'tags'
) )
serializer_class = serializers.ConsoleServerPortSerializer serializer_class = serializers.ConsoleServerPortSerializer
filterset_class = filtersets.ConsoleServerPortFilterSet filterset_class = filtersets.ConsoleServerPortFilterSet
@ -529,14 +529,14 @@ class ConsoleServerPortViewSet(PathEndpointMixin, ModelViewSet):
class PowerPortViewSet(PathEndpointMixin, ModelViewSet): class PowerPortViewSet(PathEndpointMixin, ModelViewSet):
queryset = PowerPort.objects.prefetch_related('device', '_path__destination', 'cable', '_cable_peer', 'tags') queryset = PowerPort.objects.prefetch_related('device', '_path__destination', 'cable', '_link_peer', 'tags')
serializer_class = serializers.PowerPortSerializer serializer_class = serializers.PowerPortSerializer
filterset_class = filtersets.PowerPortFilterSet filterset_class = filtersets.PowerPortFilterSet
brief_prefetch_fields = ['device'] brief_prefetch_fields = ['device']
class PowerOutletViewSet(PathEndpointMixin, ModelViewSet): class PowerOutletViewSet(PathEndpointMixin, ModelViewSet):
queryset = PowerOutlet.objects.prefetch_related('device', '_path__destination', 'cable', '_cable_peer', 'tags') queryset = PowerOutlet.objects.prefetch_related('device', '_path__destination', 'cable', '_link_peer', 'tags')
serializer_class = serializers.PowerOutletSerializer serializer_class = serializers.PowerOutletSerializer
filterset_class = filtersets.PowerOutletFilterSet filterset_class = filtersets.PowerOutletFilterSet
brief_prefetch_fields = ['device'] brief_prefetch_fields = ['device']
@ -544,7 +544,7 @@ class PowerOutletViewSet(PathEndpointMixin, ModelViewSet):
class InterfaceViewSet(PathEndpointMixin, ModelViewSet): class InterfaceViewSet(PathEndpointMixin, ModelViewSet):
queryset = Interface.objects.prefetch_related( queryset = Interface.objects.prefetch_related(
'device', 'parent', 'lag', '_path__destination', 'cable', '_cable_peer', 'ip_addresses', 'tags' 'device', 'parent', 'lag', '_path__destination', 'cable', '_link_peer', 'ip_addresses', 'tags'
) )
serializer_class = serializers.InterfaceSerializer serializer_class = serializers.InterfaceSerializer
filterset_class = filtersets.InterfaceFilterSet filterset_class = filtersets.InterfaceFilterSet
@ -625,7 +625,7 @@ class PowerPanelViewSet(ModelViewSet):
class PowerFeedViewSet(PathEndpointMixin, CustomFieldModelViewSet): class PowerFeedViewSet(PathEndpointMixin, CustomFieldModelViewSet):
queryset = PowerFeed.objects.prefetch_related( queryset = PowerFeed.objects.prefetch_related(
'power_panel', 'rack', '_path__destination', 'cable', '_cable_peer', 'tags' 'power_panel', 'rack', '_path__destination', 'cable', '_link_peer', 'tags'
) )
serializer_class = serializers.PowerFeedSerializer serializer_class = serializers.PowerFeedSerializer
filterset_class = filtersets.PowerFeedFilterSet filterset_class = filtersets.PowerFeedFilterSet

View File

@ -0,0 +1,93 @@
# Generated by Django 3.2.8 on 2021-10-13 17:47
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('dcim', '0138_interface_wireless_link'),
]
operations = [
migrations.RenameField(
model_name='consoleport',
old_name='_cable_peer_id',
new_name='_link_peer_id',
),
migrations.RenameField(
model_name='consoleport',
old_name='_cable_peer_type',
new_name='_link_peer_type',
),
migrations.RenameField(
model_name='consoleserverport',
old_name='_cable_peer_id',
new_name='_link_peer_id',
),
migrations.RenameField(
model_name='consoleserverport',
old_name='_cable_peer_type',
new_name='_link_peer_type',
),
migrations.RenameField(
model_name='frontport',
old_name='_cable_peer_id',
new_name='_link_peer_id',
),
migrations.RenameField(
model_name='frontport',
old_name='_cable_peer_type',
new_name='_link_peer_type',
),
migrations.RenameField(
model_name='interface',
old_name='_cable_peer_id',
new_name='_link_peer_id',
),
migrations.RenameField(
model_name='interface',
old_name='_cable_peer_type',
new_name='_link_peer_type',
),
migrations.RenameField(
model_name='powerfeed',
old_name='_cable_peer_id',
new_name='_link_peer_id',
),
migrations.RenameField(
model_name='powerfeed',
old_name='_cable_peer_type',
new_name='_link_peer_type',
),
migrations.RenameField(
model_name='poweroutlet',
old_name='_cable_peer_id',
new_name='_link_peer_id',
),
migrations.RenameField(
model_name='poweroutlet',
old_name='_cable_peer_type',
new_name='_link_peer_type',
),
migrations.RenameField(
model_name='powerport',
old_name='_cable_peer_id',
new_name='_link_peer_id',
),
migrations.RenameField(
model_name='powerport',
old_name='_cable_peer_type',
new_name='_link_peer_type',
),
migrations.RenameField(
model_name='rearport',
old_name='_cable_peer_id',
new_name='_link_peer_id',
),
migrations.RenameField(
model_name='rearport',
old_name='_cable_peer_type',
new_name='_link_peer_type',
),
]

View File

@ -10,7 +10,7 @@ __all__ = (
'BaseInterface', 'BaseInterface',
'Cable', 'Cable',
'CablePath', 'CablePath',
'CableTermination', 'LinkTermination',
'ConsolePort', 'ConsolePort',
'ConsolePortTemplate', 'ConsolePortTemplate',
'ConsoleServerPort', 'ConsoleServerPort',

View File

@ -395,7 +395,7 @@ class CablePath(BigIDModel):
# Follow the link to its far-end termination # Follow the link to its far-end termination
path.append(object_to_path_node(node.link)) path.append(object_to_path_node(node.link))
peer_termination = node.get_cable_peer() peer_termination = node.get_link_peer()
# Follow a FrontPort to its corresponding RearPort # Follow a FrontPort to its corresponding RearPort
if isinstance(peer_termination, FrontPort): if isinstance(peer_termination, FrontPort):

View File

@ -22,7 +22,7 @@ from utilities.query_functions import CollateAsChar
__all__ = ( __all__ = (
'BaseInterface', 'BaseInterface',
'CableTermination', 'LinkTermination',
'ConsolePort', 'ConsolePort',
'ConsoleServerPort', 'ConsoleServerPort',
'DeviceBay', 'DeviceBay',
@ -87,14 +87,14 @@ class ComponentModel(PrimaryModel):
return self.device return self.device
class CableTermination(models.Model): class LinkTermination(models.Model):
""" """
An abstract model inherited by all models to which a Cable can terminate (certain device components, PowerFeed, and An abstract model inherited by all models to which a Cable, WirelessLink, or other such link can terminate. Examples
CircuitTermination instances). The `cable` field indicates the Cable instance which is terminated to this instance. include most device components, CircuitTerminations, and PowerFeeds. The `cable` and `wireless_link` fields
reference the attached Cable or WirelessLink instance, respectively.
`_cable_peer` is a GenericForeignKey used to cache the far-end CableTermination on the local instance; this is a `_link_peer` is a GenericForeignKey used to cache the far-end LinkTermination on the local instance; this is a
shortcut to referencing `cable.termination_b`, for example. `_cable_peer` is set or cleared by the receivers in shortcut to referencing `instance.link.termination_b`, for example.
dcim.signals when a Cable instance is created or deleted, respectively.
""" """
cable = models.ForeignKey( cable = models.ForeignKey(
to='dcim.Cable', to='dcim.Cable',
@ -103,20 +103,20 @@ class CableTermination(models.Model):
blank=True, blank=True,
null=True null=True
) )
_cable_peer_type = models.ForeignKey( _link_peer_type = models.ForeignKey(
to=ContentType, to=ContentType,
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
related_name='+', related_name='+',
blank=True, blank=True,
null=True null=True
) )
_cable_peer_id = models.PositiveIntegerField( _link_peer_id = models.PositiveIntegerField(
blank=True, blank=True,
null=True null=True
) )
_cable_peer = GenericForeignKey( _link_peer = GenericForeignKey(
ct_field='_cable_peer_type', ct_field='_link_peer_type',
fk_field='_cable_peer_id' fk_field='_link_peer_id'
) )
mark_connected = models.BooleanField( mark_connected = models.BooleanField(
default=False, default=False,
@ -146,8 +146,8 @@ class CableTermination(models.Model):
"mark_connected": "Cannot mark as connected with a cable attached." "mark_connected": "Cannot mark as connected with a cable attached."
}) })
def get_cable_peer(self): def get_link_peer(self):
return self._cable_peer return self._link_peer
@property @property
def _occupied(self): def _occupied(self):
@ -226,7 +226,7 @@ class PathEndpoint(models.Model):
# #
@extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks') @extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks')
class ConsolePort(ComponentModel, CableTermination, PathEndpoint): class ConsolePort(ComponentModel, LinkTermination, PathEndpoint):
""" """
A physical console port within a Device. ConsolePorts connect to ConsoleServerPorts. A physical console port within a Device. ConsolePorts connect to ConsoleServerPorts.
""" """
@ -258,7 +258,7 @@ class ConsolePort(ComponentModel, CableTermination, PathEndpoint):
# #
@extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks') @extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks')
class ConsoleServerPort(ComponentModel, CableTermination, PathEndpoint): class ConsoleServerPort(ComponentModel, LinkTermination, PathEndpoint):
""" """
A physical port within a Device (typically a designated console server) which provides access to ConsolePorts. A physical port within a Device (typically a designated console server) which provides access to ConsolePorts.
""" """
@ -290,7 +290,7 @@ class ConsoleServerPort(ComponentModel, CableTermination, PathEndpoint):
# #
@extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks') @extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks')
class PowerPort(ComponentModel, CableTermination, PathEndpoint): class PowerPort(ComponentModel, LinkTermination, PathEndpoint):
""" """
A physical power supply (intake) port within a Device. PowerPorts connect to PowerOutlets. A physical power supply (intake) port within a Device. PowerPorts connect to PowerOutlets.
""" """
@ -340,8 +340,8 @@ class PowerPort(ComponentModel, CableTermination, PathEndpoint):
poweroutlet_ct = ContentType.objects.get_for_model(PowerOutlet) poweroutlet_ct = ContentType.objects.get_for_model(PowerOutlet)
outlet_ids = PowerOutlet.objects.filter(power_port=self).values_list('pk', flat=True) outlet_ids = PowerOutlet.objects.filter(power_port=self).values_list('pk', flat=True)
utilization = PowerPort.objects.filter( utilization = PowerPort.objects.filter(
_cable_peer_type=poweroutlet_ct, _link_peer_type=poweroutlet_ct,
_cable_peer_id__in=outlet_ids _link_peer_id__in=outlet_ids
).aggregate( ).aggregate(
maximum_draw_total=Sum('maximum_draw'), maximum_draw_total=Sum('maximum_draw'),
allocated_draw_total=Sum('allocated_draw'), allocated_draw_total=Sum('allocated_draw'),
@ -354,12 +354,12 @@ class PowerPort(ComponentModel, CableTermination, PathEndpoint):
} }
# Calculate per-leg aggregates for three-phase feeds # Calculate per-leg aggregates for three-phase feeds
if getattr(self._cable_peer, 'phase', None) == PowerFeedPhaseChoices.PHASE_3PHASE: if getattr(self._link_peer, 'phase', None) == PowerFeedPhaseChoices.PHASE_3PHASE:
for leg, leg_name in PowerOutletFeedLegChoices: for leg, leg_name in PowerOutletFeedLegChoices:
outlet_ids = PowerOutlet.objects.filter(power_port=self, feed_leg=leg).values_list('pk', flat=True) outlet_ids = PowerOutlet.objects.filter(power_port=self, feed_leg=leg).values_list('pk', flat=True)
utilization = PowerPort.objects.filter( utilization = PowerPort.objects.filter(
_cable_peer_type=poweroutlet_ct, _link_peer_type=poweroutlet_ct,
_cable_peer_id__in=outlet_ids _link_peer_id__in=outlet_ids
).aggregate( ).aggregate(
maximum_draw_total=Sum('maximum_draw'), maximum_draw_total=Sum('maximum_draw'),
allocated_draw_total=Sum('allocated_draw'), allocated_draw_total=Sum('allocated_draw'),
@ -387,7 +387,7 @@ class PowerPort(ComponentModel, CableTermination, PathEndpoint):
# #
@extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks') @extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks')
class PowerOutlet(ComponentModel, CableTermination, PathEndpoint): class PowerOutlet(ComponentModel, LinkTermination, PathEndpoint):
""" """
A physical power outlet (output) within a Device which provides power to a PowerPort. A physical power outlet (output) within a Device which provides power to a PowerPort.
""" """
@ -482,7 +482,7 @@ class BaseInterface(models.Model):
@extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks') @extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks')
class Interface(ComponentModel, BaseInterface, CableTermination, PathEndpoint): class Interface(ComponentModel, BaseInterface, LinkTermination, PathEndpoint):
""" """
A network interface within a Device. A physical Interface can connect to exactly one other Interface. A network interface within a Device. A physical Interface can connect to exactly one other Interface.
""" """
@ -674,7 +674,7 @@ class Interface(ComponentModel, BaseInterface, CableTermination, PathEndpoint):
# #
@extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks') @extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks')
class FrontPort(ComponentModel, CableTermination): class FrontPort(ComponentModel, LinkTermination):
""" """
A pass-through port on the front of a Device. A pass-through port on the front of a Device.
""" """
@ -728,7 +728,7 @@ class FrontPort(ComponentModel, CableTermination):
@extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks') @extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks')
class RearPort(ComponentModel, CableTermination): class RearPort(ComponentModel, LinkTermination):
""" """
A pass-through port on the rear of a Device. A pass-through port on the rear of a Device.
""" """

View File

@ -10,7 +10,7 @@ from extras.utils import extras_features
from netbox.models import PrimaryModel from netbox.models import PrimaryModel
from utilities.querysets import RestrictedQuerySet from utilities.querysets import RestrictedQuerySet
from utilities.validators import ExclusionValidator from utilities.validators import ExclusionValidator
from .device_components import CableTermination, PathEndpoint from .device_components import LinkTermination, PathEndpoint
__all__ = ( __all__ = (
'PowerFeed', 'PowerFeed',
@ -67,7 +67,7 @@ class PowerPanel(PrimaryModel):
@extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks') @extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks')
class PowerFeed(PrimaryModel, PathEndpoint, CableTermination): class PowerFeed(PrimaryModel, PathEndpoint, LinkTermination):
""" """
An electrical circuit delivered from a PowerPanel. An electrical circuit delivered from a PowerPanel.
""" """

View File

@ -422,13 +422,13 @@ class Rack(PrimaryModel):
return 0 return 0
pf_powerports = PowerPort.objects.filter( pf_powerports = PowerPort.objects.filter(
_cable_peer_type=ContentType.objects.get_for_model(PowerFeed), _link_peer_type=ContentType.objects.get_for_model(PowerFeed),
_cable_peer_id__in=powerfeeds.values_list('id', flat=True) _link_peer_id__in=powerfeeds.values_list('id', flat=True)
) )
poweroutlets = PowerOutlet.objects.filter(power_port_id__in=pf_powerports) poweroutlets = PowerOutlet.objects.filter(power_port_id__in=pf_powerports)
allocated_draw_total = PowerPort.objects.filter( allocated_draw_total = PowerPort.objects.filter(
_cable_peer_type=ContentType.objects.get_for_model(PowerOutlet), _link_peer_type=ContentType.objects.get_for_model(PowerOutlet),
_cable_peer_id__in=poweroutlets.values_list('id', flat=True) _link_peer_id__in=poweroutlets.values_list('id', flat=True)
).aggregate(Sum('allocated_draw'))['allocated_draw__sum'] or 0 ).aggregate(Sum('allocated_draw'))['allocated_draw__sum'] or 0
return int(allocated_draw_total / available_power_total * 100) return int(allocated_draw_total / available_power_total * 100)

View File

@ -83,12 +83,12 @@ def update_connected_endpoints(instance, created, raw=False, **kwargs):
if instance.termination_a.cable != instance: if instance.termination_a.cable != instance:
logger.debug(f"Updating termination A for cable {instance}") logger.debug(f"Updating termination A for cable {instance}")
instance.termination_a.cable = instance instance.termination_a.cable = instance
instance.termination_a._cable_peer = instance.termination_b instance.termination_a._link_peer = instance.termination_b
instance.termination_a.save() instance.termination_a.save()
if instance.termination_b.cable != instance: if instance.termination_b.cable != instance:
logger.debug(f"Updating termination B for cable {instance}") logger.debug(f"Updating termination B for cable {instance}")
instance.termination_b.cable = instance instance.termination_b.cable = instance
instance.termination_b._cable_peer = instance.termination_a instance.termination_b._link_peer = instance.termination_a
instance.termination_b.save() instance.termination_b.save()
# Create/update cable paths # Create/update cable paths
@ -119,11 +119,11 @@ def nullify_connected_endpoints(instance, **kwargs):
if instance.termination_a is not None: if instance.termination_a is not None:
logger.debug(f"Nullifying termination A for cable {instance}") logger.debug(f"Nullifying termination A for cable {instance}")
model = instance.termination_a._meta.model model = instance.termination_a._meta.model
model.objects.filter(pk=instance.termination_a.pk).update(_cable_peer_type=None, _cable_peer_id=None) model.objects.filter(pk=instance.termination_a.pk).update(_link_peer_type=None, _link_peer_id=None)
if instance.termination_b is not None: if instance.termination_b is not None:
logger.debug(f"Nullifying termination B for cable {instance}") logger.debug(f"Nullifying termination B for cable {instance}")
model = instance.termination_b._meta.model model = instance.termination_b._meta.model
model.objects.filter(pk=instance.termination_b.pk).update(_cable_peer_type=None, _cable_peer_id=None) model.objects.filter(pk=instance.termination_b.pk).update(_link_peer_type=None, _link_peer_id=None)
# Delete and retrace any dependent cable paths # Delete and retrace any dependent cable paths
for cablepath in CablePath.objects.filter(path__contains=instance): for cablepath in CablePath.objects.filter(path__contains=instance):

View File

@ -12,7 +12,7 @@ from utilities.tables import (
MarkdownColumn, TagColumn, TemplateColumn, ToggleColumn, MarkdownColumn, TagColumn, TemplateColumn, ToggleColumn,
) )
from .template_code import ( from .template_code import (
CABLETERMINATION, CONSOLEPORT_BUTTONS, CONSOLESERVERPORT_BUTTONS, DEVICE_LINK, DEVICEBAY_BUTTONS, DEVICEBAY_STATUS, LINKTERMINATION, CONSOLEPORT_BUTTONS, CONSOLESERVERPORT_BUTTONS, DEVICE_LINK, DEVICEBAY_BUTTONS, DEVICEBAY_STATUS,
FRONTPORT_BUTTONS, INTERFACE_BUTTONS, INTERFACE_IPADDRESSES, INTERFACE_TAGGED_VLANS, POWEROUTLET_BUTTONS, FRONTPORT_BUTTONS, INTERFACE_BUTTONS, INTERFACE_IPADDRESSES, INTERFACE_TAGGED_VLANS, POWEROUTLET_BUTTONS,
POWERPORT_BUTTONS, REARPORT_BUTTONS, POWERPORT_BUTTONS, REARPORT_BUTTONS,
) )
@ -258,11 +258,11 @@ class CableTerminationTable(BaseTable):
orderable=False, orderable=False,
verbose_name='Cable Color' verbose_name='Cable Color'
) )
cable_peer = TemplateColumn( link_peer = TemplateColumn(
accessor='_cable_peer', accessor='_link_peer',
template_code=CABLETERMINATION, template_code=LINKTERMINATION,
orderable=False, orderable=False,
verbose_name='Cable Peer' verbose_name='Link Peer'
) )
mark_connected = BooleanColumn() mark_connected = BooleanColumn()
@ -270,7 +270,7 @@ class CableTerminationTable(BaseTable):
class PathEndpointTable(CableTerminationTable): class PathEndpointTable(CableTerminationTable):
connection = TemplateColumn( connection = TemplateColumn(
accessor='_path.last_node', accessor='_path.last_node',
template_code=CABLETERMINATION, template_code=LINKTERMINATION,
verbose_name='Connection', verbose_name='Connection',
orderable=False orderable=False
) )
@ -291,7 +291,7 @@ class ConsolePortTable(DeviceComponentTable, PathEndpointTable):
model = ConsolePort model = ConsolePort
fields = ( fields = (
'pk', 'name', 'device', 'label', 'type', 'speed', 'description', 'mark_connected', 'cable', 'cable_color', 'pk', 'name', 'device', 'label', 'type', 'speed', 'description', 'mark_connected', 'cable', 'cable_color',
'cable_peer', 'connection', 'tags', 'link_peer', 'connection', 'tags',
) )
default_columns = ('pk', 'name', 'device', 'label', 'type', 'speed', 'description') default_columns = ('pk', 'name', 'device', 'label', 'type', 'speed', 'description')
@ -312,7 +312,7 @@ class DeviceConsolePortTable(ConsolePortTable):
model = ConsolePort model = ConsolePort
fields = ( fields = (
'pk', 'name', 'label', 'type', 'speed', 'description', 'mark_connected', 'cable', 'cable_color', 'pk', 'name', 'label', 'type', 'speed', 'description', 'mark_connected', 'cable', 'cable_color',
'cable_peer', 'connection', 'tags', 'actions' 'link_peer', 'connection', 'tags', 'actions'
) )
default_columns = ('pk', 'name', 'label', 'type', 'speed', 'description', 'cable', 'connection', 'actions') default_columns = ('pk', 'name', 'label', 'type', 'speed', 'description', 'cable', 'connection', 'actions')
row_attrs = { row_attrs = {
@ -335,7 +335,7 @@ class ConsoleServerPortTable(DeviceComponentTable, PathEndpointTable):
model = ConsoleServerPort model = ConsoleServerPort
fields = ( fields = (
'pk', 'name', 'device', 'label', 'type', 'speed', 'description', 'mark_connected', 'cable', 'cable_color', 'pk', 'name', 'device', 'label', 'type', 'speed', 'description', 'mark_connected', 'cable', 'cable_color',
'cable_peer', 'connection', 'tags', 'link_peer', 'connection', 'tags',
) )
default_columns = ('pk', 'name', 'device', 'label', 'type', 'speed', 'description') default_columns = ('pk', 'name', 'device', 'label', 'type', 'speed', 'description')
@ -357,7 +357,7 @@ class DeviceConsoleServerPortTable(ConsoleServerPortTable):
model = ConsoleServerPort model = ConsoleServerPort
fields = ( fields = (
'pk', 'name', 'label', 'type', 'speed', 'description', 'mark_connected', 'cable', 'cable_color', 'pk', 'name', 'label', 'type', 'speed', 'description', 'mark_connected', 'cable', 'cable_color',
'cable_peer', 'connection', 'tags', 'actions', 'link_peer', 'connection', 'tags', 'actions',
) )
default_columns = ('pk', 'name', 'label', 'type', 'speed', 'description', 'cable', 'connection', 'actions') default_columns = ('pk', 'name', 'label', 'type', 'speed', 'description', 'cable', 'connection', 'actions')
row_attrs = { row_attrs = {
@ -380,7 +380,7 @@ class PowerPortTable(DeviceComponentTable, PathEndpointTable):
model = PowerPort model = PowerPort
fields = ( fields = (
'pk', 'name', 'device', 'label', 'type', 'description', 'mark_connected', 'maximum_draw', 'allocated_draw', 'pk', 'name', 'device', 'label', 'type', 'description', 'mark_connected', 'maximum_draw', 'allocated_draw',
'cable', 'cable_color', 'cable_peer', 'connection', 'tags', 'cable', 'cable_color', 'link_peer', 'connection', 'tags',
) )
default_columns = ('pk', 'name', 'device', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description') default_columns = ('pk', 'name', 'device', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description')
@ -402,7 +402,7 @@ class DevicePowerPortTable(PowerPortTable):
model = PowerPort model = PowerPort
fields = ( fields = (
'pk', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description', 'mark_connected', 'cable', 'pk', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description', 'mark_connected', 'cable',
'cable_color', 'cable_peer', 'connection', 'tags', 'actions', 'cable_color', 'link_peer', 'connection', 'tags', 'actions',
) )
default_columns = ( default_columns = (
'pk', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description', 'cable', 'connection', 'pk', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description', 'cable', 'connection',
@ -431,7 +431,7 @@ class PowerOutletTable(DeviceComponentTable, PathEndpointTable):
model = PowerOutlet model = PowerOutlet
fields = ( fields = (
'pk', 'name', 'device', 'label', 'type', 'description', 'power_port', 'feed_leg', 'mark_connected', 'cable', 'pk', 'name', 'device', 'label', 'type', 'description', 'power_port', 'feed_leg', 'mark_connected', 'cable',
'cable_color', 'cable_peer', 'connection', 'tags', 'cable_color', 'link_peer', 'connection', 'tags',
) )
default_columns = ('pk', 'name', 'device', 'label', 'type', 'power_port', 'feed_leg', 'description') default_columns = ('pk', 'name', 'device', 'label', 'type', 'power_port', 'feed_leg', 'description')
@ -452,7 +452,7 @@ class DevicePowerOutletTable(PowerOutletTable):
model = PowerOutlet model = PowerOutlet
fields = ( fields = (
'pk', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description', 'mark_connected', 'cable', 'pk', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description', 'mark_connected', 'cable',
'cable_color', 'cable_peer', 'connection', 'tags', 'actions', 'cable_color', 'link_peer', 'connection', 'tags', 'actions',
) )
default_columns = ( default_columns = (
'pk', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description', 'cable', 'connection', 'actions', 'pk', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description', 'cable', 'connection', 'actions',
@ -485,6 +485,9 @@ class InterfaceTable(DeviceComponentTable, BaseInterfaceTable, PathEndpointTable
} }
) )
mgmt_only = BooleanColumn() mgmt_only = BooleanColumn()
wireless_link = tables.Column(
linkify=True
)
tags = TagColumn( tags = TagColumn(
url_name='dcim:interface_list' url_name='dcim:interface_list'
) )
@ -493,8 +496,8 @@ class InterfaceTable(DeviceComponentTable, BaseInterfaceTable, PathEndpointTable
model = Interface model = Interface
fields = ( fields = (
'pk', 'name', 'device', 'label', 'enabled', 'type', 'mgmt_only', 'mtu', 'mode', 'mac_address', 'wwn', 'pk', 'name', 'device', 'label', 'enabled', 'type', 'mgmt_only', 'mtu', 'mode', 'mac_address', 'wwn',
'rf_channel', 'rf_channel_width', 'description', 'mark_connected', 'cable', 'cable_color', 'cable_peer', 'rf_channel', 'rf_channel_width', 'description', 'mark_connected', 'cable', 'cable_color', 'wireless_link',
'connection', 'tags', 'ip_addresses', 'untagged_vlan', 'tagged_vlans', 'link_peer', 'connection', 'tags', 'ip_addresses', 'untagged_vlan', 'tagged_vlans',
) )
default_columns = ('pk', 'name', 'device', 'label', 'enabled', 'type', 'description') default_columns = ('pk', 'name', 'device', 'label', 'enabled', 'type', 'description')
@ -525,8 +528,8 @@ class DeviceInterfaceTable(InterfaceTable):
model = Interface model = Interface
fields = ( fields = (
'pk', 'name', 'label', 'enabled', 'type', 'parent', 'lag', 'mgmt_only', 'mtu', 'mode', 'mac_address', 'wwn', 'pk', 'name', 'label', 'enabled', 'type', 'parent', 'lag', 'mgmt_only', 'mtu', 'mode', 'mac_address', 'wwn',
'description', 'mark_connected', 'cable', 'cable_color', 'cable_peer', 'connection', 'tags', 'ip_addresses', 'description', 'mark_connected', 'cable', 'cable_color', 'wireless_link', 'link_peer', 'connection', 'tags',
'untagged_vlan', 'tagged_vlans', 'actions', 'ip_addresses', 'untagged_vlan', 'tagged_vlans', 'actions',
) )
order_by = ('name',) order_by = ('name',)
default_columns = ( default_columns = (
@ -562,7 +565,7 @@ class FrontPortTable(DeviceComponentTable, CableTerminationTable):
model = FrontPort model = FrontPort
fields = ( fields = (
'pk', 'name', 'device', 'label', 'type', 'color', 'rear_port', 'rear_port_position', 'description', 'pk', 'name', 'device', 'label', 'type', 'color', 'rear_port', 'rear_port_position', 'description',
'mark_connected', 'cable', 'cable_color', 'cable_peer', 'tags', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'tags',
) )
default_columns = ( default_columns = (
'pk', 'name', 'device', 'label', 'type', 'color', 'rear_port', 'rear_port_position', 'description', 'pk', 'name', 'device', 'label', 'type', 'color', 'rear_port', 'rear_port_position', 'description',
@ -586,10 +589,10 @@ class DeviceFrontPortTable(FrontPortTable):
model = FrontPort model = FrontPort
fields = ( fields = (
'pk', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description', 'mark_connected', 'cable', 'pk', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description', 'mark_connected', 'cable',
'cable_color', 'cable_peer', 'tags', 'actions', 'cable_color', 'link_peer', 'tags', 'actions',
) )
default_columns = ( default_columns = (
'pk', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description', 'cable', 'cable_peer', 'pk', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description', 'cable', 'link_peer',
'actions', 'actions',
) )
row_attrs = { row_attrs = {
@ -613,7 +616,7 @@ class RearPortTable(DeviceComponentTable, CableTerminationTable):
model = RearPort model = RearPort
fields = ( fields = (
'pk', 'name', 'device', 'label', 'type', 'color', 'positions', 'description', 'mark_connected', 'cable', 'pk', 'name', 'device', 'label', 'type', 'color', 'positions', 'description', 'mark_connected', 'cable',
'cable_color', 'cable_peer', 'tags', 'cable_color', 'link_peer', 'tags',
) )
default_columns = ('pk', 'name', 'device', 'label', 'type', 'color', 'description') default_columns = ('pk', 'name', 'device', 'label', 'type', 'color', 'description')
@ -635,10 +638,10 @@ class DeviceRearPortTable(RearPortTable):
model = RearPort model = RearPort
fields = ( fields = (
'pk', 'name', 'label', 'type', 'positions', 'description', 'mark_connected', 'cable', 'cable_color', 'pk', 'name', 'label', 'type', 'positions', 'description', 'mark_connected', 'cable', 'cable_color',
'cable_peer', 'tags', 'actions', 'link_peer', 'tags', 'actions',
) )
default_columns = ( default_columns = (
'pk', 'name', 'label', 'type', 'positions', 'description', 'cable', 'cable_peer', 'actions', 'pk', 'name', 'label', 'type', 'positions', 'description', 'cable', 'link_peer', 'actions',
) )
row_attrs = { row_attrs = {
'class': get_cabletermination_row_class 'class': get_cabletermination_row_class

View File

@ -71,10 +71,10 @@ class PowerFeedTable(CableTerminationTable):
model = PowerFeed model = PowerFeed
fields = ( fields = (
'pk', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase', 'pk', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase',
'max_utilization', 'mark_connected', 'cable', 'cable_color', 'cable_peer', 'connection', 'available_power', 'max_utilization', 'mark_connected', 'cable', 'cable_color', 'link_peer', 'connection', 'available_power',
'comments', 'tags', 'comments', 'tags',
) )
default_columns = ( default_columns = (
'pk', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase', 'cable', 'pk', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase', 'cable',
'cable_peer', 'link_peer',
) )

View File

@ -1,4 +1,4 @@
CABLETERMINATION = """ LINKTERMINATION = """
{% if value %} {% if value %}
{% if value.parent_object %} {% if value.parent_object %}
<a href="{{ value.parent_object.get_absolute_url }}">{{ value.parent_object }}</a> <a href="{{ value.parent_object.get_absolute_url }}">{{ value.parent_object }}</a>

View File

@ -494,9 +494,9 @@ class CableTestCase(TestCase):
interface1 = Interface.objects.get(pk=self.interface1.pk) interface1 = Interface.objects.get(pk=self.interface1.pk)
interface2 = Interface.objects.get(pk=self.interface2.pk) interface2 = Interface.objects.get(pk=self.interface2.pk)
self.assertEqual(self.cable.termination_a, interface1) self.assertEqual(self.cable.termination_a, interface1)
self.assertEqual(interface1._cable_peer, interface2) self.assertEqual(interface1._link_peer, interface2)
self.assertEqual(self.cable.termination_b, interface2) self.assertEqual(self.cable.termination_b, interface2)
self.assertEqual(interface2._cable_peer, interface1) self.assertEqual(interface2._link_peer, interface1)
def test_cable_deletion(self): def test_cable_deletion(self):
""" """
@ -508,10 +508,10 @@ class CableTestCase(TestCase):
self.assertNotEqual(str(self.cable), '#None') self.assertNotEqual(str(self.cable), '#None')
interface1 = Interface.objects.get(pk=self.interface1.pk) interface1 = Interface.objects.get(pk=self.interface1.pk)
self.assertIsNone(interface1.cable) self.assertIsNone(interface1.cable)
self.assertIsNone(interface1._cable_peer) self.assertIsNone(interface1._link_peer)
interface2 = Interface.objects.get(pk=self.interface2.pk) interface2 = Interface.objects.get(pk=self.interface2.pk)
self.assertIsNone(interface2.cable) self.assertIsNone(interface2.cable)
self.assertIsNone(interface2._cable_peer) self.assertIsNone(interface2._link_peer)
def test_cabletermination_deletion(self): def test_cabletermination_deletion(self):
""" """

View File

@ -45,7 +45,7 @@
<span class="text-muted">Marked as connected</span> <span class="text-muted">Marked as connected</span>
{% elif termination.cable %} {% elif termination.cable %}
<a class="d-block d-md-inline" href="{{ termination.cable.get_absolute_url }}">{{ termination.cable }}</a> <a class="d-block d-md-inline" href="{{ termination.cable.get_absolute_url }}">{{ termination.cable }}</a>
{% with peer=termination.get_cable_peer %} {% with peer=termination.get_link_peer %}
to to
{% if peer.device %} {% if peer.device %}
<a href="{{ peer.device.get_absolute_url }}">{{ peer.device }}</a><br/> <a href="{{ peer.device.get_absolute_url }}">{{ peer.device }}</a><br/>

View File

@ -98,6 +98,9 @@ class WirelessLink(PrimaryModel):
ordering = ['pk'] ordering = ['pk']
unique_together = ('interface_a', 'interface_b') unique_together = ('interface_a', 'interface_b')
def __str__(self):
return f'#{self.pk}'
def get_absolute_url(self): def get_absolute_url(self):
return reverse('wireless:wirelesslink', args=[self.pk]) return reverse('wireless:wirelesslink', args=[self.pk])

View File

@ -25,12 +25,12 @@ def update_connected_interfaces(instance, created, 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._link_peer = instance.interface_b
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._link_peer = instance.interface_a
instance.interface_b.save() instance.interface_b.save()
# Create/update cable paths # Create/update cable paths
@ -50,15 +50,15 @@ def nullify_connected_interfaces(instance, **kwargs):
logger.debug(f"Nullifying interface A for wireless link {instance}") logger.debug(f"Nullifying interface A for wireless link {instance}")
Interface.objects.filter(pk=instance.interface_a.pk).update( Interface.objects.filter(pk=instance.interface_a.pk).update(
wireless_link=None, wireless_link=None,
_cable_peer_type=None, _link_peer_type=None,
_cable_peer_id=None _link_peer_id=None
) )
if instance.interface_b is not None: if instance.interface_b is not None:
logger.debug(f"Nullifying interface B for wireless link {instance}") logger.debug(f"Nullifying interface B for wireless link {instance}")
Interface.objects.filter(pk=instance.interface_b.pk).update( Interface.objects.filter(pk=instance.interface_b.pk).update(
wireless_link=None, wireless_link=None,
_cable_peer_type=None, _link_peer_type=None,
_cable_peer_id=None _link_peer_id=None
) )
# Delete and retrace any dependent cable paths # Delete and retrace any dependent cable paths