Fixes #17954 - Add dynamic parent resolution for cable CSV imports #845

Closed
opened 2026-04-05 18:07:12 +02:00 by MrUnknownDE · 0 comments
Owner

Originally created by @jsenecal on 11/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 #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
*Originally created by @jsenecal on 11/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 #17995 ### Usage Examples **Device to Device (Interface to Interface):** ```csv 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:** ```csv 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:** ```csv 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):** ```csv 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 ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github/netbox#845