Cleanup; updated tests

This commit is contained in:
Jeremy Stretch
2025-12-12 10:26:01 -05:00
parent 15c32d44e7
commit 144f23444b
9 changed files with 56 additions and 38 deletions

View File

@@ -353,7 +353,7 @@ class CircuitTerminationFilterSet(NetBoxModelFilterSet, CabledObjectFilterSet):
model = CircuitTermination model = CircuitTermination
fields = ( fields = (
'id', 'termination_id', 'term_side', 'port_speed', 'upstream_speed', 'xconnect_id', 'description', 'id', 'termination_id', 'term_side', 'port_speed', 'upstream_speed', 'xconnect_id', 'description',
'mark_connected', 'pp_info', 'cable_end', 'mark_connected', 'pp_info', 'cable_end', 'cable_connector',
) )
def search(self, queryset, name, value): def search(self, queryset, name, value):

View File

@@ -433,7 +433,7 @@ class CircuitTestCase(TestCase, ChangeLoggedFilterSetTests):
class CircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTests): class CircuitTerminationTestCase(TestCase, ChangeLoggedFilterSetTests):
queryset = CircuitTermination.objects.all() queryset = CircuitTermination.objects.all()
filterset = CircuitTerminationFilterSet filterset = CircuitTerminationFilterSet
ignore_fields = ('cable',) ignore_fields = ('cable', 'cable_positions')
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):

View File

@@ -61,11 +61,11 @@ class CableTerminationSerializer(NetBoxModelSerializer):
model = CableTermination model = CableTermination
fields = [ fields = [
'id', 'url', 'display', 'cable', 'cable_end', 'termination_type', 'termination_id', 'id', 'url', 'display', 'cable', 'cable_end', 'termination_type', 'termination_id',
'termination', 'position', 'created', 'last_updated', 'termination', 'positions', 'created', 'last_updated',
] ]
read_only_fields = fields read_only_fields = fields
brief_fields = ( brief_fields = (
'id', 'url', 'display', 'cable', 'cable_end', 'position', 'termination_type', 'termination_id', 'id', 'url', 'display', 'cable', 'cable_end', 'positions', 'termination_type', 'termination_id',
) )

View File

@@ -1,29 +1,37 @@
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
from dcim.models import CableTermination from dcim.models import CableTermination
class BaseCableProfile: class BaseCableProfile:
def clean(self, cable): def clean(self, cable):
pass # Enforce maximum terminations limits
# # Enforce maximum connection limits a_terminations_count = len(cable.a_terminations)
# if self.a_max_connections and len(cable.a_terminations) > self.a_max_connections: b_terminations_count = len(cable.b_terminations)
# raise ValidationError({ max_a_terminations = len(self.a_connectors)
# 'a_terminations': _( max_b_terminations = len(self.b_connectors)
# 'Maximum A side connections for profile {profile}: {max}' if a_terminations_count > max_a_terminations:
# ).format( raise ValidationError({
# profile=cable.get_profile_display(), 'a_terminations': _(
# max=self.a_max_connections, 'A side of cable has {count} terminations but only {max} are permitted for profile {profile}'
# ) ).format(
# }) count=a_terminations_count,
# if self.b_max_connections and len(cable.b_terminations) > self.b_max_connections: profile=cable.get_profile_display(),
# raise ValidationError({ max=max_a_terminations,
# 'b_terminations': _( )
# 'Maximum B side connections for profile {profile}: {max}' })
# ).format( if b_terminations_count > max_b_terminations:
# profile=cable.get_profile_display(), raise ValidationError({
# max=self.b_max_connections, 'b_terminations': _(
# ) 'B side of cable has {count} terminations but only {max} are permitted for profile {profile}'
# }) ).format(
count=b_terminations_count,
profile=cable.get_profile_display(),
max=max_b_terminations,
)
})
def get_mapped_position(self, side, connector, position): def get_mapped_position(self, side, connector, position):
""" """
@@ -36,14 +44,11 @@ class BaseCableProfile:
""" """
Given a terminating object, return the peer terminating object (if any) on the opposite end of the cable. Given a terminating object, return the peer terminating object (if any) on the opposite end of the cable.
""" """
print(f'get_peer_termination({termination}, {position})')
print(f' Mapping {termination.cable_end} {termination.cable_connector}:{position}...')
connector, position = self.get_mapped_position( connector, position = self.get_mapped_position(
termination.cable_end, termination.cable_end,
termination.cable_connector, termination.cable_connector,
position position
) )
print(f' Mapped to {connector}:{position}')
try: try:
ct = CableTermination.objects.get( ct = CableTermination.objects.get(
cable=termination.cable, cable=termination.cable,
@@ -51,10 +56,8 @@ class BaseCableProfile:
connector=connector, connector=connector,
positions__contains=[position], positions__contains=[position],
) )
print(f' Found termination {ct.termination}')
return ct.termination, position return ct.termination, position
except CableTermination.DoesNotExist: except CableTermination.DoesNotExist:
print(f' Failed to resolve far end termination for {connector}:{position}')
return None, None return None, None

