Skip to content

Conversation

@jsenecal
Copy link
Contributor

@jsenecal jsenecal commented Nov 20, 2025

Fixes: #17954

Overview

This PR implements dynamic parent resolution for cable CSV imports, enabling bulk import of cables connected to circuits, power panels, and devices. This is a revised approach following PR #17995, which was closed due to design concerns.

Key Difference from PR #17995:

Instead of adding separate fields for each parent type (side_x_circuit, side_x_power_panel), this implementation uses dynamic parent resolution by repurposing the existing side_x_device field to side_x_parent. The parent object (Circuit, Device, or PowerPanel) is determined based on the termination type specified.

Implementation Details

1. Dynamic Parent Field Resolution:

  • Renamed side_x_device to side_x_parent in CableImportForm
  • The parent field now dynamically resolves to the appropriate model based on side_x_type
  • Supports three parent types:
    • dcim.Device → Resolves using Device model (for interfaces, console ports, power ports, etc.)
    • circuits.Circuit → Resolves using Circuit model (for circuit terminations)
    • dcim.PowerPanel → Resolves using PowerPanel model (for power feeds)

2. Parent-Specific Lookup Logic:

  • Circuits: Uses cid (Circuit ID) as the lookup field
  • Devices: Uses name as the lookup field
  • Power Panels: Uses name as the lookup field
  • Each parent type uses its appropriate queryset and to_field_name

3. Enhanced Validation:

  • Validates that circuit terminations are not already connected to Provider Networks
  • Ensures proper parent object resolution based on termination type
  • Maintains backward compatibility with existing device-only imports

4. Comprehensive Test Coverage:

  • Added/Modified test cases to CableTestCase for new field names and supported variations
  • Added validation tests in CableImportFormTestCase for code that CableTestCase does not reach (all error paths)
  • Tests cover all three parent types (circuits, devices, power panels) and validation tests for edge cases and error conditions

Benefits

  • Single Field Design: Cleaner CSV format - one parent field per side instead of multiple conditional fields
  • Extensible: Easy to add support for additional parent types in the future
  • Backward Compatible: Existing device-based imports continue to work (just rename side_x_device to side_x_parent)
  • Comprehensive: Solves both circuit terminations AND power feeds as suggested in PR Fixes #17954 - Handle CircuitTerminations in Cable Bulk Import #17995

Usage Examples

Device to Device (Interface to Interface):

side_a_parent,side_a_type,side_a_name,side_b_parent,side_b_type,side_b_name,type,status
Device1,dcim.interface,eth0,Device2,dcim.interface,eth0,cat6,connected

Circuit Termination to Device Interface:

side_a_parent,side_a_type,side_a_name,side_b_parent,side_b_type,side_b_name,type,status
CID-123,circuits.circuittermination,A,Device1,dcim.interface,eth0,smf,connected

Power Feed to Power Port:

side_a_site,side_a_parent,side_a_type,side_a_name,side_b_site,side_b_parent,side_b_type,side_b_name,type,status
Site 1,Power Panel 1,dcim.powerfeed,Feed 1,Site 1,Device1,dcim.powerport,PSU1,power,connected

With Site Scoping (for non-unique device names):

side_a_site,side_a_parent,side_a_type,side_a_name,side_b_site,side_b_parent,side_b_type,side_b_name,type,status
Site 1,Device1,dcim.interface,eth0,Site 2,Device1,dcim.interface,eth0,cat6,connected

@jsenecal jsenecal marked this pull request as draft November 20, 2025 06:21
@jsenecal jsenecal marked this pull request as ready for review November 20, 2025 07:54
@jsenecal jsenecal force-pushed the 17954-cable-import-dynamic-parent-resolution branch from d1c9288 to 7237bbe Compare November 20, 2025 12:06
Replace device-specific fields with generic parent fields to support
circuits, power panels, and other cable termination types.
@jsenecal jsenecal force-pushed the 17954-cable-import-dynamic-parent-resolution branch from 7237bbe to c111c08 Compare November 20, 2025 12:16
@jeremystretch jeremystretch requested review from a team and arthanson and removed request for a team November 20, 2025 19:14
@jeremystretch jeremystretch requested review from jeremystretch and removed request for arthanson December 1, 2025 16:14
Copy link
Member

@jeremystretch jeremystretch left a comment

Choose a reason for hiding this comment

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

Thanks for your work on this @jsenecal. It's a novel approach, however I don't think it quite addresses the concerns raised under #17995.

Ideally, we want to support the dynamic assignment of objects using a minimal set of fields. I would expect these to be:

  • side_x_type: The type of the terminating object
  • side_x: The object identifier, supporting an arbitrary accessor (e.g. name or pk) selected by the user
  • side_x_parent: The parent object identifier, likewise supporting an arbitrary accessor

We want to avoid forcing the use of a specific attribute for any particular object to ensure flexibility and maintain consistency with similar import forms.

The other major consideration in play here (which admittedly is absent from #17954) is support for declaring multiple terminating objects at either end of a cable. Even if we solve the immediate concern of parent object identification, it would be a half-measure at best unless we can also support the attachment of multiple terminations. I'm not sure we have a pattern for this yet, but presumably it would involve employing CSVModelMultipleChoiceField for the terminating objects and dynamically adjusting its queryset on form initialization.

Have you done any exploration in that area?

@jsenecal
Copy link
Contributor Author

jsenecal commented Dec 3, 2025

Thanks for your work on this @jsenecal. It's a novel approach, however I don't think it quite addresses the concerns raised under #17995.

Ideally, we want to support the dynamic assignment of objects using a minimal set of fields. I would expect these to be:

  • side_x_type: The type of the terminating object
  • side_x: The object identifier, supporting an arbitrary accessor (e.g. name or pk) selected by the user
  • side_x_parent: The parent object identifier, likewise supporting an arbitrary accessor

We want to avoid forcing the use of a specific attribute for any particular object to ensure flexibility and maintain consistency with similar import forms.

The other major consideration in play here (which admittedly is absent from #17954) is support for declaring multiple terminating objects at either end of a cable. Even if we solve the immediate concern of parent object identification, it would be a half-measure at best unless we can also support the attachment of multiple terminations. I'm not sure we have a pattern for this yet, but presumably it would involve employing CSVModelMultipleChoiceField for the terminating objects and dynamically adjusting its queryset on form initialization.

Have you done any exploration in that area?

Hi @jeremystretch , I actually went with the side_x_parent single field per side approach in this PR as you can see in the modified tests : https://github.com/netbox-community/netbox/pull/20843/files#diff-fb7b770d4e8b9f98f2376f15c9e9fac16cb773b6d80e760be04c9ad2fd45ccf2R3552

Handling multiple objects at a time was out of scope on this and I was planning on opening a different issue/PR for that. The idea would we to support those using standard json arrays, or simple single string for reverse compatibility. Let me know if you'd like me to include this in this PR.

The current approach does everything in the "clean" phase of the form and allows great flexibility.

@jsenecal
Copy link
Contributor Author

jsenecal commented Dec 3, 2025

I just realized my usage example in the PR is outdated - my bad! Let me update that real quick 😅

@jeremystretch jeremystretch self-requested a review December 5, 2025 15:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cable bulk import when importing circuit terminations

2 participants