| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- from django.contrib.contenttypes.models import ContentType
- from drf_spectacular.utils import extend_schema_field
- from rest_framework import serializers
- from dcim.choices import *
- from dcim.constants import *
- from dcim.models import (
- ConsolePort, ConsoleServerPort, DeviceBay, FrontPort, Interface, InventoryItem, ModuleBay, PowerOutlet, PowerPort,
- RearPort, VirtualDeviceContext,
- )
- from ipam.api.serializers_.vlans import VLANSerializer, VLANTranslationPolicySerializer
- from ipam.api.serializers_.vrfs import VRFSerializer
- from ipam.models import VLAN
- from netbox.api.fields import ChoiceField, ContentTypeField, SerializedPKRelatedField
- from netbox.api.serializers import NetBoxModelSerializer, WritableNestedSerializer
- from utilities.api import get_serializer_for_model
- from vpn.api.serializers_.l2vpn import L2VPNTerminationSerializer
- from wireless.api.serializers_.nested import NestedWirelessLinkSerializer
- from wireless.api.serializers_.wirelesslans import WirelessLANSerializer
- from wireless.choices import *
- from wireless.models import WirelessLAN
- from .base import ConnectedEndpointsSerializer
- from .cables import CabledObjectSerializer
- from .devices import DeviceSerializer, MACAddressSerializer, ModuleSerializer, VirtualDeviceContextSerializer
- from .manufacturers import ManufacturerSerializer
- from .nested import NestedInterfaceSerializer
- from .roles import InventoryItemRoleSerializer
- __all__ = (
- 'ConsolePortSerializer',
- 'ConsoleServerPortSerializer',
- 'DeviceBaySerializer',
- 'FrontPortSerializer',
- 'InterfaceSerializer',
- 'InventoryItemSerializer',
- 'ModuleBaySerializer',
- 'PowerOutletSerializer',
- 'PowerPortSerializer',
- 'RearPortSerializer',
- )
- class ConsoleServerPortSerializer(NetBoxModelSerializer, CabledObjectSerializer, ConnectedEndpointsSerializer):
- device = DeviceSerializer(nested=True)
- module = ModuleSerializer(
- nested=True,
- fields=('id', 'url', 'display', 'device', 'module_bay'),
- required=False,
- allow_null=True
- )
- type = ChoiceField(
- choices=ConsolePortTypeChoices,
- allow_blank=True,
- required=False
- )
- speed = ChoiceField(
- choices=ConsolePortSpeedChoices,
- allow_null=True,
- required=False
- )
- class Meta:
- model = ConsoleServerPort
- fields = [
- 'id', 'url', 'display_url', 'display', 'device', 'module', 'name', 'label', 'type', 'speed', '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',
- ]
- brief_fields = ('id', 'url', 'display', 'device', 'name', 'description', 'cable', '_occupied')
- class ConsolePortSerializer(NetBoxModelSerializer, CabledObjectSerializer, ConnectedEndpointsSerializer):
- device = DeviceSerializer(nested=True)
- module = ModuleSerializer(
- nested=True,
- fields=('id', 'url', 'display', 'device', 'module_bay'),
- required=False,
- allow_null=True
- )
- type = ChoiceField(
- choices=ConsolePortTypeChoices,
- allow_blank=True,
- required=False
- )
- speed = ChoiceField(
- choices=ConsolePortSpeedChoices,
- allow_null=True,
- required=False
- )
- class Meta:
- model = ConsolePort
- fields = [
- 'id', 'url', 'display_url', 'display', 'device', 'module', 'name', 'label', 'type', 'speed', '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',
- ]
- brief_fields = ('id', 'url', 'display', 'device', 'name', 'description', 'cable', '_occupied')
- class PowerPortSerializer(NetBoxModelSerializer, CabledObjectSerializer, ConnectedEndpointsSerializer):
- device = DeviceSerializer(nested=True)
- module = ModuleSerializer(
- nested=True,
- fields=('id', 'url', 'display', 'device', 'module_bay'),
- required=False,
- allow_null=True
- )
- type = ChoiceField(
- choices=PowerPortTypeChoices,
- allow_blank=True,
- required=False,
- allow_null=True
- )
- class Meta:
- model = PowerPort
- fields = [
- 'id', 'url', 'display_url', 'display', 'device', 'module', 'name', 'label', 'type', 'maximum_draw',
- 'allocated_draw', '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',
- ]
- brief_fields = ('id', 'url', 'display', 'device', 'name', 'description', 'cable', '_occupied')
- class PowerOutletSerializer(NetBoxModelSerializer, CabledObjectSerializer, ConnectedEndpointsSerializer):
- device = DeviceSerializer(nested=True)
- module = ModuleSerializer(
- nested=True,
- fields=('id', 'url', 'display', 'device', 'module_bay'),
- required=False,
- allow_null=True
- )
- type = ChoiceField(
- choices=PowerOutletTypeChoices,
- allow_blank=True,
- required=False,
- allow_null=True
- )
- power_port = PowerPortSerializer(
- nested=True,
- required=False,
- allow_null=True
- )
- feed_leg = ChoiceField(
- choices=PowerOutletFeedLegChoices,
- allow_blank=True,
- required=False,
- allow_null=True
- )
- class Meta:
- model = PowerOutlet
- fields = [
- 'id', 'url', 'display_url', 'display', 'device', 'module', 'name', 'label', 'type', 'color', 'power_port',
- 'feed_leg', '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',
- ]
- brief_fields = ('id', 'url', 'display', 'device', 'name', 'description', 'cable', '_occupied')
- class InterfaceSerializer(NetBoxModelSerializer, CabledObjectSerializer, ConnectedEndpointsSerializer):
- device = DeviceSerializer(nested=True)
- vdcs = SerializedPKRelatedField(
- queryset=VirtualDeviceContext.objects.all(),
- serializer=VirtualDeviceContextSerializer,
- nested=True,
- required=False,
- many=True
- )
- module = ModuleSerializer(
- nested=True,
- fields=('id', 'url', 'display', 'device', 'module_bay'),
- required=False,
- allow_null=True
- )
- type = ChoiceField(choices=InterfaceTypeChoices)
- parent = NestedInterfaceSerializer(required=False, allow_null=True)
- bridge = NestedInterfaceSerializer(required=False, allow_null=True)
- lag = NestedInterfaceSerializer(required=False, allow_null=True)
- mode = ChoiceField(choices=InterfaceModeChoices, required=False, allow_blank=True)
- duplex = ChoiceField(choices=InterfaceDuplexChoices, required=False, allow_blank=True, allow_null=True)
- rf_role = ChoiceField(choices=WirelessRoleChoices, required=False, allow_blank=True)
- rf_channel = ChoiceField(choices=WirelessChannelChoices, required=False, allow_blank=True)
- poe_mode = ChoiceField(choices=InterfacePoEModeChoices, required=False, allow_blank=True)
- poe_type = ChoiceField(choices=InterfacePoETypeChoices, required=False, allow_blank=True)
- untagged_vlan = VLANSerializer(nested=True, required=False, allow_null=True)
- tagged_vlans = SerializedPKRelatedField(
- queryset=VLAN.objects.all(),
- serializer=VLANSerializer,
- nested=True,
- required=False,
- many=True
- )
- qinq_svlan = VLANSerializer(nested=True, required=False, allow_null=True)
- vlan_translation_policy = VLANTranslationPolicySerializer(nested=True, required=False, allow_null=True)
- vrf = VRFSerializer(nested=True, required=False, allow_null=True)
- l2vpn_termination = L2VPNTerminationSerializer(nested=True, read_only=True, allow_null=True)
- wireless_link = NestedWirelessLinkSerializer(read_only=True, allow_null=True)
- wireless_lans = SerializedPKRelatedField(
- queryset=WirelessLAN.objects.all(),
- serializer=WirelessLANSerializer,
- nested=True,
- required=False,
- many=True
- )
- count_ipaddresses = serializers.IntegerField(read_only=True)
- count_fhrp_groups = serializers.IntegerField(read_only=True)
- # Maintains backward compatibility with NetBox <v4.2
- mac_address = serializers.CharField(allow_null=True, read_only=True)
- primary_mac_address = MACAddressSerializer(nested=True, required=False, allow_null=True)
- mac_addresses = MACAddressSerializer(many=True, nested=True, read_only=True, allow_null=True)
- wwn = serializers.CharField(required=False, default=None, allow_blank=True, allow_null=True)
- class Meta:
- model = Interface
- fields = [
- 'id', 'url', 'display_url', 'display', 'device', 'vdcs', 'module', 'name', 'label', 'type', 'enabled',
- 'parent', 'bridge', 'lag', 'mtu', 'mac_address', 'primary_mac_address', 'mac_addresses', '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', 'tagged_vlans', 'qinq_svlan',
- 'vlan_translation_policy', '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',
- ]
- brief_fields = ('id', 'url', 'display', 'device', 'name', 'description', 'cable', '_occupied')
- def validate(self, data):
- # Validate many-to-many VLAN assignments
- if not self.nested:
- 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, "
- f"or it must be global."
- })
- return super().validate(data)
- class RearPortSerializer(NetBoxModelSerializer, CabledObjectSerializer):
- device = DeviceSerializer(nested=True)
- module = ModuleSerializer(
- nested=True,
- fields=('id', 'url', 'display', 'device', 'module_bay'),
- required=False,
- allow_null=True
- )
- type = ChoiceField(choices=PortTypeChoices)
- class Meta:
- model = RearPort
- fields = [
- 'id', 'url', 'display_url', 'display', 'device', 'module', 'name', 'label', 'type', 'color', 'positions',
- 'description', 'mark_connected', 'cable', 'cable_end', 'link_peers', 'link_peers_type', 'tags',
- 'custom_fields', 'created', 'last_updated', '_occupied',
- ]
- brief_fields = ('id', 'url', 'display', 'device', 'name', 'description', 'cable', '_occupied')
- class FrontPortRearPortSerializer(WritableNestedSerializer):
- """
- NestedRearPortSerializer but with parent device omitted (since front and rear ports must belong to same device)
- """
- class Meta:
- model = RearPort
- fields = ['id', 'url', 'display_url', 'display', 'name', 'label', 'description']
- class FrontPortSerializer(NetBoxModelSerializer, CabledObjectSerializer):
- device = DeviceSerializer(nested=True)
- module = ModuleSerializer(
- nested=True,
- fields=('id', 'url', 'display', 'device', 'module_bay'),
- required=False,
- allow_null=True
- )
- type = ChoiceField(choices=PortTypeChoices)
- rear_port = FrontPortRearPortSerializer()
- class Meta:
- model = FrontPort
- fields = [
- 'id', 'url', 'display_url', 'display', 'device', 'module', 'name', 'label', 'type', 'color', 'rear_port',
- 'rear_port_position', 'description', 'mark_connected', 'cable', 'cable_end', 'link_peers',
- 'link_peers_type', 'tags', 'custom_fields', 'created', 'last_updated', '_occupied',
- ]
- brief_fields = ('id', 'url', 'display', 'device', 'name', 'description', 'cable', '_occupied')
- class ModuleBaySerializer(NetBoxModelSerializer):
- device = DeviceSerializer(nested=True)
- module = ModuleSerializer(
- nested=True,
- fields=('id', 'url', 'display'),
- required=False,
- allow_null=True,
- default=None
- )
- installed_module = ModuleSerializer(
- nested=True,
- fields=('id', 'url', 'display', 'serial', 'description'),
- required=False,
- allow_null=True
- )
- class Meta:
- model = ModuleBay
- fields = [
- 'id', 'url', 'display_url', 'display', 'device', 'module', 'name', 'installed_module', 'label', 'position',
- 'description', 'tags', 'custom_fields', 'created', 'last_updated',
- ]
- brief_fields = ('id', 'url', 'display', 'installed_module', 'name', 'description')
- class DeviceBaySerializer(NetBoxModelSerializer):
- device = DeviceSerializer(nested=True)
- installed_device = DeviceSerializer(nested=True, required=False, allow_null=True)
- class Meta:
- model = DeviceBay
- fields = [
- 'id', 'url', 'display_url', 'display', 'device', 'name', 'label', 'description', 'installed_device',
- 'tags', 'custom_fields', 'created', 'last_updated',
- ]
- brief_fields = ('id', 'url', 'display', 'device', 'name', 'description')
- class InventoryItemSerializer(NetBoxModelSerializer):
- device = DeviceSerializer(nested=True)
- parent = serializers.PrimaryKeyRelatedField(queryset=InventoryItem.objects.all(), allow_null=True, default=None)
- role = InventoryItemRoleSerializer(nested=True, required=False, allow_null=True)
- manufacturer = ManufacturerSerializer(nested=True, required=False, allow_null=True, default=None)
- component_type = ContentTypeField(
- queryset=ContentType.objects.filter(MODULAR_COMPONENT_MODELS),
- required=False,
- allow_null=True
- )
- component = serializers.SerializerMethodField(read_only=True, allow_null=True)
- _depth = serializers.IntegerField(source='level', read_only=True)
- status = ChoiceField(choices=InventoryItemStatusChoices, required=False)
- class Meta:
- model = InventoryItem
- fields = [
- 'id', 'url', 'display_url', 'display', 'device', 'parent', 'name', 'label', 'status', 'role', 'manufacturer',
- 'part_id', 'serial', 'asset_tag', 'discovered', 'description', 'component_type', 'component_id',
- 'component', 'tags', 'custom_fields', 'created', 'last_updated', '_depth',
- ]
- brief_fields = ('id', 'url', 'display', 'device', 'name', 'description', '_depth')
- @extend_schema_field(serializers.JSONField(allow_null=True))
- def get_component(self, obj):
- if obj.component is None:
- return None
- serializer = get_serializer_for_model(obj.component)
- context = {'request': self.context['request']}
- return serializer(obj.component, nested=True, context=context).data
|