1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Implemented Cable API endpoint

This commit is contained in:
Jeremy Stretch
2018-10-26 12:25:11 -04:00
parent 4ad7882762
commit 3518d023dc
4 changed files with 64 additions and 6 deletions

View File

@ -5,7 +5,7 @@ from taggit_serializer.serializers import TaggitSerializer, TagListSerializerFie
from circuits.models import Circuit, CircuitTermination
from dcim.constants import *
from dcim.models import (
ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
Cable, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
DeviceBayTemplate, DeviceType, DeviceRole, FrontPort, FrontPortTemplate, Interface, InterfaceTemplate,
Manufacturer, InventoryItem, Platform, PowerOutlet, PowerOutletTemplate, PowerPort, PowerPortTemplate, Rack,
RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site, VirtualChassis,
@ -15,8 +15,8 @@ from ipam.models import IPAddress, VLAN
from tenancy.api.serializers import NestedTenantSerializer
from users.api.serializers import NestedUserSerializer
from utilities.api import (
ChoiceField, SerializedPKRelatedField, TimeZoneField, ValidatedModelSerializer,
WritableNestedSerializer,
ChoiceField, ContentTypeField, SerializedPKRelatedField, TimeZoneField, ValidatedModelSerializer,
WritableNestedSerializer, get_serializer_for_model,
)
from virtualization.models import Cluster
@ -717,11 +717,12 @@ class RearPortSerializer(ValidatedModelSerializer):
class NestedRearPortSerializer(WritableNestedSerializer):
device = NestedDeviceSerializer(read_only=True)
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearport-detail')
class Meta:
model = RearPort
fields = ['id', 'url', 'name']
fields = ['id', 'url', 'device', 'name']
#
@ -740,11 +741,12 @@ class FrontPortSerializer(ValidatedModelSerializer):
class NestedFrontPortSerializer(WritableNestedSerializer):
device = NestedDeviceSerializer(read_only=True)
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:frontport-detail')
class Meta:
model = FrontPort
fields = ['id', 'url', 'name']
fields = ['id', 'url', 'device', 'name']
#
@ -807,6 +809,47 @@ class InterfaceConnectionSerializer(ValidatedModelSerializer):
return NestedInterfaceSerializer(instance=obj, context=context).data
#
# Cables
#
class CableSerializer(ValidatedModelSerializer):
termination_a_type = ContentTypeField()
termination_b_type = ContentTypeField()
termination_a = serializers.SerializerMethodField(read_only=True)
termination_b = serializers.SerializerMethodField(read_only=True)
status = ChoiceField(choices=CONNECTION_STATUS_CHOICES)
length_unit = ChoiceField(choices=LENGTH_UNIT_CHOICES)
class Meta:
model = Cable
fields = [
'id', 'termination_a_type', 'termination_a_id', 'termination_a', 'termination_b_type', 'termination_b_id',
'termination_b', 'type', 'status', 'label', 'color', 'length', 'length_unit',
]
def _get_termination(self, obj, side):
"""
Serialize a nested representation of a termination.
"""
if side.lower() not in ['a', 'b']:
raise ValueError("Termination side must be either A or B.")
termination = getattr(obj, 'termination_{}'.format(side.lower()))
if termination is None:
return None
serializer = get_serializer_for_model(termination, prefix='Nested')
context = {'request': self.context['request']}
data = serializer(termination, context=context).data
return data
def get_termination_a(self, obj):
return self._get_termination(obj, 'a')
def get_termination_b(self, obj):
return self._get_termination(obj, 'b')
#
# Virtual chassis
#

View File

@ -62,6 +62,9 @@ router.register(r'console-connections', views.ConsoleConnectionViewSet, base_nam
router.register(r'power-connections', views.PowerConnectionViewSet, base_name='powerconnections')
router.register(r'interface-connections', views.InterfaceConnectionViewSet, base_name='interfaceconnections')
# Cables
router.register(r'cables', views.CableViewSet)
# Virtual chassis
router.register(r'virtual-chassis', views.VirtualChassisViewSet)

View File

@ -14,7 +14,7 @@ from rest_framework.viewsets import GenericViewSet, ViewSet
from dcim import filters
from dcim.models import (
ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
Cable, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
DeviceBayTemplate, DeviceRole, DeviceType, FrontPort, FrontPortTemplate, Interface, InterfaceTemplate,
Manufacturer, InventoryItem, Platform, PowerOutlet, PowerOutletTemplate, PowerPort, PowerPortTemplate, Rack,
RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site, VirtualChassis,
@ -428,6 +428,16 @@ class InterfaceConnectionViewSet(ModelViewSet):
filter_class = filters.InterfaceConnectionFilter
#
# Cables
#
class CableViewSet(ModelViewSet):
queryset = Cable.objects.prefetch_related('termination_a__device', 'termination_b__device')
serializer_class = serializers.CableSerializer
filter_class = filters.CableFilter
#
# Virtual chassis
#

View File

@ -69,6 +69,8 @@ class ChoiceField(Field):
super(ChoiceField, self).__init__(**kwargs)
def to_representation(self, obj):
if obj is '':
return None
return {'value': obj, 'label': self._choices[obj]}
def to_internal_value(self, data):