Circuit Terminations- Cable Bulk import

922 views
Skip to first unread message

vmurali

unread,
Feb 20, 2021, 4:05:08 PM2/20/21
to NetBox
Hi
Netbox: 2.9.9
Python : 3.6.8

Feature request: Circuit terminations : A/Z end Terminations inclusion in the bulk cable import CSV

Based on how API allows Circuit and Device Interface or passive ports to be connected using cable /dcim/cables/  is it possible to include circuits in the cable bulk import options?

Also Netbox now has circuit termination as an option under connect so should this also be extended for Bulk imports?
Please help me understand if its viable
Thanks
For example :api

{
    "id": 1759,
    "termination_a_type": "circuits.circuittermination",
    "termination_a_id": 61,
    "termination_a": {
        "id": 61,
        "url": "http://192.168.1.221/circuits/circuit-terminations/61/",
        "circuit": {
            "id": 39,
            "url": "http://192.168.1.221/api/circuits/circuits/39/",
            "cid": "181527-Rx"
        },
        "term_side": "A"
    },
    "termination_b_type": "dcim.interface",
    "termination_b_id": 3164,
    "termination_b": {
        "id": 3164,
        "url": "http://192.168.1.221/dcim/interfaces/3164/",
        "device": {
            "id": 301,
            "url": "http://192.168.1.221/api/dcim/devices/301/",
            "name": "tp-in-dwdm-02",
            "display_name": "tp-in-dwdm-02"
        },
        "name": "CH2-Rx-A",
        "cable": 1759,
        "connection_status": {
            "value": true,
            "label": "Connected"
        }
    },
    "type": "smf",
    "status": "connected",
    "label": "SR#2048",
    "color": "ffeb3b",
    "length": 50,
    "length_unit": "ft"
   
}

Brian Candler

unread,
Feb 21, 2021, 3:39:34 AM2/21/21
to NetBox
In Netbox 2.10, the CSV import for cables includes circuit termination as an option for side_a_type and side_b_type.  I haven't tested it.

img1.png
I don't see this specifically mentioned in the release notes, but there were other changes for circuits and cable path tracing in 2.10 so it's possible this was enabled at the same time.

Regards,

Brian.

vmurali

unread,
Feb 28, 2021, 8:42:19 PM2/28/21
to NetBox
Thank you for the prompt response.

I tried v2.10.5 , please advise on the what to set for side_b_device=? and side_b_name=?  when  I choose side_b_type= circuits.circuittermination

Side b device = Provider name or Circuit id ? and side_b_name= A or Z side?

When I choose sibe b device as circuit id or provider name both are unrecognized and side b name A side or Z side

side_a_device,side_a_type,side_a_name,side_b_device,side_b_type,side_b_name,type,color,length,length_unit
tp-da2-dwdm-03,dcim.frontport,CH12 Rx-A,Zayo Bandwidth,circuits.circuittermination,A,smf,ffff00,20,ft

  • Row 1 side_b_device: Object not found.
  • Row 1 __all__: Termination B type has not been specified

When I  connect it  through gui, the connected options for Termination A side has only provider and circuit  from this I assumed
side b device = Provider name
side_b_name = 181529-Rx (Side A)


Cable

Type

Singlemode Fiber

Status

Connected

Label

test

Color

 

Length

20 Feet
Tags
No tags assigned
Termination A

Provider

Zayo Bandwidth

Circuit

181529-Rx (Side A)
Termination B

Device

tp-da2-dwdm-03

Type

Front port

Component

CH12 Rx-A

Brian Candler

unread,
Mar 1, 2021, 3:17:17 AM3/1/21
to NetBox
As I said, I haven't tested it.

Looking at the code, I think it's an oversight.  It says
termination_object = model.objects.get(device=device, name=name)
but circuit terminations don't have "device" or "name" attributes.

This code could be changed, but I can't see how you could identify a circuit termination without at least three pieces of data (provider, cid, side A/Z)

It may have been unintentional to allow circuit terminations as an option for the endpoints for CSV uploads in the first place.

If you have a large number of them to import, I suggest you write a small bit of python which talks to the Netbox API instead.

Regards,

Brian.

----------------------

class CableCSVForm(CustomFieldModelCSVForm):
    # Termination A
    side_a_device = CSVModelChoiceField(
        queryset=Device.objects.all(),
        to_field_name='name',
        help_text='Side A device'
    )
    side_a_type = CSVContentTypeField(
        queryset=ContentType.objects.all(),
        limit_choices_to=CABLE_TERMINATION_MODELS,
        help_text='Side A type'
    )
    side_a_name = forms.CharField(
        help_text='Side A component name'
    )
...
    def clean_side_a_name(self):
        return self._clean_side('a')
...
    def _clean_side(self, side):
        """
        Derive a Cable's A/B termination objects.

        :param side: 'a' or 'b'
        """
        assert side in 'ab', f"Invalid side designation: {side}"

        device = self.cleaned_data.get(f'side_{side}_device')
        content_type = self.cleaned_data.get(f'side_{side}_type')
        name = self.cleaned_data.get(f'side_{side}_name')
        if not device or not content_type or not name:
            return None

        model = content_type.model_class()
        try:
            termination_object = model.objects.get(device=device, name=name)
            if termination_object.cable is not None:
                raise forms.ValidationError(f"Side {side.upper()}: {device} {termination_object} is already connected")
        except ObjectDoesNotExist:
            raise forms.ValidationError(f"{side.upper()} side termination not found: {device} {name}")

        setattr(self.instance, f'termination_{side}', termination_object)
        return termination_object
Reply all
Reply to author
Forward
0 new messages