Port Topology¶
This page is the developer-facing companion to the user-facing DeviceType Setup recipes. It covers the position-stack contract that ties WDM channels to NetBox port mappings, the per-hardware port layouts the plugin understands, and the rules a new DeviceType must obey to participate in cable tracing.
Position-stack contract¶
The plugin uses one integer to bridge ITU and NetBox: grid_position.
WdmChannelPlan.grid_positionrecords the channel's index in the ITU grid (1-based).WdmChannel.grid_positionis copied from the plan at auto-population time and never drifts across the overlay.- Every
dcim.PortMappingthe plugin emits setsrear_port_position = channel.grid_position. NetBox'sdcim.CablePathpicks the right per-channel front port back out of a shared trunk by comparing this against the cable'spositionon the rear port side.
The single rule a DeviceType must obey is therefore:
Every PortTemplateMapping's
rear_port_positionmust equal thegrid_positionof the channel it carries.
PortTemplateMapping rows live on the DeviceType and are how NetBox
materialises PortMapping rows when a Device is created. Mismatched
positions break tracing silently because cables continue to terminate but
no longer pick up the right per-channel port on the far side.
EXP, 1310, and other pass-through ports¶
Real hardware exposes pass-through ports (EXP for upgrade chains, 1310 for gray-light injection) that share the same trunk fibres as the WDM-multiplexed channels. The plugin models them as ordinary FrontPortTemplate plus PortTemplateMapping rows on the DeviceType, but at positions after the channel positions on the same COM rear ports.
For an N-channel CWDM duplex MUX, RearPortTemplate positions is set to
N + 2 and the PortTemplateMappings stack like this:
rear_port_position |
Front port (mux side) | Front port (demux side) |
|---|---|---|
| 1 | CH1-MUX |
CH1-DEMUX |
| ... | ... | ... |
| N | CHN-MUX |
CHN-DEMUX |
| N + 1 | EXP-MUX |
EXP-DEMUX |
| N + 2 | 1310-MUX |
1310-DEMUX |
These pass-through ports are deliberately not part of any
WdmChannelPlan. They have no WdmChannel row, no PROTECT guard, and no
representation in the wavelength editor. The port-sync hash also excludes
them, so a cable plugged into EXP without an accompanying channel does
not raise drift.
The trace can still follow an EXP cable like any other, because the PortTemplateMapping puts the EXP front port behind the same COM rear port. This is what lets operators run an upgrade fibre into an existing MUX without modelling it in the WDM layer.
Hardware classes¶
The factories under netbox_wdm.testing.device_types are reference
implementations of every layout below. They use get_or_create, so they
are safe to run more than once.
Duplex terminal MUX¶
Two trunk fibres (COM-TX + COM-RX); per-channel client ports split
into a MUX (TX) leg and a DEMUX (RX) leg. The DEMUX leg is what makes
this a duplex profile and is what fills WdmChannelPlan.demux_front_port_template.
- RearPortTemplates:
COM-TX,COM-RX, both withpositions = N + extras. - FrontPortTemplates:
CH{n}-MUXandCH{n}-DEMUXper channel, plusEXP-MUX/DEMUXand1310-MUX/DEMUXif present. - PortTemplateMappings:
CH{n}-MUX -> COM-TX @ n,CH{n}-DEMUX -> COM-RX @ n, EXP and 1310 at trailing positions.
For DWDM hardware the per-channel front ports are usually named after
the ITU label (C21-MUX, C21-DEMUX, ...). The factory
create_dwdm_mux_dx_type follows that convention.
Single-fibre terminal MUX¶
One trunk fibre (COM) carrying both directions; per-channel client
ports are bidirectional CH{n} front ports. WdmChannelPlan.demux_front_port_template
is null on every plan row.
- RearPortTemplate:
COMwithpositions = N + extras. - FrontPortTemplates:
CH{n}per channel, plusEXPand1310. - PortTemplateMappings:
CH{n} -> COM @ n, EXP/1310 at trailing positions.
The plugin reflects this through WdmFiberTypeChoices.SINGLE_FIBER on
the profile. The wavelength editor hides its DEMUX column for these
profiles; the trace visualisation collapses TX and RX onto a single fibre.
2-degree ROADM¶
Four trunk fibres (LINE-EAST-TX/RX, LINE-WEST-TX/RX); a pool of
ADD/DROP front ports that the wavelength editor rebinds to channels at
runtime.
- RearPortTemplates:
LINE-{EAST,WEST}-{TX,RX}, each withpositions = full grid(44 for DWDM 100 GHz, 88 for DWDM 50 GHz). - FrontPortTemplates:
ADD-{nn}andDROP-{nn}per intended channel count. - PortTemplateMappings:
ADD-{nn} -> LINE-EAST-TX @ nn,DROP-{nn} -> LINE-EAST-RX @ nnby convention. The mappings only define the default binding; the wavelength editor rewrites the deriveddcim.PortMappingrows when an operator assigns ADDs and DROPs to a different channel.
A higher-degree ROADM follows the same shape -- one TX/RX RearPortTemplate per direction.
Inline amplifier (EDFA)¶
One LINE-IN front port, one LINE-OUT rear port, one PortTemplateMapping linking them. No per-channel ports.
_auto_populate_channels() skips amplifier nodes, so no
WdmChannelPlan rows are needed. This is why the WDM model can let an
amplifier participate in the cable plant trace without owning any
channel objects of its own.
Fibre patch panel¶
1:1 FrontPort to RearPort mappings, no profile.
The trace identifies a patch panel by the absence of a WdmLinePort on
the RearPort and the presence of a PortMapping out the front. This is
the same path-following logic used to enter and exit any pass-through
device.
Line ports¶
WdmLinePort is how the trace identifies trunk RearPorts. It is not
auto-created -- per-Device line ports are user-managed (see
WDM Nodes).
The pair (direction, role) is a uniqueness key per node. The trace uses
role to filter outbound vs inbound walks (TX/BIDI for forward, RX/BIDI
for backward) and uses direction together with the topological position
of the rear port to decide which TX is the "right" one to follow on
multi-degree nodes.
The full enum lists are in netbox_wdm/choices.py:
WdmLineDirectionChoices:common,east,west(extensible to N/S for future higher-degree ROADMs).WdmLineRoleChoices:tx,rx,bidi.
Validation rules¶
The plugin enforces these at save time:
WdmLinePort.rear_portmust belong to the same Device as theWdmLinePort.wdm_node.device.WdmLinePortcannot duplicate another row on the same node by eitherrear_portor(direction, role).WdmChannelcannot reuse agrid_positionon the same node.WdmChannelPlan.mux_front_port_templateanddemux_front_port_templatemust reference FrontPortTemplates on the profile's DeviceType.- A duplex profile rejects null
demux_front_port_template. A single-fibre profile rejects non-nulldemux_front_port_template.
These constraints are how the overlay stays internally consistent: a DeviceType the plugin accepts is one whose ports it can map back to channels deterministically.
Adding a new hardware class¶
To support a new hardware class:
- Decide whether it fits one of
terminal_mux,oadm,roadm,amplifier. If not, extendWdmNodeTypeChoicesfirst. - Decide whether channels are auto-populated. If not (as for amplifiers),
add the type to the early-return branch in
WdmNode._auto_populate_channels(). - Decide the trunk shape: how many RearPorts, what direction/role each carries, whether duplex or single-fibre.
- Build a factory in
netbox_wdm/testing/device_types.pythat creates the templates and mappings. Keep the position stack honest -- channel positions first, pass-through positions after. - If the new class introduces a different per-degree topology, extend the trace to recognise it. The current code is direction-agnostic for anything beyond 2-degree (it tries every TX line port until one reaches an unvisited node), so most new shapes work without code changes.
Where to look in code¶
| Concern | File |
|---|---|
| ITU grid tables | netbox_wdm/wdm_constants.py |
| Choice enums | netbox_wdm/choices.py |
| Profile, channel plan, node, line port, channel models | netbox_wdm/models.py |
| Auto-population | WdmNode._auto_populate_channels in netbox_wdm/models.py |
| DeviceType factories | netbox_wdm/testing/device_types.py |
| Device factories | netbox_wdm/testing/devices.py |