mirror of
https://github.com/netbox-community/netbox.git
synced 2026-01-08 04:56:56 -06:00
Simplify profile mappings; misc cleanup
This commit is contained in:
@@ -1,17 +1,24 @@
|
|||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
from dcim.choices import CableEndChoices
|
||||||
from dcim.models import CableTermination
|
from dcim.models import CableTermination
|
||||||
|
|
||||||
|
|
||||||
class BaseCableProfile:
|
class BaseCableProfile:
|
||||||
"""Base class for representing a cable profile."""
|
"""Base class for representing a cable profile."""
|
||||||
|
|
||||||
# Mappings of connectors to their available positions at either end of the cable. For example, a 12-strand MPO
|
# Mappings of connectors to the number of positions presented by each, at either end of the cable. For example, a
|
||||||
# fiber cable would have one connector at either end with six positions (six bidirectional fiber pairs).
|
# 12-strand MPO fiber cable would have one connector at either end with six positions (six bidirectional fiber
|
||||||
|
# pairs).
|
||||||
a_connectors = {}
|
a_connectors = {}
|
||||||
b_connectors = {}
|
b_connectors = {}
|
||||||
|
|
||||||
|
# Defined a mapping of A/B connector & position pairings. If not defined, all positions are presumed to be
|
||||||
|
# symmetrical (i.e. 1:1 on side A maps to 1:1 on side B). If defined, it must be constructed as a dictionary of
|
||||||
|
# two-item tuples, e.g. {(1, 1): (1, 1)}.
|
||||||
|
_mapping = None
|
||||||
|
|
||||||
def clean(self, cable):
|
def clean(self, cable):
|
||||||
# Enforce maximum terminations limits
|
# Enforce maximum terminations limits
|
||||||
a_terminations_count = len(cable.a_terminations)
|
a_terminations_count = len(cable.a_terminations)
|
||||||
@@ -44,6 +51,8 @@ class BaseCableProfile:
|
|||||||
Return the mapped far-end connector & position for a given cable end the local connector & position.
|
Return the mapped far-end connector & position for a given cable end the local connector & position.
|
||||||
"""
|
"""
|
||||||
# By default, assume all positions are symmetrical.
|
# By default, assume all positions are symmetrical.
|
||||||
|
if self._mapping:
|
||||||
|
return self._mapping.get((connector, position))
|
||||||
return connector, position
|
return connector, position
|
||||||
|
|
||||||
def get_peer_termination(self, termination, position):
|
def get_peer_termination(self, termination, position):
|
||||||
@@ -67,176 +76,182 @@ class BaseCableProfile:
|
|||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
|
|
||||||
|
# Profile naming:
|
||||||
|
# - Single: One connector per side, with one or more positions
|
||||||
|
# - Trunk: Two or more connectors per side, with one or more positions per connector
|
||||||
|
# - Breakout: One or more connectors on the A side which map to a greater number of B side connectors
|
||||||
|
# - Shuffle: A cable with nonlinear position mappings between sides
|
||||||
|
|
||||||
class Single1C1PCableProfile(BaseCableProfile):
|
class Single1C1PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1],
|
1: 1,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Single1C2PCableProfile(BaseCableProfile):
|
class Single1C2PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2],
|
1: 2,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Single1C4PCableProfile(BaseCableProfile):
|
class Single1C4PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2, 3, 4],
|
1: 4,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Single1C6PCableProfile(BaseCableProfile):
|
class Single1C6PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2, 3, 4, 5, 6],
|
1: 6,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Single1C8PCableProfile(BaseCableProfile):
|
class Single1C8PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2, 3, 4, 5, 6, 7, 8],
|
1: 8,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Single1C12PCableProfile(BaseCableProfile):
|
class Single1C12PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
|
1: 12,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Single1C16PCableProfile(BaseCableProfile):
|
class Single1C16PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 16],
|
1: 16,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Trunk2C1PCableProfile(BaseCableProfile):
|
class Trunk2C1PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1],
|
1: 1,
|
||||||
2: [1],
|
2: 1,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Trunk2C2PCableProfile(BaseCableProfile):
|
class Trunk2C2PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2],
|
1: 2,
|
||||||
2: [1, 2],
|
2: 2,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Trunk2C4PCableProfile(BaseCableProfile):
|
class Trunk2C4PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2, 3, 4],
|
1: 4,
|
||||||
2: [1, 2, 3, 4],
|
2: 4,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Trunk2C6PCableProfile(BaseCableProfile):
|
class Trunk2C6PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2, 3, 4, 5, 6],
|
1: 6,
|
||||||
2: [1, 2, 3, 4, 5, 6],
|
2: 6,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Trunk2C8PCableProfile(BaseCableProfile):
|
class Trunk2C8PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2, 3, 4, 5, 6, 7, 8],
|
1: 8,
|
||||||
2: [1, 2, 3, 4, 5, 6, 7, 8],
|
2: 8,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Trunk2C12PCableProfile(BaseCableProfile):
|
class Trunk2C12PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
|
1: 12,
|
||||||
2: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
|
2: 12,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Trunk4C1PCableProfile(BaseCableProfile):
|
class Trunk4C1PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1],
|
1: 1,
|
||||||
2: [1],
|
2: 1,
|
||||||
3: [1],
|
3: 1,
|
||||||
4: [1],
|
4: 1,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Trunk4C2PCableProfile(BaseCableProfile):
|
class Trunk4C2PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2],
|
1: 2,
|
||||||
2: [1, 2],
|
2: 2,
|
||||||
3: [1, 2],
|
3: 2,
|
||||||
4: [1, 2],
|
4: 2,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Trunk4C4PCableProfile(BaseCableProfile):
|
class Trunk4C4PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2, 3, 4],
|
1: 4,
|
||||||
2: [1, 2, 3, 4],
|
2: 4,
|
||||||
3: [1, 2, 3, 4],
|
3: 4,
|
||||||
4: [1, 2, 3, 4],
|
4: 4,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Trunk4C6PCableProfile(BaseCableProfile):
|
class Trunk4C6PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2, 3, 4, 5, 6],
|
1: 6,
|
||||||
2: [1, 2, 3, 4, 5, 6],
|
2: 6,
|
||||||
3: [1, 2, 3, 4, 5, 6],
|
3: 6,
|
||||||
4: [1, 2, 3, 4, 5, 6],
|
4: 6,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Trunk4C8PCableProfile(BaseCableProfile):
|
class Trunk4C8PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2, 3, 4, 5, 6, 7, 8],
|
1: 8,
|
||||||
2: [1, 2, 3, 4, 5, 6, 7, 8],
|
2: 8,
|
||||||
3: [1, 2, 3, 4, 5, 6, 7, 8],
|
3: 8,
|
||||||
4: [1, 2, 3, 4, 5, 6, 7, 8],
|
4: 8,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Trunk8C4PCableProfile(BaseCableProfile):
|
class Trunk8C4PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2, 3, 4],
|
1: 4,
|
||||||
2: [1, 2, 3, 4],
|
2: 4,
|
||||||
3: [1, 2, 3, 4],
|
3: 4,
|
||||||
4: [1, 2, 3, 4],
|
4: 4,
|
||||||
5: [1, 2, 3, 4],
|
5: 4,
|
||||||
6: [1, 2, 3, 4],
|
6: 4,
|
||||||
7: [1, 2, 3, 4],
|
7: 4,
|
||||||
8: [1, 2, 3, 4],
|
8: 4,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
|
|
||||||
|
|
||||||
class Breakout1C4Px4C1PCableProfile(BaseCableProfile):
|
class Breakout1C4Px4C1PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2, 3, 4],
|
1: 4,
|
||||||
}
|
}
|
||||||
b_connectors = {
|
b_connectors = {
|
||||||
1: [1],
|
1: 1,
|
||||||
2: [1],
|
2: 1,
|
||||||
3: [1],
|
3: 1,
|
||||||
4: [1],
|
4: 1,
|
||||||
}
|
}
|
||||||
_mapping = {
|
_mapping = {
|
||||||
(1, 1): (1, 1),
|
(1, 1): (1, 1),
|
||||||
@@ -248,14 +263,38 @@ class Breakout1C4Px4C1PCableProfile(BaseCableProfile):
|
|||||||
(4, 1): (1, 4),
|
(4, 1): (1, 4),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_mapped_position(self, side, connector, position):
|
|
||||||
return self._mapping.get((connector, position))
|
class Breakout1C6Px6C1PCableProfile(BaseCableProfile):
|
||||||
|
a_connectors = {
|
||||||
|
1: 6,
|
||||||
|
}
|
||||||
|
b_connectors = {
|
||||||
|
1: 1,
|
||||||
|
2: 1,
|
||||||
|
3: 1,
|
||||||
|
4: 1,
|
||||||
|
5: 1,
|
||||||
|
6: 1,
|
||||||
|
}
|
||||||
|
_mapping = {
|
||||||
|
(1, 1): (1, 1),
|
||||||
|
(1, 2): (2, 1),
|
||||||
|
(1, 3): (3, 1),
|
||||||
|
(1, 4): (4, 1),
|
||||||
|
(1, 5): (5, 1),
|
||||||
|
(1, 6): (6, 1),
|
||||||
|
(2, 1): (1, 2),
|
||||||
|
(3, 1): (1, 3),
|
||||||
|
(4, 1): (1, 4),
|
||||||
|
(5, 1): (1, 5),
|
||||||
|
(6, 1): (1, 6),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Shuffle2C4PCableProfile(BaseCableProfile):
|
class Shuffle2C4PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2, 3, 4],
|
1: 4,
|
||||||
2: [1, 2, 3, 4],
|
2: 4,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
_mapping = {
|
_mapping = {
|
||||||
@@ -269,16 +308,13 @@ class Shuffle2C4PCableProfile(BaseCableProfile):
|
|||||||
(2, 4): (2, 4),
|
(2, 4): (2, 4),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_mapped_position(self, side, connector, position):
|
|
||||||
return self._mapping.get((connector, position))
|
|
||||||
|
|
||||||
|
|
||||||
class Shuffle4C4PCableProfile(BaseCableProfile):
|
class Shuffle4C4PCableProfile(BaseCableProfile):
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2, 3, 4],
|
1: 4,
|
||||||
2: [1, 2, 3, 4],
|
2: 4,
|
||||||
3: [1, 2, 3, 4],
|
3: 4,
|
||||||
4: [1, 2, 3, 4],
|
4: 4,
|
||||||
}
|
}
|
||||||
b_connectors = a_connectors
|
b_connectors = a_connectors
|
||||||
_mapping = {
|
_mapping = {
|
||||||
@@ -300,27 +336,24 @@ class Shuffle4C4PCableProfile(BaseCableProfile):
|
|||||||
(4, 4): (4, 4),
|
(4, 4): (4, 4),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_mapped_position(self, side, connector, position):
|
|
||||||
return self._mapping.get((connector, position))
|
|
||||||
|
|
||||||
|
|
||||||
class ShuffleBreakout2x8CableProfile(BaseCableProfile):
|
class ShuffleBreakout2x8CableProfile(BaseCableProfile):
|
||||||
"""
|
"""
|
||||||
Temporary solution for mapping 2 front/rear ports to 8 discrete interfaces
|
Temporary solution for mapping 2 front/rear ports to 8 discrete interfaces
|
||||||
"""
|
"""
|
||||||
a_connectors = {
|
a_connectors = {
|
||||||
1: [1, 2, 3, 4],
|
1: 4,
|
||||||
2: [1, 2, 3, 4],
|
2: 4,
|
||||||
}
|
}
|
||||||
b_connectors = {
|
b_connectors = {
|
||||||
1: [1],
|
1: 1,
|
||||||
2: [1],
|
2: 1,
|
||||||
3: [1],
|
3: 1,
|
||||||
4: [1],
|
4: 1,
|
||||||
5: [1],
|
5: 1,
|
||||||
6: [1],
|
6: 1,
|
||||||
7: [1],
|
7: 1,
|
||||||
8: [1],
|
8: 1,
|
||||||
}
|
}
|
||||||
_a_mapping = {
|
_a_mapping = {
|
||||||
(1, 1): (1, 1),
|
(1, 1): (1, 1),
|
||||||
@@ -344,6 +377,6 @@ class ShuffleBreakout2x8CableProfile(BaseCableProfile):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def get_mapped_position(self, side, connector, position):
|
def get_mapped_position(self, side, connector, position):
|
||||||
if side.lower() == 'a':
|
if side.lower() == CableEndChoices.SIDE_A:
|
||||||
return self._a_mapping.get((connector, position))
|
return self._a_mapping.get((connector, position))
|
||||||
return self._b_mapping.get((connector, position))
|
return self._b_mapping.get((connector, position))
|
||||||
|
|||||||
@@ -1745,6 +1745,7 @@ class CableProfileChoices(ChoiceSet):
|
|||||||
TRUNK_8C4P = 'trunk-8c4p'
|
TRUNK_8C4P = 'trunk-8c4p'
|
||||||
# Breakouts
|
# Breakouts
|
||||||
BREAKOUT_1C4P_4C1P = 'breakout-1c4p-4c1p'
|
BREAKOUT_1C4P_4C1P = 'breakout-1c4p-4c1p'
|
||||||
|
BREAKOUT_1C6P_6C1P = 'breakout-1c6p-6c1p'
|
||||||
SHUFFLE_BREAKOUT_2X8 = 'shuffle-breakout-2x8'
|
SHUFFLE_BREAKOUT_2X8 = 'shuffle-breakout-2x8'
|
||||||
# Shuffles
|
# Shuffles
|
||||||
SHUFFLE_2C4P = 'shuffle-2c4p'
|
SHUFFLE_2C4P = 'shuffle-2c4p'
|
||||||
@@ -1781,13 +1782,14 @@ class CableProfileChoices(ChoiceSet):
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
_('Breakouts'),
|
_('Breakout'),
|
||||||
(
|
(
|
||||||
(BREAKOUT_1C4P_4C1P, _('Breakout (1C4P/4C1P)')),
|
(BREAKOUT_1C4P_4C1P, _('Breakout (1C4P/4C1P)')),
|
||||||
|
(BREAKOUT_1C6P_6C1P, _('Breakout (1C6P/6C1P)')),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
_('Shuffles'),
|
_('Shuffle'),
|
||||||
(
|
(
|
||||||
(SHUFFLE_2C4P, _('Shuffle (2C4P)')),
|
(SHUFFLE_2C4P, _('Shuffle (2C4P)')),
|
||||||
(SHUFFLE_4C4P, _('Shuffle (4C4P)')),
|
(SHUFFLE_4C4P, _('Shuffle (4C4P)')),
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ class Cable(PrimaryModel):
|
|||||||
CableProfileChoices.TRUNK_4C8P: cable_profiles.Trunk4C8PCableProfile,
|
CableProfileChoices.TRUNK_4C8P: cable_profiles.Trunk4C8PCableProfile,
|
||||||
CableProfileChoices.TRUNK_8C4P: cable_profiles.Trunk8C4PCableProfile,
|
CableProfileChoices.TRUNK_8C4P: cable_profiles.Trunk8C4PCableProfile,
|
||||||
CableProfileChoices.BREAKOUT_1C4P_4C1P: cable_profiles.Breakout1C4Px4C1PCableProfile,
|
CableProfileChoices.BREAKOUT_1C4P_4C1P: cable_profiles.Breakout1C4Px4C1PCableProfile,
|
||||||
|
CableProfileChoices.BREAKOUT_1C6P_6C1P: cable_profiles.Breakout1C6Px6C1PCableProfile,
|
||||||
CableProfileChoices.SHUFFLE_2C4P: cable_profiles.Shuffle2C4PCableProfile,
|
CableProfileChoices.SHUFFLE_2C4P: cable_profiles.Shuffle2C4PCableProfile,
|
||||||
CableProfileChoices.SHUFFLE_4C4P: cable_profiles.Shuffle4C4PCableProfile,
|
CableProfileChoices.SHUFFLE_4C4P: cable_profiles.Shuffle4C4PCableProfile,
|
||||||
CableProfileChoices.SHUFFLE_BREAKOUT_2X8: cable_profiles.ShuffleBreakout2x8CableProfile,
|
CableProfileChoices.SHUFFLE_BREAKOUT_2X8: cable_profiles.ShuffleBreakout2x8CableProfile,
|
||||||
@@ -363,7 +364,7 @@ class Cable(PrimaryModel):
|
|||||||
connector = positions = None
|
connector = positions = None
|
||||||
if self.profile:
|
if self.profile:
|
||||||
connector = i
|
connector = i
|
||||||
positions = self.profile_class().a_connectors[i]
|
positions = list(range(1, self.profile_class().a_connectors[i] + 1))
|
||||||
CableTermination(
|
CableTermination(
|
||||||
cable=self,
|
cable=self,
|
||||||
cable_end='A',
|
cable_end='A',
|
||||||
@@ -376,7 +377,7 @@ class Cable(PrimaryModel):
|
|||||||
connector = positions = None
|
connector = positions = None
|
||||||
if self.profile:
|
if self.profile:
|
||||||
connector = i
|
connector = i
|
||||||
positions = self.profile_class().b_connectors[i]
|
positions = list(range(1, self.profile_class().b_connectors[i] + 1))
|
||||||
CableTermination(
|
CableTermination(
|
||||||
cable=self,
|
cable=self,
|
||||||
cable_end='B',
|
cable_end='B',
|
||||||
|
|||||||
Reference in New Issue
Block a user