12553 prefix serializer to IPAddress (#13592)

* 12553 prefix serializer to IPAddress

* Introduce IPNetworkField to handle prefix serialization

---------

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
This commit is contained in:
Arthur Hanson 2023-09-06 07:49:40 -07:00 committed by GitHub
parent 2d1457b94b
commit bb6b4d01c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 16 deletions

View File

@ -1,21 +1,18 @@
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from rest_framework import serializers from rest_framework import serializers
from ipam import models
from netaddr import AddrFormatError, IPNetwork from netaddr import AddrFormatError, IPNetwork
__all__ = [ __all__ = (
'IPAddressField', 'IPAddressField',
] 'IPNetworkField',
)
#
# IP address field
#
class IPAddressField(serializers.CharField): class IPAddressField(serializers.CharField):
"""IPAddressField with mask""" """
An IPv4 or IPv6 address with optional mask
"""
default_error_messages = { default_error_messages = {
'invalid': _('Enter a valid IPv4 or IPv6 address with optional mask.'), 'invalid': _('Enter a valid IPv4 or IPv6 address with optional mask.'),
} }
@ -24,7 +21,27 @@ class IPAddressField(serializers.CharField):
try: try:
return IPNetwork(data) return IPNetwork(data)
except AddrFormatError: except AddrFormatError:
raise serializers.ValidationError("Invalid IP address format: {}".format(data)) raise serializers.ValidationError(_("Invalid IP address format: {data}").format(data))
except (TypeError, ValueError) as e:
raise serializers.ValidationError(e)
def to_representation(self, value):
return str(value)
class IPNetworkField(serializers.CharField):
"""
An IPv4 or IPv6 prefix
"""
default_error_messages = {
'invalid': _('Enter a valid IPv4 or IPv6 prefix and mask in CIDR notation.'),
}
def to_internal_value(self, data):
try:
return IPNetwork(data)
except AddrFormatError:
raise serializers.ValidationError(_("Invalid IP prefix format: {data}").format(data))
except (TypeError, ValueError) as e: except (TypeError, ValueError) as e:
raise serializers.ValidationError(e) raise serializers.ValidationError(e)

View File

@ -13,7 +13,7 @@ from tenancy.api.nested_serializers import NestedTenantSerializer
from utilities.api import get_serializer_for_model from utilities.api import get_serializer_for_model
from virtualization.api.nested_serializers import NestedVirtualMachineSerializer from virtualization.api.nested_serializers import NestedVirtualMachineSerializer
from .nested_serializers import * from .nested_serializers import *
from .field_serializers import IPAddressField from .field_serializers import IPAddressField, IPNetworkField
# #
@ -138,7 +138,7 @@ class AggregateSerializer(NetBoxModelSerializer):
family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True) family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
rir = NestedRIRSerializer() rir = NestedRIRSerializer()
tenant = NestedTenantSerializer(required=False, allow_null=True) tenant = NestedTenantSerializer(required=False, allow_null=True)
prefix = serializers.CharField() prefix = IPNetworkField()
class Meta: class Meta:
model = Aggregate model = Aggregate
@ -146,7 +146,6 @@ class AggregateSerializer(NetBoxModelSerializer):
'id', 'url', 'display', 'family', 'prefix', 'rir', 'tenant', 'date_added', 'description', 'comments', 'id', 'url', 'display', 'family', 'prefix', 'rir', 'tenant', 'date_added', 'description', 'comments',
'tags', 'custom_fields', 'created', 'last_updated', 'tags', 'custom_fields', 'created', 'last_updated',
] ]
read_only_fields = ['family']
# #
@ -306,7 +305,7 @@ class PrefixSerializer(NetBoxModelSerializer):
role = NestedRoleSerializer(required=False, allow_null=True) role = NestedRoleSerializer(required=False, allow_null=True)
children = serializers.IntegerField(read_only=True) children = serializers.IntegerField(read_only=True)
_depth = serializers.IntegerField(read_only=True) _depth = serializers.IntegerField(read_only=True)
prefix = serializers.CharField() prefix = IPNetworkField()
class Meta: class Meta:
model = Prefix model = Prefix
@ -315,7 +314,6 @@ class PrefixSerializer(NetBoxModelSerializer):
'mark_utilized', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'children', 'mark_utilized', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'children',
'_depth', '_depth',
] ]
read_only_fields = ['family']
class PrefixLengthSerializer(serializers.Serializer): class PrefixLengthSerializer(serializers.Serializer):
@ -386,7 +384,6 @@ class IPRangeSerializer(NetBoxModelSerializer):
'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
'mark_utilized', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'mark_utilized', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
] ]
read_only_fields = ['family']
# #