Skip to content

cable with multiple connections can't cross module front/rear ports. #11079

@ThomasADavis

Description

@ThomasADavis

NetBox version

v3.3.9

Python version

3.9

Steps to Reproduce

We use a module fiber cassette system - these are cassettes you plug into 1u rack mount.

Trying to plug a MPO to LC breakout cable can cross these modules - the rear ports a single MPO and the front ports are 6 pairs of LC connectors. So the break out cable we use is a 1 MPO (ie, 100G qsfp) to 4 pair of LC's. This can cross between two modules.

  1. create a device. aka 'sw-test'

  2. add to this device a network interface. any type will do, except lag or virtual.

  3. create a module_type, with no components add.

  4. create a device to use as a patch panel.

  5. in that patch panel, create two module bays, 'C1' and 'C2'.

  6. populate the module bay with the above module type.

  7. for module C1 add rear port of 'MPO-1', positions of 6

  8. for module C2 add rear port of 'MPO-2', positions of 6

  9. for module C1, add front ports of 'LC-[1-6]', type 'LC', attached to rear-port MPO-1:[1-6]

  10. for module C2, add front ports of 'LC-[7-12]', type 'LC', attached to rear-port MPO-2:[1-6]

See attached screen shot for module/cassette/front/rear setup.
Screenshot_2022-12-01_15-02-22

  1. go to the test device you created.

  2. for the on the network interface, tell it you want to make a connection. Choose front port.

for the termination_b, choose LC-6 (associated with MPO-1) and LC-7 (associated with MPO-2)

Screenshot_2022-12-01_15-08-24

Get error message in browser.

Screenshot_2022-12-01_15-08-46

Stack dump from our test netbox instance, doing the same thing:

Traceback (most recent call last):
  File "/opt/netbox/venv/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "/opt/netbox/venv/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/opt/netbox/venv/lib/python3.10/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/opt/netbox/venv/lib/python3.10/site-packages/rest_framework/viewsets.py", line 125, in view
    return self.dispatch(request, *args, **kwargs)
  File "/opt/netbox/netbox/netbox/api/viewsets/__init__.py", line 118, in dispatch
    return super().dispatch(request, *args, **kwargs)
  File "/opt/netbox/venv/lib/python3.10/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/opt/netbox/venv/lib/python3.10/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/opt/netbox/venv/lib/python3.10/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/opt/netbox/venv/lib/python3.10/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/opt/netbox/venv/lib/python3.10/site-packages/rest_framework/mixins.py", line 19, in create
    self.perform_create(serializer)
  File "/opt/netbox/netbox/netbox/api/viewsets/__init__.py", line 157, in perform_create
    instance = serializer.save()
  File "/opt/netbox/venv/lib/python3.10/site-packages/rest_framework/serializers.py", line 212, in save
    self.instance = self.create(validated_data)
  File "/opt/netbox/netbox/netbox/api/serializers/features.py", line 56, in create
    instance = super().create(validated_data)
  File "/opt/netbox/venv/lib/python3.10/site-packages/rest_framework/serializers.py", line 962, in create
    instance = ModelClass._default_manager.create(**validated_data)
  File "/opt/netbox/venv/lib/python3.10/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/opt/netbox/venv/lib/python3.10/site-packages/django/db/models/query.py", line 514, in create
    obj.save(force_insert=True, using=self.db)
  File "/opt/netbox/netbox/dcim/models/cables.py", line 207, in save
    trace_paths.send(Cable, instance=self, created=_created)
  File "/opt/netbox/venv/lib/python3.10/site-packages/django/dispatch/dispatcher.py", line 176, in send
    return [
  File "/opt/netbox/venv/lib/python3.10/site-packages/django/dispatch/dispatcher.py", line 177, in <listcomp>
    (receiver, receiver(signal=self, sender=sender, **named))
  File "/opt/netbox/netbox/dcim/signals.py", line 97, in update_connected_endpoints
    create_cablepath(nodes)
  File "/opt/netbox/netbox/dcim/utils.py", line 43, in create_cablepath
    cp = CablePath.from_origin(terminations)
  File "/opt/netbox/netbox/dcim/models/cables.py", line 543, in from_origin
    assert all(rp.positions == 1 for rp in rear_ports)
AssertionError

Expected Behavior

Can attach a breakout cable across modules/frontports

Observed Behavior

Internal Server Error: /api/dcim/cables/
Traceback (most recent call last):
  File "/opt/netbox/venv/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "/opt/netbox/venv/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/opt/netbox/venv/lib/python3.10/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/opt/netbox/venv/lib/python3.10/site-packages/rest_framework/viewsets.py", line 125, in view
    return self.dispatch(request, *args, **kwargs)
  File "/opt/netbox/netbox/netbox/api/viewsets/__init__.py", line 118, in dispatch
    return super().dispatch(request, *args, **kwargs)
  File "/opt/netbox/venv/lib/python3.10/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/opt/netbox/venv/lib/python3.10/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/opt/netbox/venv/lib/python3.10/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/opt/netbox/venv/lib/python3.10/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/opt/netbox/venv/lib/python3.10/site-packages/rest_framework/mixins.py", line 19, in create
    self.perform_create(serializer)
  File "/opt/netbox/netbox/netbox/api/viewsets/__init__.py", line 157, in perform_create
    instance = serializer.save()
  File "/opt/netbox/venv/lib/python3.10/site-packages/rest_framework/serializers.py", line 212, in save
    self.instance = self.create(validated_data)
  File "/opt/netbox/netbox/netbox/api/serializers/features.py", line 56, in create
    instance = super().create(validated_data)
  File "/opt/netbox/venv/lib/python3.10/site-packages/rest_framework/serializers.py", line 962, in create
    instance = ModelClass._default_manager.create(**validated_data)
  File "/opt/netbox/venv/lib/python3.10/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/opt/netbox/venv/lib/python3.10/site-packages/django/db/models/query.py", line 514, in create
    obj.save(force_insert=True, using=self.db)
  File "/opt/netbox/netbox/dcim/models/cables.py", line 207, in save
    trace_paths.send(Cable, instance=self, created=_created)
  File "/opt/netbox/venv/lib/python3.10/site-packages/django/dispatch/dispatcher.py", line 176, in send
    return [
  File "/opt/netbox/venv/lib/python3.10/site-packages/django/dispatch/dispatcher.py", line 177, in <listcomp>
    (receiver, receiver(signal=self, sender=sender, **named))
  File "/opt/netbox/netbox/dcim/signals.py", line 97, in update_connected_endpoints
    create_cablepath(nodes)
  File "/opt/netbox/netbox/dcim/utils.py", line 43, in create_cablepath
    cp = CablePath.from_origin(terminations)
  File "/opt/netbox/netbox/dcim/models/cables.py", line 543, in from_origin
    assert all(rp.positions == 1 for rp in rear_ports)
AssertionError

Metadata

Metadata

Assignees

Labels

severity: mediumResults in substantial degraded or broken functionality for specfic workflowsstatus: acceptedThis issue has been accepted for implementationtopic: cablingtype: bugA confirmed report of unexpected behavior in the application

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions