Skip to content

feat: accept new port-mappings stanza format alongside legacy inline rear_port#4194

Open
marcinpsk wants to merge 4 commits into
netbox-community:masterfrom
marcinpsk:feat/port-mappings
Open

feat: accept new port-mappings stanza format alongside legacy inline rear_port#4194
marcinpsk wants to merge 4 commits into
netbox-community:masterfrom
marcinpsk:feat/port-mappings

Conversation

@marcinpsk

Copy link
Copy Markdown
Contributor

NetBox v4.5.0 replaced the legacy ForeignKey rear_port + rear_port_position on FrontPortTemplate with a true M2M PortTemplateMapping table, and v4.5.8 added a top-level port-mappings: section to the device-type YAML export (netbox-community/netbox#21859). The library should accept both formats so existing files remain valid while new submissions can use the M2M format.

  • schema/components.json: drop rear_port from front-port required; keep it as a valid property and use dependentRequired so a stray rear_port_position without rear_port is still rejected.
  • schema/devicetype.json, schema/moduletype.json: add a top-level port-mappings array with the four fields NetBox emits, mirroring the PortTemplateMapping model.
  • tests/definitions_test.py: leave the existing inline-format cross-reference and uniqueness loop untouched; add a self-contained follow-up block that validates the new stanza (front_port / rear_port name resolution, no-mix-per-port rule, cross-format (rear_port, rear_port_position) uniqueness, and stanza-internal (front_port, front_port_position) uniqueness). A comment documents that we deliberately do not require every front-port to be mapped, matching NetBox's own FrontPortTemplate.clean() which only enforces the upper bound positions >= mappings.count().

Would address #3999

NetBox v4.5.0 replaced the legacy ForeignKey rear_port + rear_port_position
on FrontPortTemplate with a true M2M PortTemplateMapping table, and v4.5.8
added a top-level `port-mappings:` section to the device-type YAML export
(netbox-community/netbox#21859). The library should accept both formats so
existing files remain valid while new submissions can use the M2M format.

- schema/components.json: drop `rear_port` from front-port `required`; keep
  it as a valid property and use `dependentRequired` so a stray
  `rear_port_position` without `rear_port` is still rejected.
- schema/devicetype.json, schema/moduletype.json: add a top-level
  `port-mappings` array with the four fields NetBox emits, mirroring the
  PortTemplateMapping model.
- tests/definitions_test.py: leave the existing inline-format
  cross-reference and uniqueness loop untouched; add a self-contained
  follow-up block that validates the new stanza (front_port / rear_port
  name resolution, no-mix-per-port rule, cross-format
  (rear_port, rear_port_position) uniqueness, and stanza-internal
  (front_port, front_port_position) uniqueness). A comment documents that
  we deliberately do not require every front-port to be mapped, matching
  NetBox's own FrontPortTemplate.clean() which only enforces the upper
  bound positions >= mappings.count().

Refs marcinpsk/Device-Type-Library-Import#78
Copilot AI review requested due to automatic review settings May 23, 2026 11:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds support for NetBox v4.5+ “port-mappings” by extending JSON schemas and test validation to allow the new top-level mapping stanza while keeping legacy inline mappings.

Changes:

  • Add port-mappings to device-type and module-type JSON schemas.
  • Relax inline front-port schema requirements to allow unmapped front-ports (v4.5+ behavior).
  • Add test validation to ensure port-mappings references valid ports and avoids duplicates / mixed formats.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
tests/definitions_test.py Adds validation for the new port-mappings stanza and enforces mapping constraints.
schema/moduletype.json Introduces port-mappings schema for module types.
schema/devicetype.json Introduces port-mappings schema for device types.
schema/components.json Makes inline front-port mapping optional and adds a dependency rule for rear_port_position.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread schema/components.json
Comment thread schema/devicetype.json Outdated
Comment thread tests/definitions_test.py Outdated
marcinpsk added 2 commits May 23, 2026 14:06
Without minLength, an empty string passed maxLength: 64 at the schema
layer, and the cross-reference checks in tests/definitions_test.py used
truthiness guards (`if fp_ref and ...`) — so an empty value would
silently bypass the front_port / rear_port resolution and uniqueness
checks. Apply minLength: 1 to front_port and rear_port in the
port-mappings stanza in both devicetype.json and moduletype.json.
The schema (port-mappings items: type=object, required=[front_port,
rear_port], minLength: 1 on both strings) is the source of truth for
each entry's shape. The test block was wrapping cross-reference and
uniqueness checks in `if fp_ref and ...` / `if rp_ref:` guards as a
silent fallback for malformed entries — duplicating what the schema
already enforces, and creating a drift risk if the schema ever changes.

Remove the silent guards and the non-dict skip; access required keys
directly via `pm["front_port"]` / `pm["rear_port"]`. Add a comment at
the top of the loop documenting that structural validity is the schema's
job, and this block only enforces the cross-document invariants the
schema can't express.
@marcinpsk marcinpsk requested a review from Copilot May 23, 2026 12:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

Comment thread tests/definitions_test.py Outdated
Comment thread tests/definitions_test.py Outdated
Comment thread tests/definitions_test.py Outdated
Comment thread schema/components.json
- Rename `front_port_positions` to `stanza_front_port_positions` to make
  the variable's scope explicit (it only tracks the new stanza format)
  and remove any risk of confusion with `rear_port_positions` defined
  above.
- Replace `dict[..., True]` membership tracking with a `set` — the dict
  was only ever used for `in` checks, never read.
- Drop the hard-coded "line 228" reference from the schema-validation
  comment; refer to the schema validation conceptually so it doesn't
  drift as the file changes.
@harryajc harryajc requested a review from danner26 June 10, 2026 06:51
@harryajc harryajc added the status: gathering feedback Further discussion is needed to determine this issue's scope and/or implementation label Jun 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: gathering feedback Further discussion is needed to determine this issue's scope and/or implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants