mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-24 17:38:37 -06:00
Fixes #3930: Fix API rendering of the family field for aggregates
This commit is contained in:
parent
73d1a2df3d
commit
fdf8211e9a
@ -240,6 +240,7 @@ PATCH) to maintain backward compatibility. This behavior will be discontinued be
|
|||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
|
|
||||||
* [#3830](https://github.com/digitalocean/netbox/issues/3830) - Ensure deterministic ordering for all models
|
* [#3830](https://github.com/digitalocean/netbox/issues/3830) - Ensure deterministic ordering for all models
|
||||||
|
* [#3930](https://github.com/digitalocean/netbox/issues/3930) - Fix API rendering of the `family` field for aggregates
|
||||||
|
|
||||||
## Bug Fixes (From Beta)
|
## Bug Fixes (From Beta)
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ from dcim.api.nested_serializers import NestedDeviceSerializer, NestedSiteSerial
|
|||||||
from dcim.models import Interface
|
from dcim.models import Interface
|
||||||
from extras.api.customfields import CustomFieldModelSerializer
|
from extras.api.customfields import CustomFieldModelSerializer
|
||||||
from ipam.choices import *
|
from ipam.choices import *
|
||||||
from ipam.models import AF_CHOICES, 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.nested_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,
|
||||||
@ -49,6 +49,7 @@ class RIRSerializer(ValidatedModelSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class AggregateSerializer(TaggitSerializer, CustomFieldModelSerializer):
|
class AggregateSerializer(TaggitSerializer, CustomFieldModelSerializer):
|
||||||
|
family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
|
||||||
rir = NestedRIRSerializer()
|
rir = NestedRIRSerializer()
|
||||||
tags = TagListSerializerField(required=False)
|
tags = TagListSerializerField(required=False)
|
||||||
|
|
||||||
@ -135,7 +136,7 @@ class VLANSerializer(TaggitSerializer, CustomFieldModelSerializer):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class PrefixSerializer(TaggitSerializer, CustomFieldModelSerializer):
|
class PrefixSerializer(TaggitSerializer, CustomFieldModelSerializer):
|
||||||
family = ChoiceField(choices=AF_CHOICES, read_only=True)
|
family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
|
||||||
site = NestedSiteSerializer(required=False, allow_null=True)
|
site = NestedSiteSerializer(required=False, allow_null=True)
|
||||||
vrf = NestedVRFSerializer(required=False, allow_null=True)
|
vrf = NestedVRFSerializer(required=False, allow_null=True)
|
||||||
tenant = NestedTenantSerializer(required=False, allow_null=True)
|
tenant = NestedTenantSerializer(required=False, allow_null=True)
|
||||||
@ -197,7 +198,7 @@ class IPAddressInterfaceSerializer(WritableNestedSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class IPAddressSerializer(TaggitSerializer, CustomFieldModelSerializer):
|
class IPAddressSerializer(TaggitSerializer, CustomFieldModelSerializer):
|
||||||
family = ChoiceField(choices=AF_CHOICES, read_only=True)
|
family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
|
||||||
vrf = NestedVRFSerializer(required=False, allow_null=True)
|
vrf = NestedVRFSerializer(required=False, allow_null=True)
|
||||||
tenant = NestedTenantSerializer(required=False, allow_null=True)
|
tenant = NestedTenantSerializer(required=False, allow_null=True)
|
||||||
status = ChoiceField(choices=IPAddressStatusChoices, required=False)
|
status = ChoiceField(choices=IPAddressStatusChoices, required=False)
|
||||||
|
@ -1,6 +1,17 @@
|
|||||||
from utilities.choices import ChoiceSet
|
from utilities.choices import ChoiceSet
|
||||||
|
|
||||||
|
|
||||||
|
class IPAddressFamilyChoices(ChoiceSet):
|
||||||
|
|
||||||
|
FAMILY_4 = 4
|
||||||
|
FAMILY_6 = 6
|
||||||
|
|
||||||
|
CHOICES = (
|
||||||
|
(FAMILY_4, 'IPv4'),
|
||||||
|
(FAMILY_6, 'IPv6'),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Prefixes
|
# Prefixes
|
||||||
#
|
#
|
||||||
|
@ -21,13 +21,6 @@ from .querysets import PrefixQuerySet
|
|||||||
from .validators import DNSValidator
|
from .validators import DNSValidator
|
||||||
|
|
||||||
|
|
||||||
# IP address families
|
|
||||||
AF_CHOICES = (
|
|
||||||
(4, 'IPv4'),
|
|
||||||
(6, 'IPv6'),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'Aggregate',
|
'Aggregate',
|
||||||
'IPAddress',
|
'IPAddress',
|
||||||
@ -158,7 +151,7 @@ class Aggregate(ChangeLoggedModel, CustomFieldModel):
|
|||||||
the hierarchy and track the overall utilization of available address space. Each Aggregate is assigned to a RIR.
|
the hierarchy and track the overall utilization of available address space. Each Aggregate is assigned to a RIR.
|
||||||
"""
|
"""
|
||||||
family = models.PositiveSmallIntegerField(
|
family = models.PositiveSmallIntegerField(
|
||||||
choices=AF_CHOICES
|
choices=IPAddressFamilyChoices
|
||||||
)
|
)
|
||||||
prefix = IPNetworkField()
|
prefix = IPNetworkField()
|
||||||
rir = models.ForeignKey(
|
rir = models.ForeignKey(
|
||||||
@ -299,7 +292,7 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
|
|||||||
assigned to a VLAN where appropriate.
|
assigned to a VLAN where appropriate.
|
||||||
"""
|
"""
|
||||||
family = models.PositiveSmallIntegerField(
|
family = models.PositiveSmallIntegerField(
|
||||||
choices=AF_CHOICES,
|
choices=IPAddressFamilyChoices,
|
||||||
editable=False
|
editable=False
|
||||||
)
|
)
|
||||||
prefix = IPNetworkField(
|
prefix = IPNetworkField(
|
||||||
@ -570,7 +563,7 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel):
|
|||||||
which has a NAT outside IP, that Interface's Device can use either the inside or outside IP as its primary IP.
|
which has a NAT outside IP, that Interface's Device can use either the inside or outside IP as its primary IP.
|
||||||
"""
|
"""
|
||||||
family = models.PositiveSmallIntegerField(
|
family = models.PositiveSmallIntegerField(
|
||||||
choices=AF_CHOICES,
|
choices=IPAddressFamilyChoices,
|
||||||
editable=False
|
editable=False
|
||||||
)
|
)
|
||||||
address = IPAddressField(
|
address = IPAddressField(
|
||||||
|
@ -264,6 +264,7 @@ class AggregateTest(APITestCase):
|
|||||||
url = reverse('ipam-api:aggregate-detail', kwargs={'pk': self.aggregate1.pk})
|
url = reverse('ipam-api:aggregate-detail', kwargs={'pk': self.aggregate1.pk})
|
||||||
response = self.client.get(url, **self.header)
|
response = self.client.get(url, **self.header)
|
||||||
|
|
||||||
|
self.assertEqual(response.data['family']['value'], 4)
|
||||||
self.assertEqual(response.data['prefix'], str(self.aggregate1.prefix))
|
self.assertEqual(response.data['prefix'], str(self.aggregate1.prefix))
|
||||||
|
|
||||||
def test_list_aggregates(self):
|
def test_list_aggregates(self):
|
||||||
@ -470,6 +471,7 @@ class PrefixTest(APITestCase):
|
|||||||
url = reverse('ipam-api:prefix-detail', kwargs={'pk': self.prefix1.pk})
|
url = reverse('ipam-api:prefix-detail', kwargs={'pk': self.prefix1.pk})
|
||||||
response = self.client.get(url, **self.header)
|
response = self.client.get(url, **self.header)
|
||||||
|
|
||||||
|
self.assertEqual(response.data['family']['value'], 4)
|
||||||
self.assertEqual(response.data['prefix'], str(self.prefix1.prefix))
|
self.assertEqual(response.data['prefix'], str(self.prefix1.prefix))
|
||||||
|
|
||||||
def test_list_prefixes(self):
|
def test_list_prefixes(self):
|
||||||
@ -706,6 +708,7 @@ class IPAddressTest(APITestCase):
|
|||||||
url = reverse('ipam-api:ipaddress-detail', kwargs={'pk': self.ipaddress1.pk})
|
url = reverse('ipam-api:ipaddress-detail', kwargs={'pk': self.ipaddress1.pk})
|
||||||
response = self.client.get(url, **self.header)
|
response = self.client.get(url, **self.header)
|
||||||
|
|
||||||
|
self.assertEqual(response.data['family']['value'], 4)
|
||||||
self.assertEqual(response.data['address'], str(self.ipaddress1.address))
|
self.assertEqual(response.data['address'], str(self.ipaddress1.address))
|
||||||
|
|
||||||
def test_list_ipaddresss(self):
|
def test_list_ipaddresss(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user