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

893 lines
35 KiB
Python
Raw Normal View History

from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from drf_yasg.utils import swagger_serializer_method
2016-03-01 11:23:03 -05:00
from rest_framework import serializers
from timezone_field.rest_framework import TimeZoneSerializerField
2016-03-01 11:23:03 -05:00
from dcim.choices import *
2018-10-03 14:04:16 -04:00
from dcim.constants import *
from dcim.models import *
from ipam.api.nested_serializers import NestedIPAddressSerializer, NestedVLANSerializer
from ipam.models import VLAN
2021-03-25 16:09:28 -04:00
from netbox.api import ChoiceField, ContentTypeField, SerializedPKRelatedField
2021-02-25 17:15:07 -05:00
from netbox.api.serializers import (
NestedGroupModelSerializer, PrimaryModelSerializer, ValidatedModelSerializer, WritableNestedSerializer,
2021-02-25 17:15:07 -05:00
)
from tenancy.api.nested_serializers import NestedTenantSerializer
from users.api.nested_serializers import NestedUserSerializer
from utilities.api import get_serializer_for_model
from virtualization.api.nested_serializers import NestedClusterSerializer
from wireless.choices import *
from .nested_serializers import *
2016-03-01 11:23:03 -05:00
2021-10-13 14:04:53 -04:00
class LinkTerminationSerializer(serializers.ModelSerializer):
link_peer_type = serializers.SerializerMethodField(read_only=True)
link_peer = serializers.SerializerMethodField(read_only=True)
_occupied = serializers.SerializerMethodField(read_only=True)
2021-10-13 14:04:53 -04:00
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}'
return None
@swagger_serializer_method(serializer_or_field=serializers.DictField)
2021-10-13 14:04:53 -04:00
def get_link_peer(self, obj):
"""
2021-10-13 14:04:53 -04:00
Return the appropriate serializer for the link termination model.
"""
2021-10-13 14:04:53 -04:00
if obj._link_peer is not None:
serializer = get_serializer_for_model(obj._link_peer, prefix='Nested')
context = {'request': self.context['request']}
2021-10-13 14:04:53 -04:00
return serializer(obj._link_peer, context=context).data
return None
@swagger_serializer_method(serializer_or_field=serializers.BooleanField)
def get__occupied(self, obj):
return obj._occupied
2021-03-12 13:30:23 -05:00
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)
2017-02-28 16:10:53 -05:00
def get_connected_endpoint_type(self, obj):
2020-10-05 10:08:16 -04:00
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
2017-02-28 16:10:53 -05:00
@swagger_serializer_method(serializer_or_field=serializers.DictField)
def get_connected_endpoint(self, obj):
"""
Return the appropriate serializer for the type of connected object.
"""
2020-10-05 10:08:16 -04:00
if obj._path is not None and obj._path.destination is not None:
serializer = get_serializer_for_model(obj._path.destination, prefix='Nested')
2020-10-01 14:16:43 -04:00
context = {'request': self.context['request']}
2020-10-05 10:08:16 -04:00
return serializer(obj._path.destination, context=context).data
2020-10-01 14:16:43 -04:00
return None
@swagger_serializer_method(serializer_or_field=serializers.BooleanField)
def get_connected_endpoint_reachable(self, obj):
2020-10-05 10:08:16 -04:00
if obj._path is not None:
return obj._path.is_active
return None
2017-02-28 16:10:53 -05:00
#
# Regions/sites
2017-02-28 16:10:53 -05:00
#
2021-02-25 17:15:07 -05:00
class RegionSerializer(NestedGroupModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:region-detail')
parent = NestedRegionSerializer(required=False, allow_null=True, default=None)
site_count = serializers.IntegerField(read_only=True)
2017-02-28 16:10:53 -05:00
class Meta:
model = Region
fields = [
'id', 'url', 'display', 'name', 'slug', 'parent', 'description', 'tags', 'custom_fields', 'created',
'last_updated', 'site_count', '_depth',
]
2017-02-28 16:10:53 -05:00
class SiteGroupSerializer(NestedGroupModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:sitegroup-detail')
parent = NestedSiteGroupSerializer(required=False, allow_null=True, default=None)
site_count = serializers.IntegerField(read_only=True)
class Meta:
model = SiteGroup
fields = [
'id', 'url', 'display', 'name', 'slug', 'parent', 'description', 'tags', 'custom_fields', 'created',
'last_updated', 'site_count', '_depth',
]
2021-03-12 13:30:23 -05:00
class SiteSerializer(PrimaryModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:site-detail')
2019-11-21 22:54:01 -05:00
status = ChoiceField(choices=SiteStatusChoices, required=False)
2018-04-05 14:12:43 -04:00
region = NestedRegionSerializer(required=False, allow_null=True)
group = NestedSiteGroupSerializer(required=False, allow_null=True)
2018-04-05 14:12:43 -04:00
tenant = NestedTenantSerializer(required=False, allow_null=True)
time_zone = TimeZoneSerializerField(required=False)
circuit_count = serializers.IntegerField(read_only=True)
device_count = serializers.IntegerField(read_only=True)
prefix_count = serializers.IntegerField(read_only=True)
rack_count = serializers.IntegerField(read_only=True)
virtualmachine_count = serializers.IntegerField(read_only=True)
vlan_count = serializers.IntegerField(read_only=True)
2016-03-01 11:23:03 -05:00
class Meta:
model = Site
fields = [
'id', 'url', 'display', 'name', 'slug', 'status', 'region', 'group', 'tenant', 'facility', 'asn',
'time_zone', 'description', 'physical_address', 'shipping_address', 'latitude', 'longitude', 'contact_name',
'contact_phone', 'contact_email', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
'circuit_count', 'device_count', 'prefix_count', 'rack_count', 'virtualmachine_count', 'vlan_count',
]
2016-03-01 11:23:03 -05:00
#
# Racks
2016-03-01 11:23:03 -05:00
#
class LocationSerializer(NestedGroupModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:location-detail')
site = NestedSiteSerializer()
parent = NestedLocationSerializer(required=False, allow_null=True)
tenant = NestedTenantSerializer(required=False, allow_null=True)
rack_count = serializers.IntegerField(read_only=True)
2021-04-05 11:04:12 -04:00
device_count = serializers.IntegerField(read_only=True)
2016-03-01 11:23:03 -05:00
class Meta:
model = Location
fields = [
'id', 'url', 'display', 'name', 'slug', 'site', 'parent', 'tenant', 'description', 'tags', 'custom_fields',
'created', 'last_updated', 'rack_count', 'device_count', '_depth',
]
2016-03-01 11:23:03 -05:00
class RackRoleSerializer(PrimaryModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackrole-detail')
rack_count = serializers.IntegerField(read_only=True)
2016-08-10 11:52:27 -04:00
class Meta:
model = RackRole
fields = [
'id', 'url', 'display', 'name', 'slug', 'color', 'description', 'tags', 'custom_fields', 'created',
'last_updated', 'rack_count',
]
2016-08-10 11:52:27 -04:00
2021-03-12 13:30:23 -05:00
class RackSerializer(PrimaryModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rack-detail')
site = NestedSiteSerializer()
location = NestedLocationSerializer(required=False, allow_null=True, default=None)
2018-04-05 14:12:43 -04:00
tenant = NestedTenantSerializer(required=False, allow_null=True)
2019-11-15 22:03:41 -05:00
status = ChoiceField(choices=RackStatusChoices, required=False)
2018-04-05 14:12:43 -04:00
role = NestedRackRoleSerializer(required=False, allow_null=True)
type = ChoiceField(choices=RackTypeChoices, allow_blank=True, required=False)
facility_id = serializers.CharField(max_length=50, allow_blank=True, allow_null=True, label='Facility ID',
default=None)
width = ChoiceField(choices=RackWidthChoices, required=False)
outer_unit = ChoiceField(choices=RackDimensionUnitChoices, allow_blank=True, required=False)
device_count = serializers.IntegerField(read_only=True)
powerfeed_count = serializers.IntegerField(read_only=True)
2016-03-01 11:23:03 -05:00
class Meta:
model = Rack
fields = [
'id', 'url', 'display', 'name', 'facility_id', 'site', 'location', 'tenant', 'status', 'role', 'serial',
'asset_tag', 'type', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit',
'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'device_count', 'powerfeed_count',
]
2016-03-01 11:23:03 -05:00
class RackUnitSerializer(serializers.Serializer):
"""
A rack unit is an abstraction formed by the set (rack, position, face); it does not exist as a row in the database.
"""
id = serializers.IntegerField(read_only=True)
name = serializers.CharField(read_only=True)
2019-12-11 13:39:10 -05:00
face = ChoiceField(choices=DeviceFaceChoices, read_only=True)
device = NestedDeviceSerializer(read_only=True)
occupied = serializers.BooleanField(read_only=True)
display = serializers.SerializerMethodField(read_only=True)
def get_display(self, obj):
return obj['name']
2021-03-12 13:30:23 -05:00
class RackReservationSerializer(PrimaryModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackreservation-detail')
rack = NestedRackSerializer()
2017-12-18 16:52:49 -05:00
user = NestedUserSerializer()
2018-04-05 14:12:43 -04:00
tenant = NestedTenantSerializer(required=False, allow_null=True)
class Meta:
model = RackReservation
fields = [
'id', 'url', 'display', 'rack', 'units', 'created', 'user', 'tenant', 'description', 'tags',
'custom_fields',
]
2019-12-11 09:45:08 -05:00
class RackElevationDetailFilterSerializer(serializers.Serializer):
q = serializers.CharField(
required=False,
default=None
)
face = serializers.ChoiceField(
choices=DeviceFaceChoices,
default=DeviceFaceChoices.FACE_FRONT
)
render = serializers.ChoiceField(
choices=RackElevationDetailRenderChoices,
default=RackElevationDetailRenderChoices.RENDER_JSON
)
unit_width = serializers.IntegerField(
default=settings.RACK_ELEVATION_DEFAULT_UNIT_WIDTH
)
unit_height = serializers.IntegerField(
default=settings.RACK_ELEVATION_DEFAULT_UNIT_HEIGHT
)
legend_width = serializers.IntegerField(
default=RACK_ELEVATION_LEGEND_WIDTH_DEFAULT
)
exclude = serializers.IntegerField(
required=False,
default=None
)
expand_devices = serializers.BooleanField(
required=False,
default=True
2019-12-11 13:39:10 -05:00
)
include_images = serializers.BooleanField(
required=False,
default=True
)
2019-12-11 09:45:08 -05:00
2016-03-01 11:23:03 -05:00
#
# Device types
2016-03-01 11:23:03 -05:00
#
class ManufacturerSerializer(PrimaryModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:manufacturer-detail')
devicetype_count = serializers.IntegerField(read_only=True)
inventoryitem_count = serializers.IntegerField(read_only=True)
platform_count = serializers.IntegerField(read_only=True)
2016-03-01 11:23:03 -05:00
class Meta:
model = Manufacturer
fields = [
'id', 'url', 'display', 'name', 'slug', 'description', 'tags', 'custom_fields', 'created', 'last_updated',
'devicetype_count', 'inventoryitem_count', 'platform_count',
]
2016-03-01 11:23:03 -05:00
2021-03-12 13:30:23 -05:00
class DeviceTypeSerializer(PrimaryModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicetype-detail')
manufacturer = NestedManufacturerSerializer()
subdevice_role = ChoiceField(choices=SubdeviceRoleChoices, allow_blank=True, required=False)
2021-10-14 15:38:29 -04:00
airflow = ChoiceField(choices=DeviceAirflowChoices, allow_blank=True, required=False)
device_count = serializers.IntegerField(read_only=True)
class Meta:
model = DeviceType
fields = [
'id', 'url', 'display', 'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth',
2021-10-14 15:38:29 -04:00
'subdevice_role', 'airflow', 'front_image', 'rear_image', 'comments', 'tags', 'custom_fields', 'created',
'last_updated', 'device_count',
]
class ConsolePortTemplateSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleporttemplate-detail')
device_type = NestedDeviceTypeSerializer()
type = ChoiceField(
choices=ConsolePortTypeChoices,
allow_blank=True,
required=False
)
class Meta:
model = ConsolePortTemplate
fields = [
'id', 'url', 'display', 'device_type', 'name', 'label', 'type', 'description', 'created', 'last_updated',
]
class ConsoleServerPortTemplateSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverporttemplate-detail')
device_type = NestedDeviceTypeSerializer()
type = ChoiceField(
choices=ConsolePortTypeChoices,
allow_blank=True,
required=False
)
class Meta:
model = ConsoleServerPortTemplate
fields = [
'id', 'url', 'display', 'device_type', 'name', 'label', 'type', 'description', 'created', 'last_updated',
]
class PowerPortTemplateSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerporttemplate-detail')
device_type = NestedDeviceTypeSerializer()
2019-11-06 15:30:54 -05:00
type = ChoiceField(
choices=PowerPortTypeChoices,
allow_blank=True,
2019-11-06 15:30:54 -05:00
required=False
)
class Meta:
model = PowerPortTemplate
fields = [
'id', 'url', 'display', 'device_type', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw',
'description', 'created', 'last_updated',
]
class PowerOutletTemplateSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:poweroutlettemplate-detail')
device_type = NestedDeviceTypeSerializer()
2019-11-06 15:30:54 -05:00
type = ChoiceField(
choices=PowerOutletTypeChoices,
allow_blank=True,
2019-11-06 15:30:54 -05:00
required=False
)
power_port = NestedPowerPortTemplateSerializer(
2019-04-11 11:37:44 -04:00
required=False
)
feed_leg = ChoiceField(
2019-11-27 21:29:58 -05:00
choices=PowerOutletFeedLegChoices,
allow_blank=True,
required=False
)
class Meta:
model = PowerOutletTemplate
fields = [
'id', 'url', 'display', 'device_type', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description',
'created', 'last_updated',
]
class InterfaceTemplateSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interfacetemplate-detail')
device_type = NestedDeviceTypeSerializer()
type = ChoiceField(choices=InterfaceTypeChoices)
class Meta:
model = InterfaceTemplate
fields = [
'id', 'url', 'display', 'device_type', 'name', 'label', 'type', 'mgmt_only', 'description', 'created',
'last_updated',
]
class RearPortTemplateSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearporttemplate-detail')
2018-10-03 14:04:16 -04:00
device_type = NestedDeviceTypeSerializer()
2019-11-25 19:39:25 -05:00
type = ChoiceField(choices=PortTypeChoices)
2018-10-03 14:04:16 -04:00
class Meta:
model = RearPortTemplate
fields = [
'id', 'url', 'display', 'device_type', 'name', 'label', 'type', 'color', 'positions', 'description',
'created', 'last_updated',
]
2018-10-03 14:04:16 -04:00
class FrontPortTemplateSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:frontporttemplate-detail')
2018-10-03 14:04:16 -04:00
device_type = NestedDeviceTypeSerializer()
2019-11-25 19:39:25 -05:00
type = ChoiceField(choices=PortTypeChoices)
rear_port = NestedRearPortTemplateSerializer()
2018-10-03 14:04:16 -04:00
class Meta:
model = FrontPortTemplate
fields = [
'id', 'url', 'display', 'device_type', 'name', 'label', 'type', 'color', 'rear_port', 'rear_port_position',
'description', 'created', 'last_updated',
]
2018-10-03 14:04:16 -04:00
class DeviceBayTemplateSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicebaytemplate-detail')
device_type = NestedDeviceTypeSerializer()
class Meta:
model = DeviceBayTemplate
fields = ['id', 'url', 'display', 'device_type', 'name', 'label', 'description', 'created', 'last_updated']
2016-03-01 11:23:03 -05:00
#
# Devices
2016-03-01 11:23:03 -05:00
#
class DeviceRoleSerializer(PrimaryModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicerole-detail')
device_count = serializers.IntegerField(read_only=True)
virtualmachine_count = serializers.IntegerField(read_only=True)
2016-03-01 11:23:03 -05:00
class Meta:
model = DeviceRole
fields = [
'id', 'url', 'display', 'name', 'slug', 'color', 'vm_role', 'description', 'tags', 'custom_fields',
'created', 'last_updated', 'device_count', 'virtualmachine_count',
]
2016-03-01 11:23:03 -05:00
class PlatformSerializer(PrimaryModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:platform-detail')
2018-04-05 14:12:43 -04:00
manufacturer = NestedManufacturerSerializer(required=False, allow_null=True)
device_count = serializers.IntegerField(read_only=True)
virtualmachine_count = serializers.IntegerField(read_only=True)
2016-03-01 11:23:03 -05:00
class Meta:
model = Platform
fields = [
'id', 'url', 'display', 'name', 'slug', 'manufacturer', 'napalm_driver', 'napalm_args', 'description',
'tags', 'custom_fields', 'created', 'last_updated', 'device_count', 'virtualmachine_count',
]
2018-02-01 13:02:34 -05:00
2021-03-12 13:30:23 -05:00
class DeviceSerializer(PrimaryModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:device-detail')
device_type = NestedDeviceTypeSerializer()
device_role = NestedDeviceRoleSerializer()
tenant = NestedTenantSerializer(required=False, allow_null=True, default=None)
2018-04-05 14:12:43 -04:00
platform = NestedPlatformSerializer(required=False, allow_null=True)
site = NestedSiteSerializer()
location = NestedLocationSerializer(required=False, allow_null=True, default=None)
rack = NestedRackSerializer(required=False, allow_null=True, default=None)
face = ChoiceField(choices=DeviceFaceChoices, allow_blank=True, default='')
position = serializers.IntegerField(allow_null=True, label='Position (U)', min_value=1, default=None)
2019-11-25 19:23:43 -05:00
status = ChoiceField(choices=DeviceStatusChoices, required=False)
2021-10-14 16:04:42 -04:00
airflow = ChoiceField(choices=DeviceAirflowChoices, allow_blank=True, required=False)
primary_ip = NestedIPAddressSerializer(read_only=True)
primary_ip4 = NestedIPAddressSerializer(required=False, allow_null=True)
primary_ip6 = NestedIPAddressSerializer(required=False, allow_null=True)
parent_device = serializers.SerializerMethodField()
2018-04-05 14:12:43 -04:00
cluster = NestedClusterSerializer(required=False, allow_null=True)
virtual_chassis = NestedVirtualChassisSerializer(required=False, allow_null=True, default=None)
vc_position = serializers.IntegerField(allow_null=True, max_value=255, min_value=0, default=None)
2016-03-01 11:23:03 -05:00
class Meta:
model = Device
fields = [
'id', 'url', 'display', 'name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag',
2021-10-14 16:04:42 -04:00
'site', 'location', 'rack', 'position', 'face', 'parent_device', 'status', 'airflow', 'primary_ip',
'primary_ip4', 'primary_ip6', 'cluster', 'virtual_chassis', 'vc_position', 'vc_priority', 'comments',
'local_context_data', 'tags', 'custom_fields', 'created', 'last_updated',
]
@swagger_serializer_method(serializer_or_field=NestedDeviceSerializer)
def get_parent_device(self, obj):
try:
device_bay = obj.parent_bay
except DeviceBay.DoesNotExist:
return None
context = {'request': self.context['request']}
data = NestedDeviceSerializer(instance=device_bay.device, context=context).data
data['device_bay'] = NestedDeviceBaySerializer(instance=device_bay, context=context).data
2017-03-17 12:16:24 -04:00
return data
class DeviceWithConfigContextSerializer(DeviceSerializer):
config_context = serializers.SerializerMethodField()
class Meta(DeviceSerializer.Meta):
fields = [
'id', 'url', 'display', 'name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag',
'site', 'location', 'rack', 'position', 'face', 'parent_device', 'status', 'primary_ip', 'primary_ip4',
'primary_ip6', 'cluster', 'virtual_chassis', 'vc_position', 'vc_priority', 'comments', 'local_context_data',
'tags', 'custom_fields', 'config_context', 'created', 'last_updated',
]
@swagger_serializer_method(serializer_or_field=serializers.DictField)
def get_config_context(self, obj):
return obj.get_config_context()
class DeviceNAPALMSerializer(serializers.Serializer):
method = serializers.DictField()
2021-03-12 13:30:23 -05:00
#
# Device components
#
2021-10-13 14:04:53 -04:00
class ConsoleServerPortSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverport-detail')
device = NestedDeviceSerializer()
type = ChoiceField(
choices=ConsolePortTypeChoices,
allow_blank=True,
required=False
)
speed = ChoiceField(
choices=ConsolePortSpeedChoices,
allow_blank=True,
required=False
)
2018-10-29 13:14:41 -04:00
cable = NestedCableSerializer(read_only=True)
2016-03-01 11:23:03 -05:00
class Meta:
model = ConsoleServerPort
fields = [
'id', 'url', 'display', 'device', 'name', 'label', 'type', 'speed', 'description', 'mark_connected',
2021-10-13 14:04:53 -04:00
'cable', 'link_peer', 'link_peer_type', 'connected_endpoint', 'connected_endpoint_type',
'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
]
2016-03-01 11:23:03 -05:00
2021-10-13 14:04:53 -04:00
class ConsolePortSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleport-detail')
device = NestedDeviceSerializer()
type = ChoiceField(
choices=ConsolePortTypeChoices,
allow_blank=True,
required=False
)
speed = ChoiceField(
choices=ConsolePortSpeedChoices,
allow_blank=True,
required=False
)
2018-10-29 13:14:41 -04:00
cable = NestedCableSerializer(read_only=True)
2016-03-01 11:23:03 -05:00
class Meta:
model = ConsolePort
fields = [
'id', 'url', 'display', 'device', 'name', 'label', 'type', 'speed', 'description', 'mark_connected',
2021-10-13 14:04:53 -04:00
'cable', 'link_peer', 'link_peer_type', 'connected_endpoint', 'connected_endpoint_type',
'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
]
2018-10-04 16:20:01 -04:00
2016-03-01 11:23:03 -05:00
2021-10-13 14:04:53 -04:00
class PowerOutletSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:poweroutlet-detail')
device = NestedDeviceSerializer()
2019-11-06 15:30:54 -05:00
type = ChoiceField(
choices=PowerOutletTypeChoices,
allow_blank=True,
2019-11-06 15:30:54 -05:00
required=False
)
2019-04-11 11:37:44 -04:00
power_port = NestedPowerPortSerializer(
required=False
)
feed_leg = ChoiceField(
2019-11-27 21:29:58 -05:00
choices=PowerOutletFeedLegChoices,
allow_blank=True,
required=False
)
cable = NestedCableSerializer(
read_only=True
)
2016-03-01 11:23:03 -05:00
class Meta:
model = PowerOutlet
fields = [
'id', 'url', 'display', 'device', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description',
2021-10-13 14:04:53 -04:00
'mark_connected', 'cable', 'link_peer', 'link_peer_type', 'connected_endpoint', 'connected_endpoint_type',
'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
]
2016-03-01 11:23:03 -05:00
2021-10-13 14:04:53 -04:00
class PowerPortSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerport-detail')
device = NestedDeviceSerializer()
2019-11-06 15:30:54 -05:00
type = ChoiceField(
choices=PowerPortTypeChoices,
allow_blank=True,
2019-11-06 15:30:54 -05:00
required=False
)
2018-10-29 13:14:41 -04:00
cable = NestedCableSerializer(read_only=True)
2016-03-01 11:23:03 -05:00
class Meta:
model = PowerPort
fields = [
'id', 'url', 'display', 'device', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description',
2021-10-13 14:04:53 -04:00
'mark_connected', 'cable', 'link_peer', 'link_peer_type', 'connected_endpoint', 'connected_endpoint_type',
'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
]
2021-10-13 14:04:53 -04:00
class InterfaceSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail')
device = NestedDeviceSerializer()
type = ChoiceField(choices=InterfaceTypeChoices)
2021-03-05 13:49:41 -05:00
parent = NestedInterfaceSerializer(required=False, allow_null=True)
2018-04-05 14:12:43 -04:00
lag = NestedInterfaceSerializer(required=False, allow_null=True)
mode = ChoiceField(choices=InterfaceModeChoices, allow_blank=True, required=False)
2021-10-13 20:16:36 -04:00
rf_role = ChoiceField(choices=WirelessRoleChoices, required=False, allow_null=True)
2021-10-13 13:39:14 -04:00
rf_channel = ChoiceField(choices=WirelessChannelChoices, required=False)
untagged_vlan = NestedVLANSerializer(required=False, allow_null=True)
tagged_vlans = SerializedPKRelatedField(
queryset=VLAN.objects.all(),
serializer=NestedVLANSerializer,
required=False,
many=True
)
2018-10-29 13:14:41 -04:00
cable = NestedCableSerializer(read_only=True)
count_ipaddresses = serializers.IntegerField(read_only=True)
2016-03-01 11:23:03 -05:00
class Meta:
model = Interface
fields = [
'id', 'url', 'display', 'device', 'name', 'label', 'type', 'enabled', 'parent', 'lag', 'mtu', 'mac_address',
'wwn', 'mgmt_only', 'description', 'mode', 'rf_role', 'rf_channel', 'rf_channel_frequency',
'rf_channel_width', 'untagged_vlan', 'tagged_vlans', 'mark_connected', 'cable', 'link_peer',
'link_peer_type', 'connected_endpoint', 'connected_endpoint_type', 'connected_endpoint_reachable', 'tags',
'custom_fields', 'created', 'last_updated', 'count_ipaddresses', '_occupied',
]
def validate(self, data):
# Validate many-to-many VLAN assignments
device = self.instance.device if self.instance else data.get('device')
for vlan in data.get('tagged_vlans', []):
if vlan.site not in [device.site, None]:
raise serializers.ValidationError({
'tagged_vlans': f"VLAN {vlan} must belong to the same site as the interface's parent device, or "
f"it must be global."
})
return super().validate(data)
2016-03-01 11:23:03 -05:00
2021-10-13 14:04:53 -04:00
class RearPortSerializer(PrimaryModelSerializer, LinkTerminationSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearport-detail')
2018-10-03 14:04:16 -04:00
device = NestedDeviceSerializer()
2019-11-25 19:39:25 -05:00
type = ChoiceField(choices=PortTypeChoices)
2018-10-29 13:14:41 -04:00
cable = NestedCableSerializer(read_only=True)
2018-10-03 14:04:16 -04:00
class Meta:
model = RearPort
fields = [
'id', 'url', 'display', 'device', 'name', 'label', 'type', 'color', 'positions', 'description',
2021-10-13 14:04:53 -04:00
'mark_connected', 'cable', 'link_peer', 'link_peer_type', 'tags', 'custom_fields', 'created',
'last_updated', '_occupied',
]
2016-07-05 13:43:19 -04:00
2018-10-03 14:04:16 -04:00
2018-10-29 13:26:09 -04:00
class FrontPortRearPortSerializer(WritableNestedSerializer):
"""
NestedRearPortSerializer but with parent device omitted (since front and rear ports must belong to same device)
"""
2018-10-29 13:26:09 -04:00
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearport-detail')
class Meta:
model = RearPort
fields = ['id', 'url', 'display', 'name', 'label']
2018-10-29 13:26:09 -04:00
2021-10-13 14:04:53 -04:00
class FrontPortSerializer(PrimaryModelSerializer, LinkTerminationSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:frontport-detail')
device = NestedDeviceSerializer()
2019-11-25 19:39:25 -05:00
type = ChoiceField(choices=PortTypeChoices)
2018-10-29 13:26:09 -04:00
rear_port = FrontPortRearPortSerializer()
2018-10-29 13:14:41 -04:00
cable = NestedCableSerializer(read_only=True)
2016-07-05 13:43:19 -04:00
class Meta:
model = FrontPort
fields = [
'id', 'url', 'display', 'device', 'name', 'label', 'type', 'color', 'rear_port', 'rear_port_position',
2021-10-13 14:04:53 -04:00
'description', 'mark_connected', 'cable', 'link_peer', 'link_peer_type', 'tags', 'custom_fields',
'created', 'last_updated', '_occupied',
]
2016-07-05 13:43:19 -04:00
2021-03-12 13:30:23 -05:00
class DeviceBaySerializer(PrimaryModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicebay-detail')
device = NestedDeviceSerializer()
2018-04-05 14:12:43 -04:00
installed_device = NestedDeviceSerializer(required=False, allow_null=True)
class Meta:
model = DeviceBay
fields = [
'id', 'url', 'display', 'device', 'name', 'label', 'description', 'installed_device', 'tags',
'custom_fields', 'created', 'last_updated',
]
#
# Inventory items
#
2021-03-12 13:30:23 -05:00
class InventoryItemSerializer(PrimaryModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:inventoryitem-detail')
device = NestedDeviceSerializer()
parent = serializers.PrimaryKeyRelatedField(queryset=InventoryItem.objects.all(), allow_null=True, default=None)
manufacturer = NestedManufacturerSerializer(required=False, allow_null=True, default=None)
_depth = serializers.IntegerField(source='level', read_only=True)
class Meta:
model = InventoryItem
fields = [
'id', 'url', 'display', 'device', 'parent', 'name', 'label', 'manufacturer', 'part_id', 'serial',
'asset_tag', 'discovered', 'description', 'tags', 'custom_fields', 'created', 'last_updated', '_depth',
]
#
# Cables
#
2021-03-12 13:30:23 -05:00
class CableSerializer(PrimaryModelSerializer):
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)
2021-10-13 14:31:30 -04:00
status = ChoiceField(choices=LinkStatusChoices, required=False)
tenant = NestedTenantSerializer(required=False, allow_null=True)
length_unit = ChoiceField(choices=CableLengthUnitChoices, allow_blank=True, required=False)
class Meta:
model = Cable
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',
]
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
@swagger_serializer_method(serializer_or_field=serializers.DictField)
def get_termination_a(self, obj):
return self._get_termination(obj, 'a')
@swagger_serializer_method(serializer_or_field=serializers.DictField)
def get_termination_b(self, obj):
return self._get_termination(obj, 'b')
class TracedCableSerializer(serializers.ModelSerializer):
"""
Used only while tracing a cable path.
"""
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:cable-detail')
class Meta:
model = Cable
fields = [
'id', 'url', 'type', 'status', 'label', 'color', 'length', 'length_unit',
]
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 = [
2020-11-16 15:49:07 -05:00
'id', 'origin_type', 'origin', 'destination_type', 'destination', 'path', 'is_active', 'is_split',
]
@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.get_path():
serializer = get_serializer_for_model(node, prefix='Nested')
context = {'request': self.context['request']}
ret.append(serializer(node, context=context).data)
return ret
#
# Virtual chassis
#
2021-03-12 13:30:23 -05:00
class VirtualChassisSerializer(PrimaryModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:virtualchassis-detail')
master = NestedDeviceSerializer(required=False)
member_count = serializers.IntegerField(read_only=True)
class Meta:
model = VirtualChassis
fields = ['id', 'url', 'display', 'name', 'domain', 'master', 'tags', 'custom_fields', 'member_count']
2019-03-12 11:36:29 -04:00
#
# Power panels
#
2021-03-12 13:30:23 -05:00
class PowerPanelSerializer(PrimaryModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerpanel-detail')
2019-03-12 11:36:29 -04:00
site = NestedSiteSerializer()
location = NestedLocationSerializer(
2019-03-12 11:36:29 -04:00
required=False,
allow_null=True,
default=None
)
powerfeed_count = serializers.IntegerField(read_only=True)
2019-03-12 11:36:29 -04:00
class Meta:
model = PowerPanel
fields = ['id', 'url', 'display', 'site', 'location', 'name', 'tags', 'custom_fields', 'powerfeed_count']
2019-03-12 11:36:29 -04:00
2021-10-13 14:04:53 -04:00
class PowerFeedSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerfeed-detail')
2019-03-12 11:36:29 -04:00
power_panel = NestedPowerPanelSerializer()
rack = NestedRackSerializer(
required=False,
allow_null=True,
default=None
)
type = ChoiceField(
2019-11-25 21:03:11 -05:00
choices=PowerFeedTypeChoices,
default=PowerFeedTypeChoices.TYPE_PRIMARY
2019-03-12 11:36:29 -04:00
)
status = ChoiceField(
2019-11-25 21:21:35 -05:00
choices=PowerFeedStatusChoices,
default=PowerFeedStatusChoices.STATUS_ACTIVE
2019-03-12 11:36:29 -04:00
)
supply = ChoiceField(
2019-11-25 21:08:34 -05:00
choices=PowerFeedSupplyChoices,
default=PowerFeedSupplyChoices.SUPPLY_AC
2019-03-12 11:36:29 -04:00
)
phase = ChoiceField(
2019-11-25 21:14:04 -05:00
choices=PowerFeedPhaseChoices,
default=PowerFeedPhaseChoices.PHASE_SINGLE
2019-03-12 11:36:29 -04:00
)
cable = NestedCableSerializer(read_only=True)
2019-03-12 11:36:29 -04:00
class Meta:
model = PowerFeed
fields = [
'id', 'url', 'display', 'power_panel', 'rack', 'name', 'status', 'type', 'supply', 'phase', 'voltage',
2021-10-13 14:04:53 -04:00
'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',
2019-03-12 11:36:29 -04:00
]