Closes #2578: Reorganized nested serializers

This commit is contained in:
Jeremy Stretch 2018-11-12 11:36:44 -05:00
parent 04ae6ec7af
commit 75f0d8ee90
18 changed files with 788 additions and 801 deletions

View File

@ -49,6 +49,7 @@ NetBox now supports modeling physical cables for console, power, and interface c
* [#2572](https://github.com/digitalocean/netbox/issues/2572) - Add button to disconnect cable from circuit termination * [#2572](https://github.com/digitalocean/netbox/issues/2572) - Add button to disconnect cable from circuit termination
* [#2573](https://github.com/digitalocean/netbox/issues/2573) - Fix bulk console/power/interface disconnections * [#2573](https://github.com/digitalocean/netbox/issues/2573) - Fix bulk console/power/interface disconnections
* [#2574](https://github.com/digitalocean/netbox/issues/2574) - Remove duplicate interface links from topology maps * [#2574](https://github.com/digitalocean/netbox/issues/2574) - Remove duplicate interface links from topology maps
* [#2578](https://github.com/digitalocean/netbox/issues/2578) - Reorganized nested serializers
* [#2579](https://github.com/digitalocean/netbox/issues/2579) - Add missing cable disconnect buttons for front/rear ports * [#2579](https://github.com/digitalocean/netbox/issues/2579) - Add missing cable disconnect buttons for front/rear ports
## API Changes ## API Changes

View File

@ -0,0 +1,52 @@
from rest_framework import serializers
from circuits.models import Circuit, CircuitTermination, CircuitType, Provider
from utilities.api import WritableNestedSerializer
__all__ = [
'NestedCircuitSerializer',
'NestedCircuitTerminationSerializer',
'NestedCircuitTypeSerializer',
'NestedProviderSerializer',
]
#
# Providers
#
class NestedProviderSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:provider-detail')
class Meta:
model = Provider
fields = ['id', 'url', 'name', 'slug']
#
# Circuits
#
class NestedCircuitTypeSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuittype-detail')
class Meta:
model = CircuitType
fields = ['id', 'url', 'name', 'slug']
class NestedCircuitSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuit-detail')
class Meta:
model = Circuit
fields = ['id', 'url', 'cid']
class NestedCircuitTerminationSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuittermination-detail')
circuit = NestedCircuitSerializer()
class Meta:
model = CircuitTermination
fields = ['id', 'url', 'circuit', 'term_side']

View File

@ -1,12 +1,12 @@
from rest_framework import serializers
from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField
from circuits.constants import CIRCUIT_STATUS_CHOICES from circuits.constants import CIRCUIT_STATUS_CHOICES
from circuits.models import Provider, Circuit, CircuitTermination, CircuitType from circuits.models import Provider, Circuit, CircuitTermination, CircuitType
from dcim.api.serializers import NestedCableSerializer, NestedInterfaceSerializer, NestedSiteSerializer from dcim.api.nested_serializers import NestedCableSerializer, NestedInterfaceSerializer, NestedSiteSerializer
from extras.api.customfields import CustomFieldModelSerializer from extras.api.customfields import CustomFieldModelSerializer
from tenancy.api.serializers import NestedTenantSerializer from tenancy.api.nested_serializers import NestedTenantSerializer
from utilities.api import ChoiceField, ValidatedModelSerializer, WritableNestedSerializer from utilities.api import ChoiceField, ValidatedModelSerializer
from .nested_serializers import *
# #
@ -24,16 +24,8 @@ class ProviderSerializer(TaggitSerializer, CustomFieldModelSerializer):
] ]
class NestedProviderSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:provider-detail')
class Meta:
model = Provider
fields = ['id', 'url', 'name', 'slug']
# #
# Circuit types # Circuits
# #
class CircuitTypeSerializer(ValidatedModelSerializer): class CircuitTypeSerializer(ValidatedModelSerializer):
@ -43,18 +35,6 @@ class CircuitTypeSerializer(ValidatedModelSerializer):
fields = ['id', 'name', 'slug'] fields = ['id', 'name', 'slug']
class NestedCircuitTypeSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuittype-detail')
class Meta:
model = CircuitType
fields = ['id', 'url', 'name', 'slug']
#
# Circuits
#
class CircuitSerializer(TaggitSerializer, CustomFieldModelSerializer): class CircuitSerializer(TaggitSerializer, CustomFieldModelSerializer):
provider = NestedProviderSerializer() provider = NestedProviderSerializer()
status = ChoiceField(choices=CIRCUIT_STATUS_CHOICES, required=False) status = ChoiceField(choices=CIRCUIT_STATUS_CHOICES, required=False)
@ -70,18 +50,6 @@ class CircuitSerializer(TaggitSerializer, CustomFieldModelSerializer):
] ]
class NestedCircuitSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuit-detail')
class Meta:
model = Circuit
fields = ['id', 'url', 'cid']
#
# Circuit Terminations
#
class CircuitTerminationSerializer(ValidatedModelSerializer): class CircuitTerminationSerializer(ValidatedModelSerializer):
circuit = NestedCircuitSerializer() circuit = NestedCircuitSerializer()
site = NestedSiteSerializer() site = NestedSiteSerializer()
@ -94,12 +62,3 @@ class CircuitTerminationSerializer(ValidatedModelSerializer):
'id', 'circuit', 'term_side', 'site', 'port_speed', 'upstream_speed', 'xconnect_id', 'pp_info', 'id', 'circuit', 'term_side', 'site', 'port_speed', 'upstream_speed', 'xconnect_id', 'pp_info',
'description', 'connected_endpoint', 'cable', 'description', 'connected_endpoint', 'cable',
] ]
class NestedCircuitTerminationSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuittermination-detail')
circuit = NestedCircuitSerializer()
class Meta:
model = CircuitTermination
fields = ['id', 'url', 'circuit', 'term_side']

View File

@ -0,0 +1,243 @@
from rest_framework import serializers
from dcim.models import (
Cable, ConsolePort, ConsoleServerPort, Device, DeviceBay, DeviceType, DeviceRole, FrontPort, FrontPortTemplate,
Interface, Manufacturer, Platform, PowerOutlet, PowerPort, Rack, RackGroup, RackRole, RearPort, RearPortTemplate,
Region, Site, VirtualChassis,
)
from utilities.api import WritableNestedSerializer
__all__ = [
'NestedCableSerializer',
'NestedConsolePortSerializer',
'NestedConsoleServerPortSerializer',
'NestedDeviceBaySerializer',
'NestedDeviceRoleSerializer',
'NestedDeviceSerializer',
'NestedDeviceTypeSerializer',
'NestedFrontPortSerializer',
'NestedFrontPortTemplateSerializer',
'NestedInterfaceSerializer',
'NestedManufacturerSerializer',
'NestedPlatformSerializer',
'NestedPowerOutletSerializer',
'NestedPowerPortSerializer',
'NestedRackGroupSerializer',
'NestedRackRoleSerializer',
'NestedRackSerializer',
'NestedRearPortSerializer',
'NestedRearPortTemplateSerializer',
'NestedRegionSerializer',
'NestedSiteSerializer',
'NestedVirtualChassisSerializer',
]
#
# Regions/sites
#
class NestedRegionSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:region-detail')
class Meta:
model = Region
fields = ['id', 'url', 'name', 'slug']
class NestedSiteSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:site-detail')
class Meta:
model = Site
fields = ['id', 'url', 'name', 'slug']
#
# Racks
#
class NestedRackGroupSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackgroup-detail')
class Meta:
model = RackGroup
fields = ['id', 'url', 'name', 'slug']
class NestedRackRoleSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackrole-detail')
class Meta:
model = RackRole
fields = ['id', 'url', 'name', 'slug']
class NestedRackSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rack-detail')
class Meta:
model = Rack
fields = ['id', 'url', 'name', 'display_name']
#
# Device types
#
class NestedManufacturerSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:manufacturer-detail')
class Meta:
model = Manufacturer
fields = ['id', 'url', 'name', 'slug']
class NestedDeviceTypeSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicetype-detail')
manufacturer = NestedManufacturerSerializer(read_only=True)
class Meta:
model = DeviceType
fields = ['id', 'url', 'manufacturer', 'model', 'slug']
class NestedRearPortTemplateSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearporttemplate-detail')
class Meta:
model = RearPortTemplate
fields = ['id', 'url', 'name']
class NestedFrontPortTemplateSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:frontporttemplate-detail')
class Meta:
model = FrontPortTemplate
fields = ['id', 'url', 'name']
#
# Devices
#
class NestedDeviceRoleSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicerole-detail')
class Meta:
model = DeviceRole
fields = ['id', 'url', 'name', 'slug']
class NestedPlatformSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:platform-detail')
class Meta:
model = Platform
fields = ['id', 'url', 'name', 'slug']
class NestedDeviceSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:device-detail')
class Meta:
model = Device
fields = ['id', 'url', 'name', 'display_name']
class NestedConsoleServerPortSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverport-detail')
device = NestedDeviceSerializer(read_only=True)
class Meta:
model = ConsoleServerPort
fields = ['id', 'url', 'device', 'name', 'cable']
class NestedConsolePortSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleport-detail')
device = NestedDeviceSerializer(read_only=True)
class Meta:
model = ConsolePort
fields = ['id', 'url', 'device', 'name', 'cable']
class NestedPowerOutletSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:poweroutlet-detail')
device = NestedDeviceSerializer(read_only=True)
class Meta:
model = PowerOutlet
fields = ['id', 'url', 'device', 'name', 'cable']
class NestedPowerPortSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerport-detail')
device = NestedDeviceSerializer(read_only=True)
class Meta:
model = PowerPort
fields = ['id', 'url', 'device', 'name', 'cable']
class NestedInterfaceSerializer(WritableNestedSerializer):
device = NestedDeviceSerializer(read_only=True)
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail')
class Meta:
model = Interface
fields = ['id', 'url', 'device', 'name', 'cable']
class NestedRearPortSerializer(WritableNestedSerializer):
device = NestedDeviceSerializer(read_only=True)
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearport-detail')
class Meta:
model = RearPort
fields = ['id', 'url', 'device', 'name', 'cable']
class NestedFrontPortSerializer(WritableNestedSerializer):
device = NestedDeviceSerializer(read_only=True)
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:frontport-detail')
class Meta:
model = FrontPort
fields = ['id', 'url', 'device', 'name', 'cable']
class NestedDeviceBaySerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearport-detail')
device = NestedDeviceSerializer(read_only=True)
class Meta:
model = DeviceBay
fields = ['id', 'url', 'device', 'name']
#
# Cables
#
class NestedCableSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:cable-detail')
class Meta:
model = Cable
fields = ['id', 'url', 'label']
#
# Virtual chassis
#
class NestedVirtualChassisSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:virtualchassis-detail')
master = NestedDeviceSerializer()
class Meta:
model = VirtualChassis
fields = ['id', 'url', 'master']

