mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Add cable paths API detail view for pass-through ports
This commit is contained in:
@ -7,12 +7,13 @@ from rest_framework.validators import UniqueTogetherValidator
|
||||
from dcim.choices import *
|
||||
from dcim.constants import *
|
||||
from dcim.models import (
|
||||
Cable, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
|
||||
Cable, CablePath, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
|
||||
DeviceBayTemplate, DeviceType, DeviceRole, FrontPort, FrontPortTemplate, Interface, InterfaceTemplate,
|
||||
Manufacturer, InventoryItem, Platform, PowerFeed, PowerOutlet, PowerOutletTemplate, PowerPanel, PowerPort,
|
||||
PowerPortTemplate, Rack, RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site,
|
||||
VirtualChassis,
|
||||
)
|
||||
from dcim.utils import decompile_path_node
|
||||
from extras.api.customfields import CustomFieldModelSerializer
|
||||
from extras.api.serializers import TaggedObjectSerializer
|
||||
from ipam.api.nested_serializers import NestedIPAddressSerializer, NestedVLANSerializer
|
||||
@ -734,6 +735,50 @@ class TracedCableSerializer(serializers.ModelSerializer):
|
||||
]
|
||||
|
||||
|
||||
class CablePathSerializer(serializers.ModelSerializer):
|
||||
origin_type = ContentTypeField(read_only=True)
|
||||
origin = serializers.SerializerMethodField(read_only=True)
|
||||
destination_type = ContentTypeField(read_only=True)
|
||||
destination = serializers.SerializerMethodField(read_only=True)
|
||||
path = serializers.SerializerMethodField(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = CablePath
|
||||
fields = [
|
||||
'id', 'origin_type', 'origin', 'destination_type', 'destination', 'path', 'is_active',
|
||||
]
|
||||
|
||||
@swagger_serializer_method(serializer_or_field=serializers.DictField)
|
||||
def get_origin(self, obj):
|
||||
"""
|
||||
Return the appropriate serializer for the origin.
|
||||
"""
|
||||
serializer = get_serializer_for_model(obj.origin, prefix='Nested')
|
||||
context = {'request': self.context['request']}
|
||||
return serializer(obj.origin, context=context).data
|
||||
|
||||
@swagger_serializer_method(serializer_or_field=serializers.DictField)
|
||||
def get_destination(self, obj):
|
||||
"""
|
||||
Return the appropriate serializer for the destination, if any.
|
||||
"""
|
||||
if obj.destination_id is not None:
|
||||
serializer = get_serializer_for_model(obj.destination, prefix='Nested')
|
||||
context = {'request': self.context['request']}
|
||||
return serializer(obj.destination, context=context).data
|
||||
return None
|
||||
|
||||
@swagger_serializer_method(serializer_or_field=serializers.ListField)
|
||||
def get_path(self, obj):
|
||||
ret = []
|
||||
for node in obj.path:
|
||||
ct_id, object_id = decompile_path_node(node)
|
||||
ct = ContentType.objects.get_for_id(ct_id)
|
||||
# TODO: Return the object URL
|
||||
ret.append(f'{ct.app_label}.{ct.model}:{object_id}')
|
||||
return ret
|
||||
|
||||
|
||||
#
|
||||
# Interface connections
|
||||
#
|
||||
|
@ -17,7 +17,7 @@ from rest_framework.viewsets import GenericViewSet, ViewSet
|
||||
from circuits.models import Circuit
|
||||
from dcim import filters
|
||||
from dcim.models import (
|
||||
Cable, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
|
||||
Cable, CablePath, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
|
||||
DeviceBayTemplate, DeviceRole, DeviceType, FrontPort, FrontPortTemplate, Interface, InterfaceTemplate,
|
||||
Manufacturer, InventoryItem, Platform, PowerFeed, PowerOutlet, PowerOutletTemplate, PowerPanel, PowerPort,
|
||||
PowerPortTemplate, Rack, RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site,
|
||||
@ -77,6 +77,20 @@ class PathEndpointMixin(object):
|
||||
return Response(path)
|
||||
|
||||
|
||||
class PassThroughPortMixin(object):
|
||||
|
||||
@action(detail=True, url_path='paths')
|
||||
def paths(self, request, pk):
|
||||
"""
|
||||
Return all CablePaths which traverse a given pass-through port.
|
||||
"""
|
||||
obj = get_object_or_404(self.queryset, pk=pk)
|
||||
cablepaths = CablePath.objects.filter(path__contains=obj).prefetch_related('origin', 'destination')
|
||||
serializer = serializers.CablePathSerializer(cablepaths, context={'request': request}, many=True)
|
||||
|
||||
return Response(serializer.data)
|
||||
|
||||
|
||||
#
|
||||
# Regions
|
||||
#
|
||||
@ -503,13 +517,13 @@ class InterfaceViewSet(PathEndpointMixin, ModelViewSet):
|
||||
filterset_class = filters.InterfaceFilterSet
|
||||
|
||||
|
||||
class FrontPortViewSet(ModelViewSet):
|
||||
class FrontPortViewSet(PassThroughPortMixin, ModelViewSet):
|
||||
queryset = FrontPort.objects.prefetch_related('device__device_type__manufacturer', 'rear_port', 'cable', 'tags')
|
||||
serializer_class = serializers.FrontPortSerializer
|
||||
filterset_class = filters.FrontPortFilterSet
|
||||
|
||||
|
||||
class RearPortViewSet(ModelViewSet):
|
||||
class RearPortViewSet(PassThroughPortMixin, ModelViewSet):
|
||||
queryset = RearPort.objects.prefetch_related('device__device_type__manufacturer', 'cable', 'tags')
|
||||
serializer_class = serializers.RearPortSerializer
|
||||
filterset_class = filters.RearPortFilterSet
|
||||
|
Reference in New Issue
Block a user