mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-16 12:12:53 -06:00
Closes #2578: Reorganized nested serializers
This commit is contained in:
parent
04ae6ec7af
commit
75f0d8ee90
@ -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
|
||||||
|
52
netbox/circuits/api/nested_serializers.py
Normal file
52
netbox/circuits/api/nested_serializers.py
Normal 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']
|
@ -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']
|
|
||||||
|
243
netbox/dcim/api/nested_serializers.py
Normal file
243
netbox/dcim/api/nested_serializers.py
Normal 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']
|
@ -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']
|
|
||||||
|
@ -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):
|
||||||
|
23
netbox/extras/api/nested_serializers.py
Normal file
23
netbox/extras/api/nested_serializers.py
Normal 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']
|
@ -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)
|
||||||
|
100
netbox/ipam/api/nested_serializers.py
Normal file
100
netbox/ipam/api/nested_serializers.py
Normal 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']
|
@ -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
|
||||||
|
16
netbox/secrets/api/nested_serializers.py
Normal file
16
netbox/secrets/api/nested_serializers.py
Normal 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']
|
@ -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()
|
||||||
|
29
netbox/tenancy/api/nested_serializers.py
Normal file
29
netbox/tenancy/api/nested_serializers.py
Normal 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']
|
@ -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']
|
|
||||||
|
18
netbox/users/api/nested_serializers.py
Normal file
18
netbox/users/api/nested_serializers.py
Normal 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']
|
@ -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']
|
|
||||||
|
62
netbox/virtualization/api/nested_serializers.py
Normal file
62
netbox/virtualization/api/nested_serializers.py
Normal 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']
|
@ -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']
|
|
||||||
|
Loading…
Reference in New Issue
Block a user