View File

@ -2,7 +2,6 @@ from rest_framework import serializers
from rest_framework.validators import UniqueTogetherValidator from rest_framework.validators import UniqueTogetherValidator
from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField
from circuits.models import Circuit, CircuitTermination
from dcim.constants import * from dcim.constants import *
from dcim.models import ( from dcim.models import (
Cable, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay, Cable, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
@ -11,28 +10,22 @@ from dcim.models import (
RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site, VirtualChassis, RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site, VirtualChassis,
) )
from extras.api.customfields import CustomFieldModelSerializer from extras.api.customfields import CustomFieldModelSerializer
from ipam.models import IPAddress, VLAN from ipam.api.nested_serializers import NestedIPAddressSerializer, NestedVLANSerializer
from tenancy.api.serializers import NestedTenantSerializer from ipam.models import VLAN
from users.api.serializers import NestedUserSerializer from tenancy.api.nested_serializers import NestedTenantSerializer
from users.api.nested_serializers import NestedUserSerializer
from utilities.api import ( from utilities.api import (
ChoiceField, ContentTypeField, SerializedPKRelatedField, TimeZoneField, ValidatedModelSerializer, ChoiceField, ContentTypeField, SerializedPKRelatedField, TimeZoneField, ValidatedModelSerializer,
WritableNestedSerializer, get_serializer_for_model, WritableNestedSerializer, get_serializer_for_model,
) )
from virtualization.models import Cluster from virtualization.api.nested_serializers import NestedClusterSerializer
from .nested_serializers import *
# #
# Regions # Regions/sites
# #
class NestedRegionSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:region-detail')
class Meta:
model = Region
fields = ['id', 'url', 'name', 'slug']
class RegionSerializer(serializers.ModelSerializer): class RegionSerializer(serializers.ModelSerializer):
parent = NestedRegionSerializer(required=False, allow_null=True) parent = NestedRegionSerializer(required=False, allow_null=True)
@ -41,10 +34,6 @@ class RegionSerializer(serializers.ModelSerializer):
fields = ['id', 'name', 'slug', 'parent'] fields = ['id', 'name', 'slug', 'parent']
#
# Sites
#
class SiteSerializer(TaggitSerializer, CustomFieldModelSerializer): class SiteSerializer(TaggitSerializer, CustomFieldModelSerializer):
status = ChoiceField(choices=SITE_STATUS_CHOICES, required=False) status = ChoiceField(choices=SITE_STATUS_CHOICES, required=False)
region = NestedRegionSerializer(required=False, allow_null=True) region = NestedRegionSerializer(required=False, allow_null=True)
@ -62,16 +51,8 @@ class SiteSerializer(TaggitSerializer, CustomFieldModelSerializer):
] ]
class NestedSiteSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:site-detail')
class Meta:
model = Site
fields = ['id', 'url', 'name', 'slug']
# #
# Rack groups # Racks
# #
class RackGroupSerializer(ValidatedModelSerializer): class RackGroupSerializer(ValidatedModelSerializer):
@ -82,18 +63,6 @@ class RackGroupSerializer(ValidatedModelSerializer):
fields = ['id', 'name', 'slug', 'site'] fields = ['id', 'name', 'slug', 'site']
class NestedRackGroupSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackgroup-detail')
class Meta:
model = RackGroup
fields = ['id', 'url', 'name', 'slug']
#
# Rack roles
#
class RackRoleSerializer(ValidatedModelSerializer): class RackRoleSerializer(ValidatedModelSerializer):
class Meta: class Meta:
@ -101,18 +70,6 @@ class RackRoleSerializer(ValidatedModelSerializer):
fields = ['id', 'name', 'slug', 'color'] fields = ['id', 'name', 'slug', 'color']
class NestedRackRoleSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackrole-detail')
class Meta:
model = RackRole
fields = ['id', 'url', 'name', 'slug']
#
# Racks
#
class RackSerializer(TaggitSerializer, CustomFieldModelSerializer): class RackSerializer(TaggitSerializer, CustomFieldModelSerializer):
site = NestedSiteSerializer() site = NestedSiteSerializer()
group = NestedRackGroupSerializer(required=False, allow_null=True, default=None) group = NestedRackGroupSerializer(required=False, allow_null=True, default=None)
@ -151,26 +108,6 @@ class RackSerializer(TaggitSerializer, CustomFieldModelSerializer):
return data return data
class NestedRackSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rack-detail')
class Meta:
model = Rack
fields = ['id', 'url', 'name', 'display_name']
#
# Rack units
#
class NestedDeviceSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:device-detail')
class Meta:
model = Device
fields = ['id', 'url', 'name', 'display_name']
class RackUnitSerializer(serializers.Serializer): 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. A rack unit is an abstraction formed by the set (rack, position, face); it does not exist as a row in the database.
@ -181,10 +118,6 @@ class RackUnitSerializer(serializers.Serializer):
device = NestedDeviceSerializer(read_only=True) device = NestedDeviceSerializer(read_only=True)
#
# Rack reservations
#
class RackReservationSerializer(ValidatedModelSerializer): class RackReservationSerializer(ValidatedModelSerializer):
rack = NestedRackSerializer() rack = NestedRackSerializer()
user = NestedUserSerializer() user = NestedUserSerializer()
@ -196,7 +129,7 @@ class RackReservationSerializer(ValidatedModelSerializer):
# #
# Manufacturers # Device types
# #
class ManufacturerSerializer(ValidatedModelSerializer): class ManufacturerSerializer(ValidatedModelSerializer):
@ -206,18 +139,6 @@ class ManufacturerSerializer(ValidatedModelSerializer):
fields = ['id', 'name', 'slug'] fields = ['id', 'name', 'slug']
class NestedManufacturerSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:manufacturer-detail')
class Meta:
model = Manufacturer
fields = ['id', 'url', 'name', 'slug']
#
# Device types
#
class DeviceTypeSerializer(TaggitSerializer, CustomFieldModelSerializer): class DeviceTypeSerializer(TaggitSerializer, CustomFieldModelSerializer):
manufacturer = NestedManufacturerSerializer() manufacturer = NestedManufacturerSerializer()
subdevice_role = ChoiceField(choices=SUBDEVICE_ROLE_CHOICES, required=False, allow_null=True) subdevice_role = ChoiceField(choices=SUBDEVICE_ROLE_CHOICES, required=False, allow_null=True)
@ -232,19 +153,6 @@ class DeviceTypeSerializer(TaggitSerializer, CustomFieldModelSerializer):
] ]
class NestedDeviceTypeSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicetype-detail')
manufacturer = NestedManufacturerSerializer(read_only=True)
class Meta:
model = DeviceType
fields = ['id', 'url', 'manufacturer', 'model', 'slug']
#
# Console port templates
#
class ConsolePortTemplateSerializer(ValidatedModelSerializer): class ConsolePortTemplateSerializer(ValidatedModelSerializer):
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer()
@ -253,10 +161,6 @@ class ConsolePortTemplateSerializer(ValidatedModelSerializer):
fields = ['id', 'device_type', 'name'] fields = ['id', 'device_type', 'name']
#
# Console server port templates
#
class ConsoleServerPortTemplateSerializer(ValidatedModelSerializer): class ConsoleServerPortTemplateSerializer(ValidatedModelSerializer):
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer()
@ -265,10 +169,6 @@ class ConsoleServerPortTemplateSerializer(ValidatedModelSerializer):
fields = ['id', 'device_type', 'name'] fields = ['id', 'device_type', 'name']
#
# Power port templates
#
class PowerPortTemplateSerializer(ValidatedModelSerializer): class PowerPortTemplateSerializer(ValidatedModelSerializer):
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer()
@ -277,10 +177,6 @@ class PowerPortTemplateSerializer(ValidatedModelSerializer):
fields = ['id', 'device_type', 'name'] fields = ['id', 'device_type', 'name']
#
# Power outlet templates
#
class PowerOutletTemplateSerializer(ValidatedModelSerializer): class PowerOutletTemplateSerializer(ValidatedModelSerializer):
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer()
@ -289,10 +185,6 @@ class PowerOutletTemplateSerializer(ValidatedModelSerializer):
fields = ['id', 'device_type', 'name'] fields = ['id', 'device_type', 'name']
#
# Interface templates
#
class InterfaceTemplateSerializer(ValidatedModelSerializer): class InterfaceTemplateSerializer(ValidatedModelSerializer):
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer()
form_factor = ChoiceField(choices=IFACE_FF_CHOICES, required=False) form_factor = ChoiceField(choices=IFACE_FF_CHOICES, required=False)
@ -302,10 +194,6 @@ class InterfaceTemplateSerializer(ValidatedModelSerializer):
fields = ['id', 'device_type', 'name', 'form_factor', 'mgmt_only'] fields = ['id', 'device_type', 'name', 'form_factor', 'mgmt_only']
#
# Rear port templates
#
class RearPortTemplateSerializer(ValidatedModelSerializer): class RearPortTemplateSerializer(ValidatedModelSerializer):
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer()
type = ChoiceField(choices=PORT_TYPE_CHOICES) type = ChoiceField(choices=PORT_TYPE_CHOICES)
@ -315,18 +203,6 @@ class RearPortTemplateSerializer(ValidatedModelSerializer):
fields = ['id', 'device_type', 'name', 'type', 'positions'] fields = ['id', 'device_type', 'name', 'type', 'positions']
class NestedRearPortTemplateSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearporttemplate-detail')
class Meta:
model = RearPortTemplate
fields = ['id', 'url', 'name']
#
# Front port templates
#
class FrontPortTemplateSerializer(ValidatedModelSerializer): class FrontPortTemplateSerializer(ValidatedModelSerializer):
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer()
type = ChoiceField(choices=PORT_TYPE_CHOICES) type = ChoiceField(choices=PORT_TYPE_CHOICES)
@ -337,18 +213,6 @@ class FrontPortTemplateSerializer(ValidatedModelSerializer):
fields = ['id', 'device_type', 'name', 'type', 'rear_port', 'rear_port_position'] fields = ['id', 'device_type', 'name', 'type', 'rear_port', 'rear_port_position']
class NestedFrontPortTemplateSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:frontporttemplate-detail')
class Meta:
model = FrontPortTemplate
fields = ['id', 'url', 'name']
#
# Device bay templates
#
class DeviceBayTemplateSerializer(ValidatedModelSerializer): class DeviceBayTemplateSerializer(ValidatedModelSerializer):
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer()
@ -358,7 +222,7 @@ class DeviceBayTemplateSerializer(ValidatedModelSerializer):
# #
# Device roles # Devices
# #
class DeviceRoleSerializer(ValidatedModelSerializer): class DeviceRoleSerializer(ValidatedModelSerializer):
@ -368,18 +232,6 @@ class DeviceRoleSerializer(ValidatedModelSerializer):
fields = ['id', 'name', 'slug', 'color', 'vm_role'] fields = ['id', 'name', 'slug', 'color', 'vm_role']
class NestedDeviceRoleSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicerole-detail')
class Meta:
model = DeviceRole
fields = ['id', 'url', 'name', 'slug']
#
# Platforms
#
class PlatformSerializer(ValidatedModelSerializer): class PlatformSerializer(ValidatedModelSerializer):
manufacturer = NestedManufacturerSerializer(required=False, allow_null=True) manufacturer = NestedManufacturerSerializer(required=False, allow_null=True)
@ -388,46 +240,6 @@ class PlatformSerializer(ValidatedModelSerializer):
fields = ['id', 'name', 'slug', 'manufacturer', 'napalm_driver', 'napalm_args'] fields = ['id', 'name', 'slug', 'manufacturer', 'napalm_driver', 'napalm_args']
class NestedPlatformSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:platform-detail')
class Meta:
model = Platform
fields = ['id', 'url', 'name', 'slug']
#
# Devices
#
# Cannot import ipam.api.NestedIPAddressSerializer due to circular dependency
class DeviceIPAddressSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:ipaddress-detail')
class Meta:
model = IPAddress
fields = ['id', 'url', 'family', 'address']
# Cannot import virtualization.api.NestedClusterSerializer due to circular dependency
class NestedClusterSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:cluster-detail')
class Meta:
model = Cluster
fields = ['id', 'url', 'name']
# Cannot import NestedVirtualChassisSerializer due to circular dependency
class DeviceVirtualChassisSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:virtualchassis-detail')
master = NestedDeviceSerializer()
class Meta:
model = VirtualChassis
fields = ['id', 'url', 'master']
class DeviceSerializer(TaggitSerializer, CustomFieldModelSerializer): class DeviceSerializer(TaggitSerializer, CustomFieldModelSerializer):
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer()
device_role = NestedDeviceRoleSerializer() device_role = NestedDeviceRoleSerializer()
@ -437,12 +249,12 @@ class DeviceSerializer(TaggitSerializer, CustomFieldModelSerializer):
rack = NestedRackSerializer(required=False, allow_null=True) rack = NestedRackSerializer(required=False, allow_null=True)
face = ChoiceField(choices=RACK_FACE_CHOICES, required=False, allow_null=True) face = ChoiceField(choices=RACK_FACE_CHOICES, required=False, allow_null=True)
status = ChoiceField(choices=DEVICE_STATUS_CHOICES, required=False) status = ChoiceField(choices=DEVICE_STATUS_CHOICES, required=False)
primary_ip = DeviceIPAddressSerializer(read_only=True) primary_ip = NestedIPAddressSerializer(read_only=True)
primary_ip4 = DeviceIPAddressSerializer(required=False, allow_null=True) primary_ip4 = NestedIPAddressSerializer(required=False, allow_null=True)
primary_ip6 = DeviceIPAddressSerializer(required=False, allow_null=True) primary_ip6 = NestedIPAddressSerializer(required=False, allow_null=True)
parent_device = serializers.SerializerMethodField() parent_device = serializers.SerializerMethodField()
cluster = NestedClusterSerializer(required=False, allow_null=True) cluster = NestedClusterSerializer(required=False, allow_null=True)
virtual_chassis = DeviceVirtualChassisSerializer(required=False, allow_null=True) virtual_chassis = NestedVirtualChassisSerializer(required=False, allow_null=True)
tags = TagListSerializerField(required=False) tags = TagListSerializerField(required=False)
class Meta: class Meta:
@ -450,8 +262,8 @@ class DeviceSerializer(TaggitSerializer, CustomFieldModelSerializer):
fields = [ fields = [
'id', 'name', 'display_name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag', 'id', 'name', 'display_name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag',
'site', 'rack', 'position', 'face', 'parent_device', 'status', 'primary_ip', 'primary_ip4', 'primary_ip6', 'site', 'rack', 'position', 'face', 'parent_device', 'status', 'primary_ip', 'primary_ip4', 'primary_ip6',
'cluster', 'virtual_chassis', 'vc_position', 'vc_priority', 'comments', 'tags', 'custom_fields', 'created', 'cluster', 'virtual_chassis', 'vc_position', 'vc_priority', 'comments', 'local_context_data', 'tags',
'last_updated', 'local_context_data', 'custom_fields', 'created', 'last_updated',
] ]
validators = [] validators = []
@ -486,14 +298,178 @@ class DeviceWithConfigContextSerializer(DeviceSerializer):
fields = [ fields = [
'id', 'name', 'display_name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag', 'id', 'name', 'display_name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag',
'site', 'rack', 'position', 'face', 'parent_device', 'status', 'primary_ip', 'primary_ip4', 'primary_ip6', 'site', 'rack', 'position', 'face', 'parent_device', 'status', 'primary_ip', 'primary_ip4', 'primary_ip6',
'cluster', 'virtual_chassis', 'vc_position', 'vc_priority', 'comments', 'tags', 'custom_fields', 'cluster', 'virtual_chassis', 'vc_position', 'vc_priority', 'comments', 'local_context_data', 'tags',
'config_context', 'created', 'last_updated', 'local_context_data', 'custom_fields', 'config_context', 'created', 'last_updated',
] ]
def get_config_context(self, obj): def get_config_context(self, obj):
return obj.get_config_context() return obj.get_config_context()
class ConsoleServerPortSerializer(TaggitSerializer, ValidatedModelSerializer):
device = NestedDeviceSerializer()
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
class Meta:
model = ConsoleServerPort
fields = ['id', 'device', 'name', 'connected_endpoint', 'cable', 'tags']
read_only_fields = ['connected_endpoint']
class ConsolePortSerializer(TaggitSerializer, ValidatedModelSerializer):
device = NestedDeviceSerializer()
connected_endpoint = NestedConsoleServerPortSerializer(read_only=True)
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
class Meta:
model = ConsolePort
fields = ['id', 'device', 'name', 'connected_endpoint', 'connection_status', 'cable', 'tags']
class PowerOutletSerializer(TaggitSerializer, ValidatedModelSerializer):
device = NestedDeviceSerializer()
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
class Meta:
model = PowerOutlet
fields = ['id', 'device', 'name', 'connected_endpoint', 'cable', 'tags']
read_only_fields = ['connected_endpoint']
class PowerPortSerializer(TaggitSerializer, ValidatedModelSerializer):
device = NestedDeviceSerializer()
connected_endpoint = NestedPowerOutletSerializer(read_only=True)
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
class Meta:
model = PowerPort
fields = ['id', 'device', 'name', 'connected_endpoint', 'connection_status', 'cable', 'tags']
class InterfaceSerializer(TaggitSerializer, ValidatedModelSerializer):
device = NestedDeviceSerializer()
form_factor = ChoiceField(choices=IFACE_FF_CHOICES, required=False)
lag = NestedInterfaceSerializer(required=False, allow_null=True)
connected_endpoint = serializers.SerializerMethodField(read_only=True)
mode = ChoiceField(choices=IFACE_MODE_CHOICES, required=False, allow_null=True)
untagged_vlan = NestedVLANSerializer(required=False, allow_null=True)
tagged_vlans = SerializedPKRelatedField(
queryset=VLAN.objects.all(),
serializer=NestedVLANSerializer,
required=False,
many=True
)
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
class Meta:
model = Interface
fields = [
'id', 'device', 'name', 'form_factor', 'enabled', 'lag', 'mtu', 'mac_address', 'mgmt_only', 'description',
'connected_endpoint', 'cable', 'mode', 'untagged_vlan', 'tagged_vlans', 'tags', 'count_ipaddresses',
]
# TODO: This validation should be handled by Interface.clean()
def validate(self, data):
# All associated VLANs be global or assigned to the parent device's site.
device = self.instance.device if self.instance else data.get('device')
untagged_vlan = data.get('untagged_vlan')
if untagged_vlan and untagged_vlan.site not in [device.site, None]:
raise serializers.ValidationError({
'untagged_vlan': "VLAN {} must belong to the same site as the interface's parent device, or it must be "
"global.".format(untagged_vlan)
})
for vlan in data.get('tagged_vlans', []):
if vlan.site not in [device.site, None]:
raise serializers.ValidationError({
'tagged_vlans': "VLAN {} must belong to the same site as the interface's parent device, or it must "
"be global.".format(vlan)
})
return super(InterfaceSerializer, self).validate(data)
def get_connected_endpoint(self, obj):
"""
Return the appropriate serializer for the type of connected object.
"""
if obj.connected_endpoint is None:
return None
serializer = get_serializer_for_model(obj.connected_endpoint, prefix='Nested')
context = {'request': self.context['request']}
data = serializer(obj.connected_endpoint, context=context).data
return data
class RearPortSerializer(ValidatedModelSerializer):
device = NestedDeviceSerializer()
type = ChoiceField(choices=PORT_TYPE_CHOICES)
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
class Meta:
model = RearPort
fields = ['id', 'device', 'name', 'type', 'positions', 'cable', 'tags']
class FrontPortRearPortSerializer(WritableNestedSerializer):
"""
NestedRearPortSerializer but with parent device omitted (since front and rear ports must belong to same device)
"""
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearport-detail')
class Meta:
model = RearPort
fields = ['id', 'url', 'name']
class FrontPortSerializer(ValidatedModelSerializer):
device = NestedDeviceSerializer()
type = ChoiceField(choices=PORT_TYPE_CHOICES)
rear_port = FrontPortRearPortSerializer()
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
class Meta:
model = FrontPort
fields = ['id', 'device', 'name', 'type', 'rear_port', 'rear_port_position', 'cable', 'tags']
class DeviceBaySerializer(TaggitSerializer, ValidatedModelSerializer):
device = NestedDeviceSerializer()
installed_device = NestedDeviceSerializer(required=False, allow_null=True)
tags = TagListSerializerField(required=False)
class Meta:
model = DeviceBay
fields = ['id', 'device', 'name', 'installed_device', 'tags']
#
# Inventory items
#
class InventoryItemSerializer(TaggitSerializer, ValidatedModelSerializer):
device = NestedDeviceSerializer()
# Provide a default value to satisfy UniqueTogetherValidator
parent = serializers.PrimaryKeyRelatedField(queryset=InventoryItem.objects.all(), allow_null=True, default=None)
manufacturer = NestedManufacturerSerializer(required=False, allow_null=True, default=None)
tags = TagListSerializerField(required=False)
class Meta:
model = InventoryItem
fields = [
'id', 'device', 'parent', 'name', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'discovered',
'description', 'tags',
]
# #
# Cables # Cables
# #
@ -548,305 +524,6 @@ class TracedCableSerializer(serializers.ModelSerializer):
] ]
class NestedCableSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:cable-detail')
class Meta:
model = Cable
fields = ['id', 'url', 'label']
#
# Console server ports
#
class ConsoleServerPortSerializer(TaggitSerializer, ValidatedModelSerializer):
device = NestedDeviceSerializer()
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
class Meta:
model = ConsoleServerPort
fields = ['id', 'device', 'name', 'connected_endpoint', 'cable', 'tags']
read_only_fields = ['connected_endpoint']
class NestedConsoleServerPortSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverport-detail')
device = NestedDeviceSerializer(read_only=True)
class Meta:
model = ConsoleServerPort
fields = ['id', 'url', 'device', 'name', 'cable']
#
# Console ports
#
class ConsolePortSerializer(TaggitSerializer, ValidatedModelSerializer):
device = NestedDeviceSerializer()
connected_endpoint = NestedConsoleServerPortSerializer(read_only=True)
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
class Meta:
model = ConsolePort
fields = ['id', 'device', 'name', 'connected_endpoint', 'connection_status', 'cable', 'tags']
class NestedConsolePortSerializer(TaggitSerializer, ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleport-detail')
device = NestedDeviceSerializer(read_only=True)
class Meta:
model = ConsolePort
fields = ['id', 'url', 'device', 'name', 'cable']
#
# Power outlets
#
class PowerOutletSerializer(TaggitSerializer, ValidatedModelSerializer):
device = NestedDeviceSerializer()
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
class Meta:
model = PowerOutlet
fields = ['id', 'device', 'name', 'connected_endpoint', 'cable', 'tags']
read_only_fields = ['connected_endpoint']
class NestedPowerOutletSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:poweroutlet-detail')
device = NestedDeviceSerializer(read_only=True)
class Meta:
model = PowerOutlet
fields = ['id', 'url', 'device', 'name', 'cable']
#
# Power ports
#
class PowerPortSerializer(TaggitSerializer, ValidatedModelSerializer):
device = NestedDeviceSerializer()
connected_endpoint = NestedPowerOutletSerializer(read_only=True)
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
class Meta:
model = PowerPort
fields = ['id', 'device', 'name', 'connected_endpoint', 'connection_status', 'cable', 'tags']
class NestedPowerPortSerializer(TaggitSerializer, ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerport-detail')
device = NestedDeviceSerializer(read_only=True)
class Meta:
model = PowerPort
fields = ['id', 'url', 'device', 'name', 'cable']
#
# Interfaces
#
class NestedInterfaceSerializer(WritableNestedSerializer):
device = NestedDeviceSerializer(read_only=True)
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail')
class Meta:
model = Interface
fields = ['id', 'url', 'device', 'name', 'cable']
class InterfaceNestedCircuitSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuit-detail')
class Meta:
model = Circuit
fields = ['id', 'url', 'cid']
class InterfaceCircuitTerminationSerializer(WritableNestedSerializer):
circuit = InterfaceNestedCircuitSerializer(read_only=True)
class Meta:
model = CircuitTermination
fields = [
'id', 'circuit', 'term_side', 'port_speed', 'upstream_speed', 'xconnect_id', 'pp_info',
]
# Cannot import ipam.api.NestedVLANSerializer due to circular dependency
class InterfaceVLANSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlan-detail')
class Meta:
model = VLAN
fields = ['id', 'url', 'vid', 'name', 'display_name']
class InterfaceSerializer(TaggitSerializer, ValidatedModelSerializer):
device = NestedDeviceSerializer()
form_factor = ChoiceField(choices=IFACE_FF_CHOICES, required=False)
lag = NestedInterfaceSerializer(required=False, allow_null=True)
connected_endpoint = serializers.SerializerMethodField(read_only=True)
mode = ChoiceField(choices=IFACE_MODE_CHOICES, required=False, allow_null=True)
untagged_vlan = InterfaceVLANSerializer(required=False, allow_null=True)
tagged_vlans = SerializedPKRelatedField(
queryset=VLAN.objects.all(),
serializer=InterfaceVLANSerializer,
required=False,
many=True
)
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
class Meta:
model = Interface
fields = [
'id', 'device', 'name', 'form_factor', 'enabled', 'lag', 'mtu', 'mac_address', 'mgmt_only', 'description',
'connected_endpoint', 'cable', 'mode', 'untagged_vlan', 'tagged_vlans', 'tags', 'count_ipaddresses',
]
def validate(self, data):
# All associated VLANs be global or assigned to the parent device's site.
device = self.instance.device if self.instance else data.get('device')
untagged_vlan = data.get('untagged_vlan')
if untagged_vlan and untagged_vlan.site not in [device.site, None]:
raise serializers.ValidationError({
'untagged_vlan': "VLAN {} must belong to the same site as the interface's parent device, or it must be "
"global.".format(untagged_vlan)
})
for vlan in data.get('tagged_vlans', []):
if vlan.site not in [device.site, None]:
raise serializers.ValidationError({
'tagged_vlans': "VLAN {} must belong to the same site as the interface's parent device, or it must "
"be global.".format(vlan)
})
return super(InterfaceSerializer, self).validate(data)
def get_connected_endpoint(self, obj):
"""
Return the appropriate serializer for the type of connected object.
"""
if obj.connected_endpoint is None:
return None
serializer = get_serializer_for_model(obj.connected_endpoint, prefix='Nested')
context = {'request': self.context['request']}
data = serializer(obj.connected_endpoint, context=context).data
return data
#
# Rear ports
#
class RearPortSerializer(ValidatedModelSerializer):
device = NestedDeviceSerializer()
type = ChoiceField(choices=PORT_TYPE_CHOICES)
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
class Meta:
model = RearPort
fields = ['id', 'device', 'name', 'type', 'positions', 'cable', 'tags']
class NestedRearPortSerializer(WritableNestedSerializer):
device = NestedDeviceSerializer(read_only=True)
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearport-detail')
class Meta:
model = RearPort
fields = ['id', 'url', 'device', 'name', 'cable']
#
# Front ports
#
class FrontPortRearPortSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearport-detail')
class Meta:
model = RearPort
fields = ['id', 'url', 'name']
class FrontPortSerializer(ValidatedModelSerializer):
device = NestedDeviceSerializer()
type = ChoiceField(choices=PORT_TYPE_CHOICES)
rear_port = FrontPortRearPortSerializer()
cable = NestedCableSerializer(read_only=True)
tags = TagListSerializerField(required=False)
class Meta:
model = FrontPort
fields = ['id', 'device', 'name', 'type', 'rear_port', 'rear_port_position', 'cable', 'tags']
class NestedFrontPortSerializer(WritableNestedSerializer):
device = NestedDeviceSerializer(read_only=True)
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:frontport-detail')
class Meta:
model = FrontPort
fields = ['id', 'url', 'device', 'name', 'cable']
#
# Device bays
#
class DeviceBaySerializer(TaggitSerializer, ValidatedModelSerializer):
device = NestedDeviceSerializer()
installed_device = NestedDeviceSerializer(required=False, allow_null=True)
tags = TagListSerializerField(required=False)
class Meta:
model = DeviceBay
fields = ['id', 'device', 'name', 'installed_device', 'tags']
class NestedDeviceBaySerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearport-detail')
device = NestedDeviceSerializer(read_only=True)
class Meta:
model = DeviceBay
fields = ['id', 'url', 'device', 'name']
#
# Inventory items
#
class InventoryItemSerializer(TaggitSerializer, ValidatedModelSerializer):
device = NestedDeviceSerializer()
# Provide a default value to satisfy UniqueTogetherValidator
parent = serializers.PrimaryKeyRelatedField(queryset=InventoryItem.objects.all(), allow_null=True, default=None)
manufacturer = NestedManufacturerSerializer(required=False, allow_null=True, default=None)
tags = TagListSerializerField(required=False)
class Meta:
model = InventoryItem
fields = [
'id', 'device', 'parent', 'name', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'discovered',
'description', 'tags',
]
# #
# Interface connections # Interface connections
# #
@ -876,11 +553,3 @@ class VirtualChassisSerializer(TaggitSerializer, ValidatedModelSerializer):
class Meta: class Meta:
model = VirtualChassis model = VirtualChassis
fields = ['id', 'master', 'domain', 'tags'] fields = ['id', 'master', 'domain', 'tags']
class NestedVirtualChassisSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:virtualchassis-detail')
class Meta:
model = VirtualChassis
fields = ['id', 'url']

View File

@ -3433,7 +3433,7 @@ class VirtualChassisTest(APITestCase):
self.assertEqual( self.assertEqual(
sorted(response.data['results'][0]), sorted(response.data['results'][0]),
['id', 'url'] ['id', 'master', 'url']
) )
def test_create_virtualchassis(self): def test_create_virtualchassis(self):

View File

@ -0,0 +1,23 @@
from rest_framework import serializers
from extras.models import ReportResult
__all__ = [
'NestedReportResultSerializer',
]
#
# Reports
#
class NestedReportResultSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(
view_name='extras-api:report-detail',
lookup_field='report',
lookup_url_kwarg='pk'
)
class Meta:
model = ReportResult
fields = ['url', 'created', 'user', 'failed']

View File

@ -2,7 +2,7 @@ from django.core.exceptions import ObjectDoesNotExist
from rest_framework import serializers from rest_framework import serializers
from taggit.models import Tag from taggit.models import Tag
from dcim.api.serializers import ( from dcim.api.nested_serializers import (
NestedDeviceSerializer, NestedDeviceRoleSerializer, NestedPlatformSerializer, NestedRackSerializer, NestedDeviceSerializer, NestedDeviceRoleSerializer, NestedPlatformSerializer, NestedRackSerializer,
NestedRegionSerializer, NestedSiteSerializer, NestedRegionSerializer, NestedSiteSerializer,
) )
@ -11,12 +11,13 @@ from extras.constants import *
from extras.models import ( from extras.models import (
ConfigContext, ExportTemplate, Graph, ImageAttachment, ObjectChange, ReportResult, TopologyMap, ConfigContext, ExportTemplate, Graph, ImageAttachment, ObjectChange, ReportResult, TopologyMap,
) )
from tenancy.api.serializers import NestedTenantSerializer, NestedTenantGroupSerializer from tenancy.api.nested_serializers import NestedTenantSerializer, NestedTenantGroupSerializer
from tenancy.models import Tenant, TenantGroup from tenancy.models import Tenant, TenantGroup
from users.api.serializers import NestedUserSerializer from users.api.nested_serializers import NestedUserSerializer
from utilities.api import ( from utilities.api import (
ChoiceField, ContentTypeField, get_serializer_for_model, SerializedPKRelatedField, ValidatedModelSerializer, ChoiceField, ContentTypeField, get_serializer_for_model, SerializedPKRelatedField, ValidatedModelSerializer,
) )
from .nested_serializers import *
# #
@ -187,18 +188,6 @@ class ReportResultSerializer(serializers.ModelSerializer):
fields = ['created', 'user', 'failed', 'data'] fields = ['created', 'user', 'failed', 'data']
class NestedReportResultSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(
view_name='extras-api:report-detail',
lookup_field='report',
lookup_url_kwarg='pk'
)
class Meta:
model = ReportResult
fields = ['url', 'created', 'user', 'failed']
class ReportSerializer(serializers.Serializer): class ReportSerializer(serializers.Serializer):
module = serializers.CharField(max_length=255) module = serializers.CharField(max_length=255)
name = serializers.CharField(max_length=255) name = serializers.CharField(max_length=255)

View File

@ -0,0 +1,100 @@
from rest_framework import serializers
from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, VLAN, VLANGroup, VRF
from utilities.api import WritableNestedSerializer
__all__ = [
'NestedAggregateSerializer',
'NestedIPAddressSerializer',
'NestedPrefixSerializer',
'NestedRIRSerializer',
'NestedRoleSerializer',
'NestedVLANGroupSerializer',
'NestedVLANSerializer',
'NestedVRFSerializer',
]
#
# VRFs
#
class NestedVRFSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vrf-detail')
class Meta:
model = VRF
fields = ['id', 'url', 'name', 'rd']
#
# RIRs/aggregates
#
class NestedRIRSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:rir-detail')
class Meta:
model = RIR
fields = ['id', 'url', 'name', 'slug']
class NestedAggregateSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:aggregate-detail')
class Meta:
model = Aggregate
fields = ['id', 'url', 'family', 'prefix']
#
# VLANs
#
class NestedRoleSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:role-detail')
class Meta:
model = Role
fields = ['id', 'url', 'name', 'slug']
class NestedVLANGroupSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlangroup-detail')
class Meta:
model = VLANGroup
fields = ['id', 'url', 'name', 'slug']
class NestedVLANSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlan-detail')
class Meta:
model = VLAN
fields = ['id', 'url', 'vid', 'name', 'display_name']
#
# Prefixes
#
class NestedPrefixSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:prefix-detail')
class Meta:
model = Prefix
fields = ['id', 'url', 'family', 'prefix']
#
# IP addresses
#
class NestedIPAddressSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:ipaddress-detail')
class Meta:
model = IPAddress
fields = ['id', 'url', 'family', 'address']

View File

@ -5,18 +5,17 @@ from rest_framework.reverse import reverse
from rest_framework.validators import UniqueTogetherValidator from rest_framework.validators import UniqueTogetherValidator
from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField
from dcim.api.serializers import NestedDeviceSerializer, InterfaceSerializer, NestedSiteSerializer from dcim.api.nested_serializers import NestedDeviceSerializer, NestedSiteSerializer
from dcim.models import Interface from dcim.models import Interface
from extras.api.customfields import CustomFieldModelSerializer from extras.api.customfields import CustomFieldModelSerializer
from ipam.constants import ( from ipam.constants import *
IPADDRESS_ROLE_CHOICES, IPADDRESS_STATUS_CHOICES, IP_PROTOCOL_CHOICES, PREFIX_STATUS_CHOICES, VLAN_STATUS_CHOICES,
)
from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF
from tenancy.api.serializers import NestedTenantSerializer from tenancy.api.nested_serializers import NestedTenantSerializer
from utilities.api import ( from utilities.api import (
ChoiceField, SerializedPKRelatedField, ValidatedModelSerializer, WritableNestedSerializer, ChoiceField, SerializedPKRelatedField, ValidatedModelSerializer, WritableNestedSerializer,
) )
from virtualization.api.serializers import NestedVirtualMachineSerializer from virtualization.api.nested_serializers import NestedVirtualMachineSerializer
from .nested_serializers import *
# #
@ -35,35 +34,8 @@ class VRFSerializer(TaggitSerializer, CustomFieldModelSerializer):
] ]
class NestedVRFSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vrf-detail')
class Meta:
model = VRF
fields = ['id', 'url', 'name', 'rd']
# #
# Roles # RIRs/aggregates
#
class RoleSerializer(ValidatedModelSerializer):
class Meta:
model = Role
fields = ['id', 'name', 'slug', 'weight']
class NestedRoleSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:role-detail')
class Meta:
model = Role
fields = ['id', 'url', 'name', 'slug']
#
# RIRs
# #
class RIRSerializer(ValidatedModelSerializer): class RIRSerializer(ValidatedModelSerializer):
@ -73,18 +45,6 @@ class RIRSerializer(ValidatedModelSerializer):
fields = ['id', 'name', 'slug', 'is_private'] fields = ['id', 'name', 'slug', 'is_private']
class NestedRIRSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:rir-detail')
class Meta:
model = RIR
fields = ['id', 'url', 'name', 'slug']
#
# Aggregates
#
class AggregateSerializer(TaggitSerializer, CustomFieldModelSerializer): class AggregateSerializer(TaggitSerializer, CustomFieldModelSerializer):
rir = NestedRIRSerializer() rir = NestedRIRSerializer()
tags = TagListSerializerField(required=False) tags = TagListSerializerField(required=False)
@ -98,18 +58,17 @@ class AggregateSerializer(TaggitSerializer, CustomFieldModelSerializer):
read_only_fields = ['family'] read_only_fields = ['family']
class NestedAggregateSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:aggregate-detail')
class Meta(AggregateSerializer.Meta):
model = Aggregate
fields = ['id', 'url', 'family', 'prefix']
# #
# VLAN groups # VLANs
# #
class RoleSerializer(ValidatedModelSerializer):
class Meta:
model = Role
fields = ['id', 'name', 'slug', 'weight']
class VLANGroupSerializer(ValidatedModelSerializer): class VLANGroupSerializer(ValidatedModelSerializer):
site = NestedSiteSerializer(required=False, allow_null=True) site = NestedSiteSerializer(required=False, allow_null=True)
@ -133,18 +92,6 @@ class VLANGroupSerializer(ValidatedModelSerializer):
return data return data
class NestedVLANGroupSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlangroup-detail')
class Meta:
model = VLANGroup
fields = ['id', 'url', 'name', 'slug']
#
# VLANs
#
class VLANSerializer(TaggitSerializer, CustomFieldModelSerializer): class VLANSerializer(TaggitSerializer, CustomFieldModelSerializer):
site = NestedSiteSerializer(required=False, allow_null=True) site = NestedSiteSerializer(required=False, allow_null=True)
group = NestedVLANGroupSerializer(required=False, allow_null=True) group = NestedVLANGroupSerializer(required=False, allow_null=True)
@ -176,14 +123,6 @@ class VLANSerializer(TaggitSerializer, CustomFieldModelSerializer):
return data return data
class NestedVLANSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlan-detail')
class Meta:
model = VLAN
fields = ['id', 'url', 'vid', 'name', 'display_name']
# #
# Prefixes # Prefixes
# #
@ -206,16 +145,10 @@ class PrefixSerializer(TaggitSerializer, CustomFieldModelSerializer):
read_only_fields = ['family'] read_only_fields = ['family']
class NestedPrefixSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:prefix-detail')
class Meta:
model = Prefix
fields = ['id', 'url', 'family', 'prefix']
class AvailablePrefixSerializer(serializers.Serializer): class AvailablePrefixSerializer(serializers.Serializer):
"""
Representation of a prefix which does not exist in the database.
"""
def to_representation(self, instance): def to_representation(self, instance):
if self.context.get('vrf'): if self.context.get('vrf'):
vrf = NestedVRFSerializer(self.context['vrf'], context={'request': self.context['request']}).data vrf = NestedVRFSerializer(self.context['vrf'], context={'request': self.context['request']}).data
@ -233,11 +166,14 @@ class AvailablePrefixSerializer(serializers.Serializer):
# #
class IPAddressInterfaceSerializer(WritableNestedSerializer): class IPAddressInterfaceSerializer(WritableNestedSerializer):
"""
Nested representation of an Interface which may belong to a Device *or* a VirtualMachine.
"""
url = serializers.SerializerMethodField() # We're imitating a HyperlinkedIdentityField here url = serializers.SerializerMethodField() # We're imitating a HyperlinkedIdentityField here
device = NestedDeviceSerializer(read_only=True) device = NestedDeviceSerializer(read_only=True)
virtual_machine = NestedVirtualMachineSerializer(read_only=True) virtual_machine = NestedVirtualMachineSerializer(read_only=True)
class Meta(InterfaceSerializer.Meta): class Meta:
model = Interface model = Interface
fields = [ fields = [
'id', 'url', 'device', 'virtual_machine', 'name', 'id', 'url', 'device', 'virtual_machine', 'name',
@ -258,6 +194,8 @@ class IPAddressSerializer(TaggitSerializer, CustomFieldModelSerializer):
status = ChoiceField(choices=IPADDRESS_STATUS_CHOICES, required=False) status = ChoiceField(choices=IPADDRESS_STATUS_CHOICES, required=False)
role = ChoiceField(choices=IPADDRESS_ROLE_CHOICES, required=False, allow_null=True) role = ChoiceField(choices=IPADDRESS_ROLE_CHOICES, required=False, allow_null=True)
interface = IPAddressInterfaceSerializer(required=False, allow_null=True) interface = IPAddressInterfaceSerializer(required=False, allow_null=True)
nat_inside = NestedIPAddressSerializer(required=False, allow_null=True)
nat_outside = NestedIPAddressSerializer(read_only=True)
tags = TagListSerializerField(required=False) tags = TagListSerializerField(required=False)
class Meta: class Meta:
@ -269,20 +207,10 @@ class IPAddressSerializer(TaggitSerializer, CustomFieldModelSerializer):
read_only_fields = ['family'] read_only_fields = ['family']
class NestedIPAddressSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:ipaddress-detail')
class Meta:
model = IPAddress
fields = ['id', 'url', 'family', 'address']
IPAddressSerializer._declared_fields['nat_inside'] = NestedIPAddressSerializer(required=False, allow_null=True)
IPAddressSerializer._declared_fields['nat_outside'] = NestedIPAddressSerializer(read_only=True)
class AvailableIPSerializer(serializers.Serializer): class AvailableIPSerializer(serializers.Serializer):
"""
Representation of an IP address which does not exist in the database.
"""
def to_representation(self, instance): def to_representation(self, instance):
if self.context.get('vrf'): if self.context.get('vrf'):
vrf = NestedVRFSerializer(self.context['vrf'], context={'request': self.context['request']}).data vrf = NestedVRFSerializer(self.context['vrf'], context={'request': self.context['request']}).data

View File

@ -0,0 +1,16 @@
from rest_framework import serializers
from secrets.models import SecretRole
from utilities.api import WritableNestedSerializer
__all__ = [
'NestedSecretRoleSerializer'
]
class NestedSecretRoleSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='secrets-api:secretrole-detail')
class Meta:
model = SecretRole
fields = ['id', 'url', 'name', 'slug']

View File

@ -2,14 +2,15 @@ from rest_framework import serializers
from rest_framework.validators import UniqueTogetherValidator from rest_framework.validators import UniqueTogetherValidator
from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField
from dcim.api.serializers import NestedDeviceSerializer from dcim.api.nested_serializers import NestedDeviceSerializer
from extras.api.customfields import CustomFieldModelSerializer from extras.api.customfields import CustomFieldModelSerializer
from secrets.models import Secret, SecretRole from secrets.models import Secret, SecretRole
from utilities.api import ValidatedModelSerializer, WritableNestedSerializer from utilities.api import ValidatedModelSerializer
from .nested_serializers import *
# #
# SecretRoles # Secrets
# #
class SecretRoleSerializer(ValidatedModelSerializer): class SecretRoleSerializer(ValidatedModelSerializer):
@ -19,18 +20,6 @@ class SecretRoleSerializer(ValidatedModelSerializer):
fields = ['id', 'name', 'slug'] fields = ['id', 'name', 'slug']
class NestedSecretRoleSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='secrets-api:secretrole-detail')
class Meta:
model = SecretRole
fields = ['id', 'url', 'name', 'slug']
#
# Secrets
#
class SecretSerializer(TaggitSerializer, CustomFieldModelSerializer): class SecretSerializer(TaggitSerializer, CustomFieldModelSerializer):
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
role = NestedSecretRoleSerializer() role = NestedSecretRoleSerializer()

