2
0
Эх сурвалжийг харах

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>
Arthur Hanson 2 жил өмнө
parent
commit
bb6b4d01c1

+ 27 - 10
netbox/ipam/api/field_serializers.py

@@ -1,21 +1,18 @@
 from django.utils.translation import gettext_lazy as _
 from rest_framework import serializers
 
-from ipam import models
 from netaddr import AddrFormatError, IPNetwork
 
-__all__ = [
+__all__ = (
     'IPAddressField',
-]
+    'IPNetworkField',
+)
 
 
-#
-# IP address field
-#
-
 class IPAddressField(serializers.CharField):
-    """IPAddressField with mask"""
-
+    """
+    An IPv4 or IPv6 address with optional mask
+    """
     default_error_messages = {
         'invalid': _('Enter a valid IPv4 or IPv6 address with optional mask.'),
     }
@@ -24,7 +21,27 @@ class IPAddressField(serializers.CharField):
         try:
             return IPNetwork(data)
         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:
             raise serializers.ValidationError(e)
 

+ 3 - 6
netbox/ipam/api/serializers.py

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