feat: accept new port-mappings stanza format alongside legacy inline rear_port#4194
Open
marcinpsk wants to merge 4 commits into
Open
feat: accept new port-mappings stanza format alongside legacy inline rear_port#4194marcinpsk wants to merge 4 commits into
marcinpsk wants to merge 4 commits into
Conversation
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
Contributor
There was a problem hiding this comment.
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-mappingsto 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-mappingsreferences 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.
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.
- 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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.rear_portfrom front-portrequired; keep it as a valid property and usedependentRequiredso a strayrear_port_positionwithoutrear_portis still rejected.port-mappingsarray with the four fields NetBox emits, mirroring the PortTemplateMapping model.Would address #3999