View File

@ -0,0 +1,29 @@
from rest_framework import serializers
from tenancy.models import Tenant, TenantGroup
from utilities.api import WritableNestedSerializer
__all__ = [
'NestedTenantGroupSerializer',
'NestedTenantSerializer',
]
#
# Tenants
#
class NestedTenantGroupSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:tenantgroup-detail')
class Meta:
model = TenantGroup
fields = ['id', 'url', 'name', 'slug']
class NestedTenantSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:tenant-detail')
class Meta:
model = Tenant
fields = ['id', 'url', 'name', 'slug']

View File

@ -1,13 +1,13 @@
from rest_framework import serializers
from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField
from extras.api.customfields import CustomFieldModelSerializer from extras.api.customfields import CustomFieldModelSerializer
from tenancy.models import Tenant, TenantGroup from tenancy.models import Tenant, TenantGroup
from utilities.api import ValidatedModelSerializer, WritableNestedSerializer from utilities.api import ValidatedModelSerializer
from .nested_serializers import *
# #
# Tenant groups # Tenants
# #
class TenantGroupSerializer(ValidatedModelSerializer): class TenantGroupSerializer(ValidatedModelSerializer):
@ -17,18 +17,6 @@ class TenantGroupSerializer(ValidatedModelSerializer):
fields = ['id', 'name', 'slug'] fields = ['id', 'name', 'slug']
class NestedTenantGroupSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:tenantgroup-detail')
class Meta:
model = TenantGroup
fields = ['id', 'url', 'name', 'slug']
#
# Tenants
#
class TenantSerializer(TaggitSerializer, CustomFieldModelSerializer): class TenantSerializer(TaggitSerializer, CustomFieldModelSerializer):
group = NestedTenantGroupSerializer(required=False) group = NestedTenantGroupSerializer(required=False)
tags = TagListSerializerField(required=False) tags = TagListSerializerField(required=False)
@ -39,11 +27,3 @@ class TenantSerializer(TaggitSerializer, CustomFieldModelSerializer):
'id', 'name', 'slug', 'group', 'description', 'comments', 'tags', 'custom_fields', 'created', 'id', 'name', 'slug', 'group', 'description', 'comments', 'tags', 'custom_fields', 'created',
'last_updated', 'last_updated',
] ]
class NestedTenantSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='tenancy-api:tenant-detail')
class Meta:
model = Tenant
fields = ['id', 'url', 'name', 'slug']

