Skip to content

Many-to-many mappings for pass-through ports #20564

@jeremystretch

Description

@jeremystretch

NetBox version

v4.4.2

Feature type

New functionality

Proposed functionality

NetBox currently permits assigning multiple front ports to a single rear port. This FR proposes extending the data model to support the reverse as well (multiple rear ports to a single front port), enabling many-to-many assignment among front and rear ports. The current implementation, which employs a ForeignKey from FrontPort to RearPort and an Integerfield would be replaced by a bi-directional many-to-many assignment.

Once implemented, it will become possible to condense of expand the "stack" of positions in both directions across a pair of pass-through ports.

Use case

Extending the data model to support multi-port mappings in either direction would enable modeling complex pass-through paths. These are commonly seen e.g. in datacenter Clos fabrics which utilize crossover fiber modules to simplify spine-to-leaf connections. An example is show below:

Image

The resulting M2M table for the above topology would look like this:

FrontPort Position RearPort Position
1 1 1 1
1 2 1 2
1 3 2 1
1 4 2 2
2 1 1 3
2 2 1 4
2 3 2 3
2 4 2 4

Database changes

There are two relevant fields currently defined on the FrontPort model:

class FrontPort:
    rear_port = models.ForeignKey(
        to='dcim.RearPort',
        on_delete=models.CASCADE,
        related_name='frontports'
    )
    rear_port_position = models.PositiveSmallIntegerField(
        verbose_name=_('rear port position'),
        default=1,
        validators=[
            MinValueValidator(REARPORT_POSITIONS_MIN),
            MaxValueValidator(REARPORT_POSITIONS_MAX)
        ],
        help_text=_('Mapped position on corresponding rear port')
    )

These would be replaced by a ManyToManyField on the FrontPort model. This M2M assignment would utilize a custom "through" table which annotates the numeric position of each port:

class PortMapping:
    front_port = models.ForeignKey(
        to='dcim.FrontPort',
        on_delete=models.CASCADE,
    )
    front_port_position = models.PositiveSmallIntegerField(
        default=1,
    )
    rear_port = models.ForeignKey(
        to='dcim.RearPort',
        on_delete=models.CASCADE,
    )
    rear_port_position = models.PositiveSmallIntegerField(
        default=1,
    )

External dependencies

N/A

Metadata

Metadata

Assignees

No one assigned

    Labels

    complexity: highExpected to require a large amont of time and effort to implement relative to other tasksnetboxstatus: under reviewFurther discussion is needed to determine this issue's scope and/or implementationtype: featureIntroduction of new functionality to the application

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions