|
@@ -28,58 +28,68 @@ from wireless.models import WirelessLAN
|
|
|
from .nested_serializers import *
|
|
from .nested_serializers import *
|
|
|
|
|
|
|
|
|
|
|
|
|
-class LinkTerminationSerializer(serializers.ModelSerializer):
|
|
|
|
|
- link_peer_type = serializers.SerializerMethodField(read_only=True)
|
|
|
|
|
- link_peer = serializers.SerializerMethodField(read_only=True)
|
|
|
|
|
|
|
+class CabledObjectSerializer(serializers.ModelSerializer):
|
|
|
|
|
+ cable = NestedCableSerializer(read_only=True)
|
|
|
|
|
+ cable_end = serializers.CharField(read_only=True)
|
|
|
|
|
+ link_peers_type = serializers.SerializerMethodField(read_only=True)
|
|
|
|
|
+ link_peers = serializers.SerializerMethodField(read_only=True)
|
|
|
_occupied = serializers.SerializerMethodField(read_only=True)
|
|
_occupied = serializers.SerializerMethodField(read_only=True)
|
|
|
|
|
|
|
|
- def get_link_peer_type(self, obj):
|
|
|
|
|
- if obj._link_peer is not None:
|
|
|
|
|
- return f'{obj._link_peer._meta.app_label}.{obj._link_peer._meta.model_name}'
|
|
|
|
|
|
|
+ def get_link_peers_type(self, obj):
|
|
|
|
|
+ """
|
|
|
|
|
+ Return the type of the peer link terminations, or None.
|
|
|
|
|
+ """
|
|
|
|
|
+ if not obj.cable:
|
|
|
|
|
+ return None
|
|
|
|
|
+
|
|
|
|
|
+ if obj.link_peers:
|
|
|
|
|
+ return f'{obj.link_peers[0]._meta.app_label}.{obj.link_peers[0]._meta.model_name}'
|
|
|
|
|
+
|
|
|
return None
|
|
return None
|
|
|
|
|
|
|
|
- @swagger_serializer_method(serializer_or_field=serializers.DictField)
|
|
|
|
|
- def get_link_peer(self, obj):
|
|
|
|
|
|
|
+ @swagger_serializer_method(serializer_or_field=serializers.ListField)
|
|
|
|
|
+ def get_link_peers(self, obj):
|
|
|
"""
|
|
"""
|
|
|
Return the appropriate serializer for the link termination model.
|
|
Return the appropriate serializer for the link termination model.
|
|
|
"""
|
|
"""
|
|
|
- if obj._link_peer is not None:
|
|
|
|
|
- serializer = get_serializer_for_model(obj._link_peer, prefix='Nested')
|
|
|
|
|
- context = {'request': self.context['request']}
|
|
|
|
|
- return serializer(obj._link_peer, context=context).data
|
|
|
|
|
- return None
|
|
|
|
|
|
|
+ if not obj.link_peers:
|
|
|
|
|
+ return []
|
|
|
|
|
+
|
|
|
|
|
+ # Return serialized peer termination objects
|
|
|
|
|
+ serializer = get_serializer_for_model(obj.link_peers[0], prefix='Nested')
|
|
|
|
|
+ context = {'request': self.context['request']}
|
|
|
|
|
+ return serializer(obj.link_peers, context=context, many=True).data
|
|
|
|
|
|
|
|
@swagger_serializer_method(serializer_or_field=serializers.BooleanField)
|
|
@swagger_serializer_method(serializer_or_field=serializers.BooleanField)
|
|
|
def get__occupied(self, obj):
|
|
def get__occupied(self, obj):
|
|
|
return obj._occupied
|
|
return obj._occupied
|
|
|
|
|
|
|
|
|
|
|
|
|
-class ConnectedEndpointSerializer(serializers.ModelSerializer):
|
|
|
|
|
- connected_endpoint_type = serializers.SerializerMethodField(read_only=True)
|
|
|
|
|
- connected_endpoint = serializers.SerializerMethodField(read_only=True)
|
|
|
|
|
- connected_endpoint_reachable = serializers.SerializerMethodField(read_only=True)
|
|
|
|
|
|
|
+class ConnectedEndpointsSerializer(serializers.ModelSerializer):
|
|
|
|
|
+ """
|
|
|
|
|
+ Legacy serializer for pre-v3.3 connections
|
|
|
|
|
+ """
|
|
|
|
|
+ connected_endpoints_type = serializers.SerializerMethodField(read_only=True)
|
|
|
|
|
+ connected_endpoints = serializers.SerializerMethodField(read_only=True)
|
|
|
|
|
+ connected_endpoints_reachable = serializers.SerializerMethodField(read_only=True)
|
|
|
|
|
|
|
|
- def get_connected_endpoint_type(self, obj):
|
|
|
|
|
- if obj._path is not None and obj._path.destination is not None:
|
|
|
|
|
- return f'{obj._path.destination._meta.app_label}.{obj._path.destination._meta.model_name}'
|
|
|
|
|
- return None
|
|
|
|
|
|
|
+ def get_connected_endpoints_type(self, obj):
|
|
|
|
|
+ if endpoints := obj.connected_endpoints:
|
|
|
|
|
+ return f'{endpoints[0]._meta.app_label}.{endpoints[0]._meta.model_name}'
|
|
|
|
|
|
|
|
- @swagger_serializer_method(serializer_or_field=serializers.DictField)
|
|
|
|
|
- def get_connected_endpoint(self, obj):
|
|
|
|
|
|
|
+ @swagger_serializer_method(serializer_or_field=serializers.ListField)
|
|
|
|
|
+ def get_connected_endpoints(self, obj):
|
|
|
"""
|
|
"""
|
|
|
Return the appropriate serializer for the type of connected object.
|
|
Return the appropriate serializer for the type of connected object.
|
|
|
"""
|
|
"""
|
|
|
- if obj._path is not None and obj._path.destination is not None:
|
|
|
|
|
- serializer = get_serializer_for_model(obj._path.destination, prefix='Nested')
|
|
|
|
|
|
|
+ if endpoints := obj.connected_endpoints:
|
|
|
|
|
+ serializer = get_serializer_for_model(endpoints[0], prefix='Nested')
|
|
|
context = {'request': self.context['request']}
|
|
context = {'request': self.context['request']}
|
|
|
- return serializer(obj._path.destination, context=context).data
|
|
|
|
|
- return None
|
|
|
|
|
|
|
+ return serializer(endpoints, many=True, context=context).data
|
|
|
|
|
|
|
|
@swagger_serializer_method(serializer_or_field=serializers.BooleanField)
|
|
@swagger_serializer_method(serializer_or_field=serializers.BooleanField)
|
|
|
- def get_connected_endpoint_reachable(self, obj):
|
|
|
|
|
- if obj._path is not None:
|
|
|
|
|
- return obj._path.is_active
|
|
|
|
|
- return None
|
|
|
|
|
|
|
+ def get_connected_endpoints_reachable(self, obj):
|
|
|
|
|
+ return obj._path and obj._path.is_complete and obj._path.is_active
|
|
|
|
|
|
|
|
|
|
|
|
|
#
|
|
#
|
|
@@ -684,7 +694,7 @@ class DeviceNAPALMSerializer(serializers.Serializer):
|
|
|
# Device components
|
|
# Device components
|
|
|
#
|
|
#
|
|
|
|
|
|
|
|
-class ConsoleServerPortSerializer(NetBoxModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
|
|
|
|
|
|
|
+class ConsoleServerPortSerializer(NetBoxModelSerializer, CabledObjectSerializer, ConnectedEndpointsSerializer):
|
|
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverport-detail')
|
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverport-detail')
|
|
|
device = NestedDeviceSerializer()
|
|
device = NestedDeviceSerializer()
|
|
|
module = ComponentNestedModuleSerializer(
|
|
module = ComponentNestedModuleSerializer(
|
|
@@ -701,18 +711,18 @@ class ConsoleServerPortSerializer(NetBoxModelSerializer, LinkTerminationSerializ
|
|
|
allow_null=True,
|
|
allow_null=True,
|
|
|
required=False
|
|
required=False
|
|
|
)
|
|
)
|
|
|
- cable = NestedCableSerializer(read_only=True)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
class Meta:
|
|
|
model = ConsoleServerPort
|
|
model = ConsoleServerPort
|
|
|
fields = [
|
|
fields = [
|
|
|
'id', 'url', 'display', 'device', 'module', 'name', 'label', 'type', 'speed', 'description',
|
|
'id', 'url', 'display', 'device', 'module', 'name', 'label', 'type', 'speed', 'description',
|
|
|
- 'mark_connected', 'cable', 'link_peer', 'link_peer_type', 'connected_endpoint', 'connected_endpoint_type',
|
|
|
|
|
- 'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
|
|
|
|
|
|
|
+ 'mark_connected', 'cable', 'cable_end', 'link_peers', 'link_peers_type', 'connected_endpoints',
|
|
|
|
|
+ 'connected_endpoints_type', 'connected_endpoints_reachable', 'tags', 'custom_fields', 'created',
|
|
|
|
|
+ 'last_updated', '_occupied',
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
-class ConsolePortSerializer(NetBoxModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
|
|
|
|
|
|
|
+class ConsolePortSerializer(NetBoxModelSerializer, CabledObjectSerializer, ConnectedEndpointsSerializer):
|
|
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleport-detail')
|
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleport-detail')
|
|
|
device = NestedDeviceSerializer()
|
|
device = NestedDeviceSerializer()
|
|
|
module = ComponentNestedModuleSerializer(
|
|
module = ComponentNestedModuleSerializer(
|
|
@@ -729,18 +739,18 @@ class ConsolePortSerializer(NetBoxModelSerializer, LinkTerminationSerializer, Co
|
|
|
allow_null=True,
|
|
allow_null=True,
|
|
|
required=False
|
|
required=False
|
|
|
)
|
|
)
|
|
|
- cable = NestedCableSerializer(read_only=True)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
class Meta:
|
|
|
model = ConsolePort
|
|
model = ConsolePort
|
|
|
fields = [
|
|
fields = [
|
|
|
'id', 'url', 'display', 'device', 'module', 'name', 'label', 'type', 'speed', 'description',
|
|
'id', 'url', 'display', 'device', 'module', 'name', 'label', 'type', 'speed', 'description',
|
|
|
- 'mark_connected', 'cable', 'link_peer', 'link_peer_type', 'connected_endpoint', 'connected_endpoint_type',
|
|
|
|
|
- 'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
|
|
|
|
|
|
|
+ 'mark_connected', 'cable', 'cable_end', 'link_peers', 'link_peers_type', 'connected_endpoints',
|
|
|
|
|
+ 'connected_endpoints_type', 'connected_endpoints_reachable', 'tags', 'custom_fields', 'created',
|
|
|
|
|
+ 'last_updated', '_occupied',
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
-class PowerOutletSerializer(NetBoxModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
|
|
|
|
|
|
|
+class PowerOutletSerializer(NetBoxModelSerializer, CabledObjectSerializer, ConnectedEndpointsSerializer):
|
|
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:poweroutlet-detail')
|
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:poweroutlet-detail')
|
|
|
device = NestedDeviceSerializer()
|
|
device = NestedDeviceSerializer()
|
|
|
module = ComponentNestedModuleSerializer(
|
|
module = ComponentNestedModuleSerializer(
|
|
@@ -761,21 +771,18 @@ class PowerOutletSerializer(NetBoxModelSerializer, LinkTerminationSerializer, Co
|
|
|
allow_blank=True,
|
|
allow_blank=True,
|
|
|
required=False
|
|
required=False
|
|
|
)
|
|
)
|
|
|
- cable = NestedCableSerializer(
|
|
|
|
|
- read_only=True
|
|
|
|
|
- )
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
class Meta:
|
|
|
model = PowerOutlet
|
|
model = PowerOutlet
|
|
|
fields = [
|
|
fields = [
|
|
|
'id', 'url', 'display', 'device', 'module', 'name', 'label', 'type', 'power_port', 'feed_leg',
|
|
'id', 'url', 'display', 'device', 'module', 'name', 'label', 'type', 'power_port', 'feed_leg',
|
|
|
- 'description', 'mark_connected', 'cable', 'link_peer', 'link_peer_type', 'connected_endpoint',
|
|
|
|
|
- 'connected_endpoint_type', 'connected_endpoint_reachable', 'tags', 'custom_fields', 'created',
|
|
|
|
|
- 'last_updated', '_occupied',
|
|
|
|
|
|
|
+ 'description', 'mark_connected', 'cable', 'cable_end', 'link_peers', 'link_peers_type',
|
|
|
|
|
+ 'connected_endpoints', 'connected_endpoints_type', 'connected_endpoints_reachable', 'tags', 'custom_fields',
|
|
|
|
|
+ 'created', 'last_updated', '_occupied',
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
-class PowerPortSerializer(NetBoxModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
|
|
|
|
|
|
|
+class PowerPortSerializer(NetBoxModelSerializer, CabledObjectSerializer, ConnectedEndpointsSerializer):
|
|
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerport-detail')
|
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerport-detail')
|
|
|
device = NestedDeviceSerializer()
|
|
device = NestedDeviceSerializer()
|
|
|
module = ComponentNestedModuleSerializer(
|
|
module = ComponentNestedModuleSerializer(
|
|
@@ -787,19 +794,18 @@ class PowerPortSerializer(NetBoxModelSerializer, LinkTerminationSerializer, Conn
|
|
|
allow_blank=True,
|
|
allow_blank=True,
|
|
|
required=False
|
|
required=False
|
|
|
)
|
|
)
|
|
|
- cable = NestedCableSerializer(read_only=True)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
class Meta:
|
|
|
model = PowerPort
|
|
model = PowerPort
|
|
|
fields = [
|
|
fields = [
|
|
|
'id', 'url', 'display', 'device', 'module', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw',
|
|
'id', 'url', 'display', 'device', 'module', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw',
|
|
|
- 'description', 'mark_connected', 'cable', 'link_peer', 'link_peer_type', 'connected_endpoint',
|
|
|
|
|
- 'connected_endpoint_type', 'connected_endpoint_reachable', 'tags', 'custom_fields', 'created',
|
|
|
|
|
- 'last_updated', '_occupied',
|
|
|
|
|
|
|
+ 'description', 'mark_connected', 'cable', 'cable_end', 'link_peers', 'link_peers_type',
|
|
|
|
|
+ 'connected_endpoints', 'connected_endpoints_type', 'connected_endpoints_reachable', 'tags', 'custom_fields',
|
|
|
|
|
+ 'created', 'last_updated', '_occupied',
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
-class InterfaceSerializer(NetBoxModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
|
|
|
|
|
|
|
+class InterfaceSerializer(NetBoxModelSerializer, CabledObjectSerializer, ConnectedEndpointsSerializer):
|
|
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail')
|
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail')
|
|
|
device = NestedDeviceSerializer()
|
|
device = NestedDeviceSerializer()
|
|
|
module = ComponentNestedModuleSerializer(
|
|
module = ComponentNestedModuleSerializer(
|
|
@@ -825,7 +831,6 @@ class InterfaceSerializer(NetBoxModelSerializer, LinkTerminationSerializer, Conn
|
|
|
)
|
|
)
|
|
|
vrf = NestedVRFSerializer(required=False, allow_null=True)
|
|
vrf = NestedVRFSerializer(required=False, allow_null=True)
|
|
|
l2vpn_termination = NestedL2VPNTerminationSerializer(read_only=True)
|
|
l2vpn_termination = NestedL2VPNTerminationSerializer(read_only=True)
|
|
|
- cable = NestedCableSerializer(read_only=True)
|
|
|
|
|
wireless_link = NestedWirelessLinkSerializer(read_only=True)
|
|
wireless_link = NestedWirelessLinkSerializer(read_only=True)
|
|
|
wireless_lans = SerializedPKRelatedField(
|
|
wireless_lans = SerializedPKRelatedField(
|
|
|
queryset=WirelessLAN.objects.all(),
|
|
queryset=WirelessLAN.objects.all(),
|
|
@@ -842,9 +847,10 @@ class InterfaceSerializer(NetBoxModelSerializer, LinkTerminationSerializer, Conn
|
|
|
'id', 'url', 'display', 'device', 'module', 'name', 'label', 'type', 'enabled', 'parent', 'bridge', 'lag',
|
|
'id', 'url', 'display', 'device', 'module', 'name', 'label', 'type', 'enabled', 'parent', 'bridge', 'lag',
|
|
|
'mtu', 'mac_address', 'speed', 'duplex', 'wwn', 'mgmt_only', 'description', 'mode', 'rf_role', 'rf_channel',
|
|
'mtu', 'mac_address', 'speed', 'duplex', 'wwn', 'mgmt_only', 'description', 'mode', 'rf_role', 'rf_channel',
|
|
|
'poe_mode', 'poe_type', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'untagged_vlan',
|
|
'poe_mode', 'poe_type', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'untagged_vlan',
|
|
|
- 'tagged_vlans', 'mark_connected', 'cable', 'wireless_link', 'link_peer', 'link_peer_type', 'wireless_lans',
|
|
|
|
|
- 'vrf', 'l2vpn_termination', 'connected_endpoint', 'connected_endpoint_type', 'connected_endpoint_reachable', 'tags',
|
|
|
|
|
- 'custom_fields', 'created', 'last_updated', 'count_ipaddresses', 'count_fhrp_groups', '_occupied',
|
|
|
|
|
|
|
+ 'tagged_vlans', 'mark_connected', 'cable', 'cable_end', 'wireless_link', 'link_peers', 'link_peers_type',
|
|
|
|
|
+ 'wireless_lans', 'vrf', 'l2vpn_termination', 'connected_endpoints', 'connected_endpoints_type',
|
|
|
|
|
+ 'connected_endpoints_reachable', 'tags', 'custom_fields', 'created', 'last_updated', 'count_ipaddresses',
|
|
|
|
|
+ 'count_fhrp_groups', '_occupied',
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
def validate(self, data):
|
|
def validate(self, data):
|
|
@@ -861,7 +867,7 @@ class InterfaceSerializer(NetBoxModelSerializer, LinkTerminationSerializer, Conn
|
|
|
return super().validate(data)
|
|
return super().validate(data)
|
|
|
|
|
|
|
|
|
|
|
|
|
-class RearPortSerializer(NetBoxModelSerializer, LinkTerminationSerializer):
|
|
|
|
|
|
|
+class RearPortSerializer(NetBoxModelSerializer, CabledObjectSerializer):
|
|
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearport-detail')
|
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearport-detail')
|
|
|
device = NestedDeviceSerializer()
|
|
device = NestedDeviceSerializer()
|
|
|
module = ComponentNestedModuleSerializer(
|
|
module = ComponentNestedModuleSerializer(
|
|
@@ -869,13 +875,12 @@ class RearPortSerializer(NetBoxModelSerializer, LinkTerminationSerializer):
|
|
|
allow_null=True
|
|
allow_null=True
|
|
|
)
|
|
)
|
|
|
type = ChoiceField(choices=PortTypeChoices)
|
|
type = ChoiceField(choices=PortTypeChoices)
|
|
|
- cable = NestedCableSerializer(read_only=True)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
class Meta:
|
|
|
model = RearPort
|
|
model = RearPort
|
|
|
fields = [
|
|
fields = [
|
|
|
'id', 'url', 'display', 'device', 'module', 'name', 'label', 'type', 'color', 'positions', 'description',
|
|
'id', 'url', 'display', 'device', 'module', 'name', 'label', 'type', 'color', 'positions', 'description',
|
|
|
- 'mark_connected', 'cable', 'link_peer', 'link_peer_type', 'tags', 'custom_fields', 'created',
|
|
|
|
|
|
|
+ 'mark_connected', 'cable', 'cable_end', 'link_peers', 'link_peers_type', 'tags', 'custom_fields', 'created',
|
|
|
'last_updated', '_occupied',
|
|
'last_updated', '_occupied',
|
|
|
]
|
|
]
|
|
|
|
|
|
|
@@ -891,7 +896,7 @@ class FrontPortRearPortSerializer(WritableNestedSerializer):
|
|
|
fields = ['id', 'url', 'display', 'name', 'label']
|
|
fields = ['id', 'url', 'display', 'name', 'label']
|
|
|
|
|
|
|
|
|
|
|
|
|
-class FrontPortSerializer(NetBoxModelSerializer, LinkTerminationSerializer):
|
|
|
|
|
|
|
+class FrontPortSerializer(NetBoxModelSerializer, CabledObjectSerializer):
|
|
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:frontport-detail')
|
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:frontport-detail')
|
|
|
device = NestedDeviceSerializer()
|
|
device = NestedDeviceSerializer()
|
|
|
module = ComponentNestedModuleSerializer(
|
|
module = ComponentNestedModuleSerializer(
|
|
@@ -900,14 +905,13 @@ class FrontPortSerializer(NetBoxModelSerializer, LinkTerminationSerializer):
|
|
|
)
|
|
)
|
|
|
type = ChoiceField(choices=PortTypeChoices)
|
|
type = ChoiceField(choices=PortTypeChoices)
|
|
|
rear_port = FrontPortRearPortSerializer()
|
|
rear_port = FrontPortRearPortSerializer()
|
|
|
- cable = NestedCableSerializer(read_only=True)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
class Meta:
|
|
|
model = FrontPort
|
|
model = FrontPort
|
|
|
fields = [
|
|
fields = [
|
|
|
'id', 'url', 'display', 'device', 'module', 'name', 'label', 'type', 'color', 'rear_port',
|
|
'id', 'url', 'display', 'device', 'module', 'name', 'label', 'type', 'color', 'rear_port',
|
|
|
- 'rear_port_position', 'description', 'mark_connected', 'cable', 'link_peer', 'link_peer_type', 'tags',
|
|
|
|
|
- 'custom_fields', 'created', 'last_updated', '_occupied',
|
|
|
|
|
|
|
+ 'rear_port_position', 'description', 'mark_connected', 'cable', 'cable_end', 'link_peers',
|
|
|
|
|
+ 'link_peers_type', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
@@ -990,14 +994,10 @@ class InventoryItemRoleSerializer(NetBoxModelSerializer):
|
|
|
|
|
|
|
|
class CableSerializer(NetBoxModelSerializer):
|
|
class CableSerializer(NetBoxModelSerializer):
|
|
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:cable-detail')
|
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:cable-detail')
|
|
|
- termination_a_type = ContentTypeField(
|
|
|
|
|
- queryset=ContentType.objects.filter(CABLE_TERMINATION_MODELS)
|
|
|
|
|
- )
|
|
|
|
|
- termination_b_type = ContentTypeField(
|
|
|
|
|
- queryset=ContentType.objects.filter(CABLE_TERMINATION_MODELS)
|
|
|
|
|
- )
|
|
|
|
|
- termination_a = serializers.SerializerMethodField(read_only=True)
|
|
|
|
|
- termination_b = serializers.SerializerMethodField(read_only=True)
|
|
|
|
|
|
|
+ a_terminations_type = serializers.SerializerMethodField(read_only=True)
|
|
|
|
|
+ b_terminations_type = serializers.SerializerMethodField(read_only=True)
|
|
|
|
|
+ a_terminations = serializers.SerializerMethodField(read_only=True)
|
|
|
|
|
+ b_terminations = serializers.SerializerMethodField(read_only=True)
|
|
|
status = ChoiceField(choices=LinkStatusChoices, required=False)
|
|
status = ChoiceField(choices=LinkStatusChoices, required=False)
|
|
|
tenant = NestedTenantSerializer(required=False, allow_null=True)
|
|
tenant = NestedTenantSerializer(required=False, allow_null=True)
|
|
|
length_unit = ChoiceField(choices=CableLengthUnitChoices, allow_blank=True, required=False)
|
|
length_unit = ChoiceField(choices=CableLengthUnitChoices, allow_blank=True, required=False)
|
|
@@ -1005,33 +1005,46 @@ class CableSerializer(NetBoxModelSerializer):
|
|
|
class Meta:
|
|
class Meta:
|
|
|
model = Cable
|
|
model = Cable
|
|
|
fields = [
|
|
fields = [
|
|
|
- 'id', 'url', 'display', 'termination_a_type', 'termination_a_id', 'termination_a', 'termination_b_type',
|
|
|
|
|
- 'termination_b_id', 'termination_b', 'type', 'status', 'tenant', 'label', 'color', 'length', 'length_unit',
|
|
|
|
|
- 'tags', 'custom_fields', 'created', 'last_updated',
|
|
|
|
|
|
|
+ 'id', 'url', 'display', 'type', 'a_terminations_type', 'a_terminations', 'b_terminations_type',
|
|
|
|
|
+ 'b_terminations', 'status', 'tenant', 'label', 'color', 'length', 'length_unit', 'tags', 'custom_fields',
|
|
|
|
|
+ 'created', 'last_updated',
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
- 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')
|
|
|
|
|
|
|
+ def _get_terminations_type(self, obj, side):
|
|
|
|
|
+ assert side in CableEndChoices.values()
|
|
|
|
|
+ terms = getattr(obj, f'get_{side.lower()}_terminations')()
|
|
|
|
|
+ if terms:
|
|
|
|
|
+ ct = ContentType.objects.get_for_model(terms[0])
|
|
|
|
|
+ return f"{ct.app_label}.{ct.model}"
|
|
|
|
|
+
|
|
|
|
|
+ def _get_terminations(self, obj, side):
|
|
|
|
|
+ assert side in CableEndChoices.values()
|
|
|
|
|
+ terms = getattr(obj, f'get_{side.lower()}_terminations')()
|
|
|
|
|
+ if not terms:
|
|
|
|
|
+ return []
|
|
|
|
|
+
|
|
|
|
|
+ termination_type = ContentType.objects.get_for_model(terms[0])
|
|
|
|
|
+ serializer = get_serializer_for_model(termination_type.model_class(), prefix='Nested')
|
|
|
context = {'request': self.context['request']}
|
|
context = {'request': self.context['request']}
|
|
|
- data = serializer(termination, context=context).data
|
|
|
|
|
|
|
+ data = serializer(terms, context=context, many=True).data
|
|
|
|
|
|
|
|
return data
|
|
return data
|
|
|
|
|
|
|
|
|
|
+ @swagger_serializer_method(serializer_or_field=serializers.CharField)
|
|
|
|
|
+ def get_a_terminations_type(self, obj):
|
|
|
|
|
+ return self._get_terminations_type(obj, CableEndChoices.SIDE_A)
|
|
|
|
|
+
|
|
|
|
|
+ @swagger_serializer_method(serializer_or_field=serializers.CharField)
|
|
|
|
|
+ def get_b_terminations_type(self, obj):
|
|
|
|
|
+ return self._get_terminations_type(obj, CableEndChoices.SIDE_B)
|
|
|
|
|
+
|
|
|
@swagger_serializer_method(serializer_or_field=serializers.DictField)
|
|
@swagger_serializer_method(serializer_or_field=serializers.DictField)
|
|
|
- def get_termination_a(self, obj):
|
|
|
|
|
- return self._get_termination(obj, 'a')
|
|
|
|
|
|
|
+ def get_a_terminations(self, obj):
|
|
|
|
|
+ return self._get_terminations(obj, CableEndChoices.SIDE_A)
|
|
|
|
|
|
|
|
@swagger_serializer_method(serializer_or_field=serializers.DictField)
|
|
@swagger_serializer_method(serializer_or_field=serializers.DictField)
|
|
|
- def get_termination_b(self, obj):
|
|
|
|
|
- return self._get_termination(obj, 'b')
|
|
|
|
|
|
|
+ def get_b_terminations(self, obj):
|
|
|
|
|
+ return self._get_terminations(obj, CableEndChoices.SIDE_B)
|
|
|
|
|
|
|
|
|
|
|
|
|
class TracedCableSerializer(serializers.ModelSerializer):
|
|
class TracedCableSerializer(serializers.ModelSerializer):
|
|
@@ -1047,46 +1060,40 @@ 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 CableTerminationSerializer(NetBoxModelSerializer):
|
|
|
|
|
+ url = serializers.HyperlinkedIdentityField(view_name='dcim-api:cabletermination-detail')
|
|
|
|
|
+ termination_type = ContentTypeField(
|
|
|
|
|
+ queryset=ContentType.objects.filter(CABLE_TERMINATION_MODELS)
|
|
|
|
|
+ )
|
|
|
|
|
+ termination = serializers.SerializerMethodField(read_only=True)
|
|
|
|
|
|
|
|
class Meta:
|
|
class Meta:
|
|
|
- model = CablePath
|
|
|
|
|
|
|
+ model = CableTermination
|
|
|
fields = [
|
|
fields = [
|
|
|
- 'id', 'origin_type', 'origin', 'destination_type', 'destination', 'path', 'is_active', 'is_split',
|
|
|
|
|
|
|
+ 'id', 'url', 'display', 'cable', 'cable_end', 'termination_type', 'termination_id', 'termination'
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
@swagger_serializer_method(serializer_or_field=serializers.DictField)
|
|
@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')
|
|
|
|
|
|
|
+ def get_termination(self, obj):
|
|
|
|
|
+ serializer = get_serializer_for_model(obj.termination, prefix='Nested')
|
|
|
context = {'request': self.context['request']}
|
|
context = {'request': self.context['request']}
|
|
|
- return serializer(obj.origin, context=context).data
|
|
|
|
|
|
|
+ return serializer(obj.termination, 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
|
|
|
|
|
|
|
+
|
|
|
|
|
+class CablePathSerializer(serializers.ModelSerializer):
|
|
|
|
|
+ path = serializers.SerializerMethodField(read_only=True)
|
|
|
|
|
+
|
|
|
|
|
+ class Meta:
|
|
|
|
|
+ model = CablePath
|
|
|
|
|
+ fields = ['id', 'path', 'is_active', 'is_complete', 'is_split']
|
|
|
|
|
|
|
|
@swagger_serializer_method(serializer_or_field=serializers.ListField)
|
|
@swagger_serializer_method(serializer_or_field=serializers.ListField)
|
|
|
def get_path(self, obj):
|
|
def get_path(self, obj):
|
|
|
ret = []
|
|
ret = []
|
|
|
- for node in obj.get_path():
|
|
|
|
|
- serializer = get_serializer_for_model(node, prefix='Nested')
|
|
|
|
|
|
|
+ for nodes in obj.path_objects:
|
|
|
|
|
+ serializer = get_serializer_for_model(nodes[0], prefix='Nested')
|
|
|
context = {'request': self.context['request']}
|
|
context = {'request': self.context['request']}
|
|
|
- ret.append(serializer(node, context=context).data)
|
|
|
|
|
|
|
+ ret.append(serializer(nodes, context=context, many=True).data)
|
|
|
return ret
|
|
return ret
|
|
|
|
|
|
|
|
|
|
|
|
@@ -1129,7 +1136,7 @@ class PowerPanelSerializer(NetBoxModelSerializer):
|
|
|
]
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
-class PowerFeedSerializer(NetBoxModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
|
|
|
|
|
|
|
+class PowerFeedSerializer(NetBoxModelSerializer, CabledObjectSerializer, ConnectedEndpointsSerializer):
|
|
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerfeed-detail')
|
|
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerfeed-detail')
|
|
|
power_panel = NestedPowerPanelSerializer()
|
|
power_panel = NestedPowerPanelSerializer()
|
|
|
rack = NestedRackSerializer(
|
|
rack = NestedRackSerializer(
|
|
@@ -1153,13 +1160,12 @@ class PowerFeedSerializer(NetBoxModelSerializer, LinkTerminationSerializer, Conn
|
|
|
choices=PowerFeedPhaseChoices,
|
|
choices=PowerFeedPhaseChoices,
|
|
|
default=PowerFeedPhaseChoices.PHASE_SINGLE
|
|
default=PowerFeedPhaseChoices.PHASE_SINGLE
|
|
|
)
|
|
)
|
|
|
- cable = NestedCableSerializer(read_only=True)
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
class Meta:
|
|
|
model = PowerFeed
|
|
model = PowerFeed
|
|
|
fields = [
|
|
fields = [
|
|
|
'id', 'url', 'display', 'power_panel', 'rack', 'name', 'status', 'type', 'supply', 'phase', 'voltage',
|
|
'id', 'url', 'display', 'power_panel', 'rack', 'name', 'status', 'type', 'supply', 'phase', 'voltage',
|
|
|
- 'amperage', 'max_utilization', 'comments', 'mark_connected', 'cable', 'link_peer', 'link_peer_type',
|
|
|
|
|
- 'connected_endpoint', 'connected_endpoint_type', 'connected_endpoint_reachable', 'tags', 'custom_fields',
|
|
|
|
|
- 'created', 'last_updated', '_occupied',
|
|
|
|
|
|
|
+ 'amperage', 'max_utilization', 'comments', 'mark_connected', 'cable', 'cable_end', 'link_peers',
|
|
|
|
|
+ 'link_peers_type', 'connected_endpoints', 'connected_endpoints_type', 'connected_endpoints_reachable',
|
|
|
|
|
+ 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
|
|
|
]
|
|
]
|