View File

@ -0,0 +1,18 @@
from django.contrib.auth.models import User
from utilities.api import WritableNestedSerializer
_all_ = [
'NestedUserSerializer',
]
#
# Users
#
class NestedUserSerializer(WritableNestedSerializer):
class Meta:
model = User
fields = ['id', 'username']

View File

@ -1,10 +1,4 @@
from django.contrib.auth.models import User from .nested_serializers import *
from utilities.api import WritableNestedSerializer
class NestedUserSerializer(WritableNestedSerializer): # Placeholder for future serializers
class Meta:
model = User
fields = ['id', 'username']

View File

@ -0,0 +1,62 @@
from rest_framework import serializers
from dcim.models import Interface
from utilities.api import WritableNestedSerializer
from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine
__all__ = [
'NestedClusterGroupSerializer',
'NestedClusterSerializer',
'NestedClusterTypeSerializer',
'NestedInterfaceSerializer',
'NestedVirtualMachineSerializer',
]
#
# Clusters
#
class NestedClusterTypeSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:clustertype-detail')
class Meta:
model = ClusterType
fields = ['id', 'url', 'name', 'slug']
class NestedClusterGroupSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:clustergroup-detail')
class Meta:
model = ClusterGroup
fields = ['id', 'url', 'name', 'slug']
class NestedClusterSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:cluster-detail')
class Meta:
model = Cluster
fields = ['id', 'url', 'name']
#
# Virtual machines
#
class NestedVirtualMachineSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:virtualmachine-detail')
class Meta:
model = VirtualMachine
fields = ['id', 'url', 'name']
class NestedInterfaceSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:interface-detail')
virtual_machine = NestedVirtualMachineSerializer(read_only=True)
class Meta:
model = Interface
fields = ['id', 'url', 'virtual_machine', 'name']

