class VRFSerializer(PrimaryModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vrf-detail') tenant = NestedTenantSerializer(required=False, allow_null=True) import_targets = SerializedPKRelatedField( queryset=RouteTarget.objects.all(), serializer=NestedRouteTargetSerializer, required=False, many=True ) export_targets = SerializedPKRelatedField( queryset=RouteTarget.objects.all(), serializer=NestedRouteTargetSerializer, required=False, many=True ) ipaddress_count = serializers.IntegerField(read_only=True) prefix_count = serializers.IntegerField(read_only=True) class Meta: model = VRF fields = [ 'id', 'url', 'display', 'name', 'rd', 'tenant', 'enforce_unique', 'description', 'import_targets', 'export_targets', 'tags', 'display_name', 'custom_fields', 'created', 'last_updated', 'ipaddress_count', 'prefix_count', ]
class ObjectPermissionSerializer(ValidatedModelSerializer): url = serializers.HyperlinkedIdentityField( view_name='users-api:objectpermission-detail') object_types = ContentTypeField(queryset=ContentType.objects.all(), many=True) groups = SerializedPKRelatedField(queryset=Group.objects.all(), serializer=NestedGroupSerializer, required=False, many=True) users = SerializedPKRelatedField(queryset=User.objects.all(), serializer=NestedUserSerializer, required=False, many=True) class Meta: model = ObjectPermission fields = ( 'id', 'url', 'display', 'name', 'description', 'enabled', 'object_types', 'groups', 'users', 'actions', 'constraints', )
class InterfaceSerializer(PrimaryModelSerializer, LinkTerminationSerializer, ConnectedEndpointSerializer): url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail') device = NestedDeviceSerializer() type = ChoiceField(choices=InterfaceTypeChoices) parent = NestedInterfaceSerializer(required=False, allow_null=True) bridge = NestedInterfaceSerializer(required=False, allow_null=True) lag = NestedInterfaceSerializer(required=False, allow_null=True) mode = ChoiceField(choices=InterfaceModeChoices, allow_blank=True, required=False) rf_role = ChoiceField(choices=WirelessRoleChoices, required=False, allow_null=True) rf_channel = ChoiceField(choices=WirelessChannelChoices, required=False) untagged_vlan = NestedVLANSerializer(required=False, allow_null=True) tagged_vlans = SerializedPKRelatedField( queryset=VLAN.objects.all(), serializer=NestedVLANSerializer, required=False, many=True ) cable = NestedCableSerializer(read_only=True) wireless_link = NestedWirelessLinkSerializer(read_only=True) wireless_lans = SerializedPKRelatedField( queryset=WirelessLAN.objects.all(), serializer=NestedWirelessLANSerializer, required=False, many=True ) count_ipaddresses = serializers.IntegerField(read_only=True) count_fhrp_groups = serializers.IntegerField(read_only=True) class Meta: model = Interface fields = [ 'id', 'url', 'display', 'device', 'name', 'label', 'type', 'enabled', 'parent', 'bridge', 'lag', 'mtu', 'mac_address', 'wwn', 'mgmt_only', 'description', 'mode', 'rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'untagged_vlan', 'tagged_vlans', 'mark_connected', 'cable', 'wireless_link', 'link_peer', 'link_peer_type', 'wireless_lans', 'connected_endpoint', 'connected_endpoint_type', 'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated', 'count_ipaddresses', 'count_fhrp_groups', '_occupied', ] def validate(self, data): # Validate many-to-many VLAN assignments device = self.instance.device if self.instance else data.get('device') for vlan in data.get('tagged_vlans', []): if vlan.site not in [device.site, None]: raise serializers.ValidationError({ 'tagged_vlans': f"VLAN {vlan} must belong to the same site as the interface's parent device, or " f"it must be global." }) return super().validate(data)
class ServiceSerializer(PrimaryModelSerializer): url = serializers.HyperlinkedIdentityField( view_name='ipam-api:service-detail') device = NestedDeviceSerializer(required=False, allow_null=True) virtual_machine = NestedVirtualMachineSerializer(required=False, allow_null=True) protocol = ChoiceField(choices=ServiceProtocolChoices, required=False) ipaddresses = SerializedPKRelatedField( queryset=IPAddress.objects.all(), serializer=NestedIPAddressSerializer, required=False, many=True) class Meta: model = Service fields = [ 'id', 'url', 'display', 'device', 'virtual_machine', 'name', 'ports', 'protocol', 'ipaddresses', 'description', 'tags', 'custom_fields', 'created', 'last_updated', ]
class SiteSerializer(PrimaryModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='dcim-api:site-detail') status = ChoiceField(choices=SiteStatusChoices, required=False) region = NestedRegionSerializer(required=False, allow_null=True) group = NestedSiteGroupSerializer(required=False, allow_null=True) tenant = NestedTenantSerializer(required=False, allow_null=True) time_zone = TimeZoneSerializerField(required=False) asns = SerializedPKRelatedField( queryset=ASN.objects.all(), serializer=NestedASNSerializer, required=False, many=True ) # Related object counts circuit_count = serializers.IntegerField(read_only=True) device_count = serializers.IntegerField(read_only=True) prefix_count = serializers.IntegerField(read_only=True) rack_count = serializers.IntegerField(read_only=True) virtualmachine_count = serializers.IntegerField(read_only=True) vlan_count = serializers.IntegerField(read_only=True) class Meta: model = Site fields = [ 'id', 'url', 'display', 'name', 'slug', 'status', 'region', 'group', 'tenant', 'facility', 'asn', 'asns', 'time_zone', 'description', 'physical_address', 'shipping_address', 'latitude', 'longitude', 'contact_name', 'contact_phone', 'contact_email', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'circuit_count', 'device_count', 'prefix_count', 'rack_count', 'virtualmachine_count', 'vlan_count', ]
class UserSerializer(ValidatedModelSerializer): url = serializers.HyperlinkedIdentityField(view_name='users-api:user-detail') groups = SerializedPKRelatedField( queryset=Group.objects.all(), serializer=NestedGroupSerializer, required=False, many=True ) class Meta: model = User fields = ( 'id', 'url', 'username', 'password', 'first_name', 'last_name', 'email', 'is_staff', 'is_active', 'date_joined', 'groups', ) extra_kwargs = { 'password': {'write_only': True} } def create(self, validated_data): """ Extract the password from validated data and set it separately to ensure proper hash generation. """ password = validated_data.pop('password') user = super().create(validated_data) user.set_password(password) user.save() return user
class InterfaceSerializer(TaggedObjectSerializer, CableTerminationSerializer, ConnectedEndpointSerializer): url = serializers.HyperlinkedIdentityField( view_name='dcim-api:interface-detail') device = NestedDeviceSerializer() type = ChoiceField(choices=InterfaceTypeChoices) lag = NestedInterfaceSerializer(required=False, allow_null=True) mode = ChoiceField(choices=InterfaceModeChoices, allow_blank=True, required=False) 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) count_ipaddresses = serializers.IntegerField(read_only=True) class Meta: model = Interface fields = [ 'id', 'url', 'device', 'name', 'label', 'type', 'enabled', 'lag', 'mtu', 'mac_address', 'mgmt_only', 'description', 'mode', 'untagged_vlan', 'tagged_vlans', 'cable', 'cable_peer', 'cable_peer_type', 'connected_endpoint', 'connected_endpoint_type', 'connected_endpoint_reachable', 'tags', 'count_ipaddresses', ] def validate(self, data): # Validate many-to-many VLAN assignments device = self.instance.device if self.instance else data.get('device') for vlan in data.get('tagged_vlans', []): if vlan.site not in [device.site, None]: raise serializers.ValidationError({ 'tagged_vlans': f"VLAN {vlan} must belong to the same site as the interface's parent device, or " f"it must be global." }) return super().validate(data)
class VMInterfaceSerializer(PrimaryModelSerializer): url = serializers.HyperlinkedIdentityField( view_name='virtualization-api:vminterface-detail') virtual_machine = NestedVirtualMachineSerializer() parent = NestedVMInterfaceSerializer(required=False, allow_null=True) bridge = NestedVMInterfaceSerializer(required=False, allow_null=True) mode = ChoiceField(choices=InterfaceModeChoices, allow_blank=True, required=False) untagged_vlan = NestedVLANSerializer(required=False, allow_null=True) tagged_vlans = SerializedPKRelatedField(queryset=VLAN.objects.all(), serializer=NestedVLANSerializer, required=False, many=True) count_ipaddresses = serializers.IntegerField(read_only=True) count_fhrp_groups = serializers.IntegerField(read_only=True) class Meta: model = VMInterface fields = [ 'id', 'url', 'display', 'virtual_machine', 'name', 'enabled', 'parent', 'bridge', 'mtu', 'mac_address', 'description', 'mode', 'untagged_vlan', 'tagged_vlans', 'tags', 'custom_fields', 'created', 'last_updated', 'count_ipaddresses', 'count_fhrp_groups', ] def validate(self, data): # Validate many-to-many VLAN assignments virtual_machine = self.instance.virtual_machine if self.instance else data.get( 'virtual_machine') for vlan in data.get('tagged_vlans', []): if vlan.site not in [virtual_machine.site, None]: raise serializers.ValidationError({ 'tagged_vlans': f"VLAN {vlan} must belong to the same site as the interface's parent virtual " f"machine, or it must be global." }) return super().validate(data)
class ConfigContextSerializer(ValidatedModelSerializer): url = serializers.HyperlinkedIdentityField( view_name='extras-api:configcontext-detail') regions = SerializedPKRelatedField(queryset=Region.objects.all(), serializer=NestedRegionSerializer, required=False, many=True) site_groups = SerializedPKRelatedField( queryset=SiteGroup.objects.all(), serializer=NestedSiteGroupSerializer, required=False, many=True) sites = SerializedPKRelatedField(queryset=Site.objects.all(), serializer=NestedSiteSerializer, required=False, many=True) device_types = SerializedPKRelatedField( queryset=DeviceType.objects.all(), serializer=NestedDeviceTypeSerializer, required=False, many=True) roles = SerializedPKRelatedField(queryset=DeviceRole.objects.all(), serializer=NestedDeviceRoleSerializer, required=False, many=True) platforms = SerializedPKRelatedField(queryset=Platform.objects.all(), serializer=NestedPlatformSerializer, required=False, many=True) cluster_groups = SerializedPKRelatedField( queryset=ClusterGroup.objects.all(), serializer=NestedClusterGroupSerializer, required=False, many=True) clusters = SerializedPKRelatedField(queryset=Cluster.objects.all(), serializer=NestedClusterSerializer, required=False, many=True) tenant_groups = SerializedPKRelatedField( queryset=TenantGroup.objects.all(), serializer=NestedTenantGroupSerializer, required=False, many=True) tenants = SerializedPKRelatedField(queryset=Tenant.objects.all(), serializer=NestedTenantSerializer, required=False, many=True) tags = serializers.SlugRelatedField(queryset=Tag.objects.all(), slug_field='slug', required=False, many=True) class Meta: model = ConfigContext fields = [ 'id', 'url', 'display', 'name', 'weight', 'description', 'is_active', 'regions', 'site_groups', 'sites', 'device_types', 'roles', 'platforms', 'cluster_groups', 'clusters', 'tenant_groups', 'tenants', 'tags', 'data', 'created', 'last_updated', ]