View File

@@ -1748,7 +1748,9 @@ class ConsolePortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSe
class Meta: class Meta:
model = ConsolePort model = ConsolePort
fields = ('id', 'name', 'label', 'speed', 'description', 'mark_connected', 'cable_end') fields = (
'id', 'name', 'label', 'speed', 'description', 'mark_connected', 'cable_end', 'cable_connector',
)
@register_filterset @register_filterset
@@ -1760,7 +1762,9 @@ class ConsoleServerPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFi
class Meta: class Meta:
model = ConsoleServerPort model = ConsoleServerPort
fields = ('id', 'name', 'label', 'speed', 'description', 'mark_connected', 'cable_end') fields = (
'id', 'name', 'label', 'speed', 'description', 'mark_connected', 'cable_end', 'cable_connector',
)
@register_filterset @register_filterset
@@ -1774,6 +1778,7 @@ class PowerPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet,
model = PowerPort model = PowerPort
fields = ( fields = (
'id', 'name', 'label', 'maximum_draw', 'allocated_draw', 'description', 'mark_connected', 'cable_end', 'id', 'name', 'label', 'maximum_draw', 'allocated_draw', 'description', 'mark_connected', 'cable_end',
'cable_connector',
) )
@@ -1800,6 +1805,7 @@ class PowerOutletFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSe
model = PowerOutlet model = PowerOutlet
fields = ( fields = (
'id', 'name', 'status', 'label', 'feed_leg', 'description', 'color', 'mark_connected', 'cable_end', 'id', 'name', 'status', 'label', 'feed_leg', 'description', 'color', 'mark_connected', 'cable_end',
'cable_connector',
) )
@@ -2109,7 +2115,7 @@ class InterfaceFilterSet(
fields = ( fields = (
'id', 'name', 'label', 'type', 'enabled', 'mtu', 'mgmt_only', 'poe_mode', 'poe_type', 'mode', 'rf_role', 'id', 'name', 'label', 'type', 'enabled', 'mtu', 'mgmt_only', 'poe_mode', 'poe_type', 'mode', 'rf_role',
'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'description', 'mark_connected', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'description', 'mark_connected',
'cable_id', 'cable_end', 'cable_id', 'cable_end', 'cable_connector',
) )
def filter_virtual_chassis_member_or_master(self, queryset, name, value): def filter_virtual_chassis_member_or_master(self, queryset, name, value):
@@ -2165,6 +2171,7 @@ class FrontPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet)
model = FrontPort model = FrontPort
fields = ( fields = (
'id', 'name', 'label', 'type', 'color', 'positions', 'description', 'mark_connected', 'cable_end', 'id', 'name', 'label', 'type', 'color', 'positions', 'description', 'mark_connected', 'cable_end',
'cable_connector',
) )
@@ -2185,6 +2192,7 @@ class RearPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet):
model = RearPort model = RearPort
fields = ( fields = (
'id', 'name', 'label', 'type', 'color', 'positions', 'description', 'mark_connected', 'cable_end', 'id', 'name', 'label', 'type', 'color', 'positions', 'description', 'mark_connected', 'cable_end',
'cable_connector',
) )
@@ -2659,7 +2667,7 @@ class PowerFeedFilterSet(PrimaryModelFilterSet, CabledObjectFilterSet, PathEndpo
model = PowerFeed model = PowerFeed
fields = ( fields = (
'id', 'name', 'status', 'type', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization', 'id', 'name', 'status', 'type', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization',
'available_power', 'mark_connected', 'cable_end', 'description', 'available_power', 'mark_connected', 'cable_end', 'cable_connector', 'description',
) )
def search(self, queryset, name, value): def search(self, queryset, name, value):

View File

@@ -532,7 +532,7 @@ class CableTermination(ChangeLoggedModel):
termination.cable = None termination.cable = None
termination.cable_end = None termination.cable_end = None
termination.cable_connector = None termination.cable_connector = None
termination.cable_position = None termination.cable_positions = None
termination.save() termination.save()
super().delete(*args, **kwargs) super().delete(*args, **kwargs)

View File

@@ -224,9 +224,9 @@ class CabledObjectModel(models.Model):
raise ValidationError({ raise ValidationError({
"cable_end": _("Cable end must not be set without a cable.") "cable_end": _("Cable end must not be set without a cable.")
}) })
if self.cable_position and not self.cable: if self.cable_positions and not self.cable:
raise ValidationError({ raise ValidationError({
"cable_position": _("Cable termination position must not be set without a cable.") "cable_positions": _("Cable termination positions must not be set without a cable.")
}) })
if self.mark_connected and self.cable: if self.mark_connected and self.cable:
raise ValidationError({ raise ValidationError({

View File

@@ -2620,7 +2620,7 @@ class CableTerminationTest(
APIViewTestCases.ListObjectsViewTestCase, APIViewTestCases.ListObjectsViewTestCase,
): ):
model = CableTermination model = CableTermination
brief_fields = ['cable', 'cable_end', 'display', 'id', 'position', 'termination_id', 'termination_type', 'url'] brief_fields = ['cable', 'cable_end', 'display', 'id', 'positions', 'termination_id', 'termination_type', 'url']
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):

View File

@@ -3332,6 +3332,7 @@ class ModuleTestCase(TestCase, ChangeLoggedFilterSetTests):
class ConsolePortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests): class ConsolePortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests):
queryset = ConsolePort.objects.all() queryset = ConsolePort.objects.all()
filterset = ConsolePortFilterSet filterset = ConsolePortFilterSet
ignore_fields = ('cable_positions',)
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):
@@ -3582,6 +3583,7 @@ class ConsolePortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedF
class ConsoleServerPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests): class ConsoleServerPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests):
queryset = ConsoleServerPort.objects.all() queryset = ConsoleServerPort.objects.all()
filterset = ConsoleServerPortFilterSet filterset = ConsoleServerPortFilterSet
ignore_fields = ('cable_positions',)
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):
@@ -3832,6 +3834,7 @@ class ConsoleServerPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeL
class PowerPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests): class PowerPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests):
queryset = PowerPort.objects.all() queryset = PowerPort.objects.all()
filterset = PowerPortFilterSet filterset = PowerPortFilterSet
ignore_fields = ('cable_positions',)
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):
@@ -4096,6 +4099,7 @@ class PowerPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil
class PowerOutletTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests): class PowerOutletTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests):
queryset = PowerOutlet.objects.all() queryset = PowerOutlet.objects.all()
filterset = PowerOutletFilterSet filterset = PowerOutletFilterSet
ignore_fields = ('cable_positions',)
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):
@@ -4380,7 +4384,7 @@ class PowerOutletTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedF
class InterfaceTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests): class InterfaceTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests):
queryset = Interface.objects.all() queryset = Interface.objects.all()
filterset = InterfaceFilterSet filterset = InterfaceFilterSet
ignore_fields = ('tagged_vlans', 'untagged_vlan', 'qinq_svlan', 'vdcs') ignore_fields = ('tagged_vlans', 'untagged_vlan', 'qinq_svlan', 'vdcs', 'cable_positions')
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):
@@ -5017,6 +5021,7 @@ class InterfaceTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil
class FrontPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests): class FrontPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests):
queryset = FrontPort.objects.all() queryset = FrontPort.objects.all()
filterset = FrontPortFilterSet filterset = FrontPortFilterSet
ignore_fields = ('cable_positions',)
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):
@@ -5321,6 +5326,7 @@ class FrontPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFil
class RearPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests): class RearPortTestCase(TestCase, DeviceComponentFilterSetTests, ChangeLoggedFilterSetTests):
queryset = RearPort.objects.all() queryset = RearPort.objects.all()
filterset = RearPortFilterSet filterset = RearPortFilterSet
ignore_fields = ('cable_positions',)
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):
@@ -6859,6 +6865,7 @@ class PowerPanelTestCase(TestCase, ChangeLoggedFilterSetTests):
class PowerFeedTestCase(TestCase, ChangeLoggedFilterSetTests): class PowerFeedTestCase(TestCase, ChangeLoggedFilterSetTests):
queryset = PowerFeed.objects.all() queryset = PowerFeed.objects.all()
filterset = PowerFeedFilterSet filterset = PowerFeedFilterSet
ignore_fields = ('cable_positions',)
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):