View File

@ -1,19 +1,21 @@
from rest_framework import serializers from rest_framework import serializers
from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField
from dcim.api.serializers import NestedDeviceRoleSerializer, NestedPlatformSerializer, NestedSiteSerializer from dcim.api.nested_serializers import NestedDeviceRoleSerializer, NestedPlatformSerializer, NestedSiteSerializer
from dcim.constants import IFACE_FF_CHOICES, IFACE_FF_VIRTUAL, IFACE_MODE_CHOICES from dcim.constants import IFACE_FF_CHOICES, IFACE_FF_VIRTUAL, IFACE_MODE_CHOICES
from dcim.models import Interface from dcim.models import Interface
from extras.api.customfields import CustomFieldModelSerializer from extras.api.customfields import CustomFieldModelSerializer
from ipam.models import IPAddress, VLAN from ipam.api.nested_serializers import NestedIPAddressSerializer, NestedVLANSerializer
from tenancy.api.serializers import NestedTenantSerializer from ipam.models import VLAN
from utilities.api import ChoiceField, SerializedPKRelatedField, ValidatedModelSerializer, WritableNestedSerializer from tenancy.api.nested_serializers import NestedTenantSerializer
from utilities.api import ChoiceField, SerializedPKRelatedField, ValidatedModelSerializer
from virtualization.constants import VM_STATUS_CHOICES from virtualization.constants import VM_STATUS_CHOICES
from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine
from .nested_serializers import *
# #
# Cluster types # Clusters
# #
class ClusterTypeSerializer(ValidatedModelSerializer): class ClusterTypeSerializer(ValidatedModelSerializer):
@ -23,18 +25,6 @@ class ClusterTypeSerializer(ValidatedModelSerializer):
fields = ['id', 'name', 'slug'] fields = ['id', 'name', 'slug']
class NestedClusterTypeSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:clustertype-detail')
class Meta:
model = ClusterType
fields = ['id', 'url', 'name', 'slug']
#
# Cluster groups
#
class ClusterGroupSerializer(ValidatedModelSerializer): class ClusterGroupSerializer(ValidatedModelSerializer):
class Meta: class Meta:
@ -42,18 +32,6 @@ class ClusterGroupSerializer(ValidatedModelSerializer):
fields = ['id', 'name', 'slug'] fields = ['id', 'name', 'slug']
class NestedClusterGroupSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:clustergroup-detail')
class Meta:
model = ClusterGroup
fields = ['id', 'url', 'name', 'slug']
#
# Clusters
#
class ClusterSerializer(TaggitSerializer, CustomFieldModelSerializer): class ClusterSerializer(TaggitSerializer, CustomFieldModelSerializer):
type = NestedClusterTypeSerializer() type = NestedClusterTypeSerializer()
group = NestedClusterGroupSerializer(required=False, allow_null=True) group = NestedClusterGroupSerializer(required=False, allow_null=True)
@ -67,27 +45,10 @@ class ClusterSerializer(TaggitSerializer, CustomFieldModelSerializer):
] ]
class NestedClusterSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:cluster-detail')
class Meta:
model = Cluster
fields = ['id', 'url', 'name']
# #
# Virtual machines # Virtual machines
# #
# Cannot import ipam.api.NestedIPAddressSerializer due to circular dependency
class VirtualMachineIPAddressSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:ipaddress-detail')
class Meta:
model = IPAddress
fields = ['id', 'url', 'family', 'address']
class VirtualMachineSerializer(TaggitSerializer, CustomFieldModelSerializer): class VirtualMachineSerializer(TaggitSerializer, CustomFieldModelSerializer):
status = ChoiceField(choices=VM_STATUS_CHOICES, required=False) status = ChoiceField(choices=VM_STATUS_CHOICES, required=False)
site = NestedSiteSerializer(read_only=True) site = NestedSiteSerializer(read_only=True)
@ -95,17 +56,17 @@ class VirtualMachineSerializer(TaggitSerializer, CustomFieldModelSerializer):
role = NestedDeviceRoleSerializer(required=False, allow_null=True) role = NestedDeviceRoleSerializer(required=False, allow_null=True)
tenant = NestedTenantSerializer(required=False, allow_null=True) tenant = NestedTenantSerializer(required=False, allow_null=True)
platform = NestedPlatformSerializer(required=False, allow_null=True) platform = NestedPlatformSerializer(required=False, allow_null=True)
primary_ip = VirtualMachineIPAddressSerializer(read_only=True) primary_ip = NestedIPAddressSerializer(read_only=True)
primary_ip4 = VirtualMachineIPAddressSerializer(required=False, allow_null=True) primary_ip4 = NestedIPAddressSerializer(required=False, allow_null=True)
primary_ip6 = VirtualMachineIPAddressSerializer(required=False, allow_null=True) primary_ip6 = NestedIPAddressSerializer(required=False, allow_null=True)
tags = TagListSerializerField(required=False) tags = TagListSerializerField(required=False)
class Meta: class Meta:
model = VirtualMachine model = VirtualMachine
fields = [ fields = [
'id', 'name', 'status', 'site', 'cluster', 'role', 'tenant', 'platform', 'primary_ip', 'primary_ip4', 'id', 'name', 'status', 'site', 'cluster', 'role', 'tenant', 'platform', 'primary_ip', 'primary_ip4',
'primary_ip6', 'vcpus', 'memory', 'disk', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'primary_ip6', 'vcpus', 'memory', 'disk', 'comments', 'local_context_data', 'tags', 'custom_fields',
'local_context_data', 'created', 'last_updated',
] ]
@ -114,44 +75,27 @@ class VirtualMachineWithConfigContextSerializer(VirtualMachineSerializer):
class Meta(VirtualMachineSerializer.Meta): class Meta(VirtualMachineSerializer.Meta):
fields = [ fields = [
'id', 'name', 'status', 'cluster', 'role', 'tenant', 'platform', 'primary_ip', 'primary_ip4', 'primary_ip6', 'id', 'name', 'status', 'site', 'cluster', 'role', 'tenant', 'platform', 'primary_ip', 'primary_ip4',
'vcpus', 'memory', 'disk', 'comments', 'tags', 'custom_fields', 'config_context', 'created', 'last_updated', 'primary_ip6', 'vcpus', 'memory', 'disk', 'comments', 'local_context_data', 'tags', 'custom_fields',
'local_context_data', 'config_context', 'created', 'last_updated',
] ]
def get_config_context(self, obj): def get_config_context(self, obj):
return obj.get_config_context() return obj.get_config_context()
class NestedVirtualMachineSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:virtualmachine-detail')
class Meta:
model = VirtualMachine
fields = ['id', 'url', 'name']
# #
# VM interfaces # VM interfaces
# #
# Cannot import ipam.api.serializers.NestedVLANSerializer due to circular dependency
class InterfaceVLANSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlan-detail')
class Meta:
model = VLAN
fields = ['id', 'url', 'vid', 'name', 'display_name']
class InterfaceSerializer(TaggitSerializer, ValidatedModelSerializer): class InterfaceSerializer(TaggitSerializer, ValidatedModelSerializer):
virtual_machine = NestedVirtualMachineSerializer() virtual_machine = NestedVirtualMachineSerializer()
form_factor = ChoiceField(choices=IFACE_FF_CHOICES, default=IFACE_FF_VIRTUAL, required=False) form_factor = ChoiceField(choices=IFACE_FF_CHOICES, default=IFACE_FF_VIRTUAL, required=False)
mode = ChoiceField(choices=IFACE_MODE_CHOICES, required=False, allow_null=True) mode = ChoiceField(choices=IFACE_MODE_CHOICES, required=False, allow_null=True)
untagged_vlan = InterfaceVLANSerializer(required=False, allow_null=True) untagged_vlan = NestedVLANSerializer(required=False, allow_null=True)
tagged_vlans = SerializedPKRelatedField( tagged_vlans = SerializedPKRelatedField(
queryset=VLAN.objects.all(), queryset=VLAN.objects.all(),
serializer=InterfaceVLANSerializer, serializer=NestedVLANSerializer,
required=False, required=False,
many=True many=True
) )
@ -163,12 +107,3 @@ class InterfaceSerializer(TaggitSerializer, ValidatedModelSerializer):
'id', 'virtual_machine', 'name', 'form_factor', 'enabled', 'mtu', 'mac_address', 'description', 'mode', 'id', 'virtual_machine', 'name', 'form_factor', 'enabled', 'mtu', 'mac_address', 'description', 'mode',
'untagged_vlan', 'tagged_vlans', 'tags', 'untagged_vlan', 'tagged_vlans', 'tags',
] ]
class NestedInterfaceSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:interface-detail')
virtual_machine = NestedVirtualMachineSerializer(read_only=True)
class Meta:
model = Interface
fields = ['id', 'url', 'virtual_machine', 'name']