@@ -371,6 +371,11 @@ def get_topology(nb_devices_qs, params):
371371 # Passive cabling devices use Rear and Front Ports.
372372 links_from_device = Cable .objects .filter (terminations__cable_end = 'A' , terminations___device_id = nb_device .id )
373373 links_to_device = Cable .objects .filter (terminations__cable_end = 'B' , terminations___device_id = nb_device .id )
374+
375+ # Filter out cables with incomplete terminations
376+ links_from_device = [c for c in links_from_device if (c .a_terminations and c .b_terminations )]
377+ links_to_device = [c for c in links_to_device if (c .a_terminations and c .b_terminations )]
378+
374379 interfaces_found = False
375380 if links_from_device :
376381 for link in links_from_device :
@@ -396,7 +401,7 @@ def get_topology(nb_devices_qs, params):
396401 continue
397402
398403 node_data = {
399- 'id' : nb_device .name ,
404+ 'id' : f'device- { nb_device .id } ' ,
400405 'name' : nb_device .name ,
401406 'label' : {'text' : nb_device .name },
402407 'layer' : get_node_layer_sort_preference (
@@ -453,8 +458,8 @@ def get_topology(nb_devices_qs, params):
453458 link_url = link .get_absolute_url ()
454459 edge_data = {
455460 "label" : f"Cable { link .id } " ,
456- "source" : link .a_terminations [0 ].device .name ,
457- "target" : link .b_terminations [0 ].device .name ,
461+ "source" : f"device- { link .a_terminations [0 ].device .id } " ,
462+ "target" : f"device- { link .b_terminations [0 ].device .id } " ,
458463 "sourceInterfaceLabel" : if_shortname (link .a_terminations [0 ].name ),
459464 "targetInterfaceLabel" : if_shortname (link .b_terminations [0 ].name ),
460465 "customAttributes" : {
@@ -490,22 +495,33 @@ def get_topology(nb_devices_qs, params):
490495 # identify segmented cable paths between end-devices
491496 if len (cable_path ) < 2 :
492497 continue
493- if isinstance (cable_path [0 ][0 ][0 ], Interface ) and isinstance (cable_path [- 1 ][2 ][0 ], Interface ):
498+
499+ side_a_interface = cable_path [0 ][0 ]
500+ side_b_interface = cable_path [- 1 ][2 ]
501+ if not (side_a_interface and side_b_interface ):
502+ continue
503+ else :
504+ side_a_interface = side_a_interface [0 ]
505+ side_b_interface = side_b_interface [0 ]
506+
507+ if isinstance (side_a_interface , Interface ) and isinstance (side_b_interface , Interface ):
494508 if set ([c [1 ][0 ] for c in cable_path ]) in [set ([c [1 ][0 ] for c in x ]) for x in multi_cable_connections ]:
495509 continue
496510 multi_cable_connections .append (cable_path )
497511 for cable_path in multi_cable_connections :
512+ source_device_id = f"device-{ side_a_interface .device .id } "
513+ target_device_id = f"device-{ side_b_interface .device .id } "
498514 topology_dict ['edges' ].append ({
499- 'source' : cable_path [ 0 ][ 0 ][ 0 ]. device . name ,
500- 'target' : cable_path [ - 1 ][ 2 ][ 0 ]. device . name ,
501- "sourceInterfaceLabel" : if_shortname (cable_path [ 0 ][ 0 ][ 0 ] .name ),
502- "targetInterfaceLabel" : if_shortname (cable_path [ - 1 ][ 2 ][ 0 ] .name ),
515+ 'source' : source_device_id ,
516+ 'target' : target_device_id ,
517+ "sourceInterfaceLabel" : if_shortname (side_a_interface .name ),
518+ "targetInterfaceLabel" : if_shortname (side_b_interface .name ),
503519 "isLogicalMultiCable" : True ,
504520 "customAttributes" : {
505521 "name" : f"Multi-Cable Connection" ,
506- "dcimCableURL" : f"/dcim/interfaces/{ cable_path [ 0 ][ 0 ][ 0 ] .id } /trace/" ,
507- "source" : link . a_terminations [ 0 ] .device .name ,
508- "target" : link . b_terminations [ 0 ] .device .name ,
522+ "dcimCableURL" : f"/dcim/interfaces/{ side_a_interface .id } /trace/" ,
523+ "source" : side_a_interface .device .name ,
524+ "target" : side_b_interface .device .name ,
509525 }
510526 })
511527 return topology_dict , device_roles , multi_cable_connections , all_device_tags
0 commit comments