1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Closes #9608: Move from drf-yasg to spectacular

Co-authored-by: arthanson <worldnomad@gmail.com>
Co-authored-by: jeremystretch <jstretch@netboxlabs.com>
This commit is contained in:
Arthur Hanson
2023-03-30 11:32:59 -07:00
committed by GitHub
parent 1be626e5ee
commit ecd0c56554
35 changed files with 514 additions and 340 deletions

View File

@@ -1,3 +1,4 @@
from drf_spectacular.utils import extend_schema_serializer
from rest_framework import serializers
from ipam import models
@@ -54,6 +55,9 @@ class NestedASNSerializer(WritableNestedSerializer):
# VRFs
#
@extend_schema_serializer(
exclude_fields=('prefix_count',),
)
class NestedVRFSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vrf-detail')
prefix_count = serializers.IntegerField(read_only=True)
@@ -79,6 +83,9 @@ class NestedRouteTargetSerializer(WritableNestedSerializer):
# RIRs/aggregates
#
@extend_schema_serializer(
exclude_fields=('aggregate_count',),
)
class NestedRIRSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:rir-detail')
aggregate_count = serializers.IntegerField(read_only=True)
@@ -121,6 +128,9 @@ class NestedFHRPGroupAssignmentSerializer(WritableNestedSerializer):
# VLANs
#
@extend_schema_serializer(
exclude_fields=('prefix_count', 'vlan_count'),
)
class NestedRoleSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:role-detail')
prefix_count = serializers.IntegerField(read_only=True)
@@ -131,6 +141,9 @@ class NestedRoleSerializer(WritableNestedSerializer):
fields = ['id', 'url', 'display', 'name', 'slug', 'prefix_count', 'vlan_count']
@extend_schema_serializer(
exclude_fields=('vlan_count',),
)
class NestedVLANGroupSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlangroup-detail')
vlan_count = serializers.IntegerField(read_only=True)

View File

@@ -1,5 +1,5 @@
from django.contrib.contenttypes.models import ContentType
from drf_yasg.utils import swagger_serializer_method
from drf_spectacular.utils import extend_schema_field
from rest_framework import serializers
from dcim.api.nested_serializers import NestedDeviceSerializer, NestedSiteSerializer
@@ -136,6 +136,7 @@ class AggregateSerializer(NetBoxModelSerializer):
family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
rir = NestedRIRSerializer()
tenant = NestedTenantSerializer(required=False, allow_null=True)
prefix = serializers.CharField()
class Meta:
model = Aggregate
@@ -177,7 +178,7 @@ class FHRPGroupAssignmentSerializer(NetBoxModelSerializer):
'last_updated',
]
@swagger_serializer_method(serializer_or_field=serializers.JSONField)
@extend_schema_field(serializers.JSONField(allow_null=True))
def get_interface(self, obj):
if obj.interface is None:
return None
@@ -225,7 +226,7 @@ class VLANGroupSerializer(NetBoxModelSerializer):
]
validators = []
@swagger_serializer_method(serializer_or_field=serializers.JSONField)
@extend_schema_field(serializers.JSONField(allow_null=True))
def get_scope(self, obj):
if obj.scope_id is None:
return None
@@ -242,7 +243,7 @@ class VLANSerializer(NetBoxModelSerializer):
tenant = NestedTenantSerializer(required=False, allow_null=True)
status = ChoiceField(choices=VLANStatusChoices, required=False)
role = NestedRoleSerializer(required=False, allow_null=True)
l2vpn_termination = NestedL2VPNTerminationSerializer(read_only=True)
l2vpn_termination = NestedL2VPNTerminationSerializer(read_only=True, allow_null=True)
prefix_count = serializers.IntegerField(read_only=True)
class Meta:
@@ -302,6 +303,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()
class Meta:
model = Prefix
@@ -371,13 +373,13 @@ class IPRangeSerializer(NetBoxModelSerializer):
tenant = NestedTenantSerializer(required=False, allow_null=True)
status = ChoiceField(choices=IPRangeStatusChoices, required=False)
role = NestedRoleSerializer(required=False, allow_null=True)
children = serializers.IntegerField(read_only=True)
class Meta:
model = IPRange
fields = [
'id', 'url', 'display', 'family', 'start_address', 'end_address', 'size', 'vrf', 'tenant', 'status', 'role',
'mark_utilized', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'children',
'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
'mark_utilized', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
]
read_only_fields = ['family']
@@ -392,7 +394,7 @@ class IPAddressSerializer(NetBoxModelSerializer):
vrf = NestedVRFSerializer(required=False, allow_null=True)
tenant = NestedTenantSerializer(required=False, allow_null=True)
status = ChoiceField(choices=IPAddressStatusChoices, required=False)
role = ChoiceField(choices=IPAddressRoleChoices, allow_blank=True, required=False)
role = ChoiceField(choices=IPAddressRoleChoices, allow_blank=True, required=False, allow_null=True)
assigned_object_type = ContentTypeField(
queryset=ContentType.objects.filter(IPADDRESS_ASSIGNMENT_MODELS),
required=False,
@@ -410,7 +412,7 @@ class IPAddressSerializer(NetBoxModelSerializer):
'tags', 'custom_fields', 'created', 'last_updated',
]
@swagger_serializer_method(serializer_or_field=serializers.JSONField)
@extend_schema_field(serializers.JSONField(allow_null=True))
def get_assigned_object(self, obj):
if obj.assigned_object is None:
return None
@@ -519,7 +521,7 @@ class L2VPNTerminationSerializer(NetBoxModelSerializer):
'assigned_object', 'tags', 'custom_fields', 'created', 'last_updated'
]
@swagger_serializer_method(serializer_or_field=serializers.JSONField)
@extend_schema_field(serializers.JSONField(allow_null=True))
def get_assigned_object(self, instance):
serializer = get_serializer_for_model(instance.assigned_object, prefix=NESTED_SERIALIZER_PREFIX)
context = {'request': self.context['request']}

View File

@@ -2,7 +2,7 @@ from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
from django.db import transaction
from django.shortcuts import get_object_or_404
from django_pglocks import advisory_lock
from drf_yasg.utils import swagger_auto_schema
from drf_spectacular.utils import extend_schema, extend_schema_view
from rest_framework import status
from rest_framework.response import Response
from rest_framework.routers import APIRootView
@@ -210,7 +210,7 @@ def get_results_limit(request):
class AvailableASNsView(ObjectValidationMixin, APIView):
queryset = ASN.objects.all()
@swagger_auto_schema(responses={200: serializers.AvailableASNSerializer(many=True)})
@extend_schema(methods=["get"], responses={200: serializers.AvailableASNSerializer(many=True)})
def get(self, request, pk):
asnrange = get_object_or_404(ASNRange.objects.restrict(request.user), pk=pk)
limit = get_results_limit(request)
@@ -224,10 +224,7 @@ class AvailableASNsView(ObjectValidationMixin, APIView):
return Response(serializer.data)
@swagger_auto_schema(
request_body=serializers.AvailableASNSerializer,
responses={201: serializers.ASNSerializer(many=True)}
)
@extend_schema(methods=["post"], responses={201: serializers.ASNSerializer(many=True)})
@advisory_lock(ADVISORY_LOCK_KEYS['available-asns'])
def post(self, request, pk):
self.queryset = self.queryset.restrict(request.user, 'add')
@@ -274,11 +271,17 @@ class AvailableASNsView(ObjectValidationMixin, APIView):
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def get_serializer_class(self):
if self.request.method == "GET":
return serializers.AvailableASNSerializer
return serializers.ASNSerializer
class AvailablePrefixesView(ObjectValidationMixin, APIView):
queryset = Prefix.objects.all()
@swagger_auto_schema(responses={200: serializers.AvailablePrefixSerializer(many=True)})
@extend_schema(methods=["get"], responses={200: serializers.AvailablePrefixSerializer(many=True)})
def get(self, request, pk):
prefix = get_object_or_404(Prefix.objects.restrict(request.user), pk=pk)
available_prefixes = prefix.get_available_prefixes()
@@ -290,10 +293,7 @@ class AvailablePrefixesView(ObjectValidationMixin, APIView):
return Response(serializer.data)
@swagger_auto_schema(
request_body=serializers.PrefixLengthSerializer,
responses={201: serializers.PrefixSerializer(many=True)}
)
@extend_schema(methods=["post"], responses={201: serializers.PrefixSerializer(many=True)})
@advisory_lock(ADVISORY_LOCK_KEYS['available-prefixes'])
def post(self, request, pk):
self.queryset = self.queryset.restrict(request.user, 'add')
@@ -356,6 +356,12 @@ class AvailablePrefixesView(ObjectValidationMixin, APIView):
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def get_serializer_class(self):
if self.request.method == "GET":
return serializers.AvailablePrefixSerializer
return serializers.PrefixLengthSerializer
class AvailableIPAddressesView(ObjectValidationMixin, APIView):
queryset = IPAddress.objects.all()
@@ -363,7 +369,7 @@ class AvailableIPAddressesView(ObjectValidationMixin, APIView):
def get_parent(self, request, pk):
raise NotImplemented()
@swagger_auto_schema(responses={200: serializers.AvailableIPSerializer(many=True)})
@extend_schema(methods=["get"], responses={200: serializers.AvailableIPSerializer(many=True)})
def get(self, request, pk):
parent = self.get_parent(request, pk)
limit = get_results_limit(request)
@@ -382,10 +388,7 @@ class AvailableIPAddressesView(ObjectValidationMixin, APIView):
return Response(serializer.data)
@swagger_auto_schema(
request_body=serializers.AvailableIPSerializer,
responses={201: serializers.IPAddressSerializer(many=True)}
)
@extend_schema(methods=["post"], responses={201: serializers.IPAddressSerializer(many=True)})
@advisory_lock(ADVISORY_LOCK_KEYS['available-ips'])
def post(self, request, pk):
self.queryset = self.queryset.restrict(request.user, 'add')
@@ -430,6 +433,12 @@ class AvailableIPAddressesView(ObjectValidationMixin, APIView):
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def get_serializer_class(self):
if self.request.method == "GET":
return serializers.AvailableIPSerializer
return serializers.IPAddressSerializer
class PrefixAvailableIPAddressesView(AvailableIPAddressesView):
@@ -446,7 +455,7 @@ class IPRangeAvailableIPAddressesView(AvailableIPAddressesView):
class AvailableVLANsView(ObjectValidationMixin, APIView):
queryset = VLAN.objects.all()
@swagger_auto_schema(responses={200: serializers.AvailableVLANSerializer(many=True)})
@extend_schema(methods=["get"], responses={200: serializers.AvailableVLANSerializer(many=True)})
def get(self, request, pk):
vlangroup = get_object_or_404(VLANGroup.objects.restrict(request.user), pk=pk)
limit = get_results_limit(request)
@@ -459,10 +468,7 @@ class AvailableVLANsView(ObjectValidationMixin, APIView):
return Response(serializer.data)
@swagger_auto_schema(
request_body=serializers.CreateAvailableVLANSerializer,
responses={201: serializers.VLANSerializer(many=True)}
)
@extend_schema(methods=["post"], responses={201: serializers.VLANSerializer(many=True)})
@advisory_lock(ADVISORY_LOCK_KEYS['available-vlans'])
def post(self, request, pk):
self.queryset = self.queryset.restrict(request.user, 'add')
@@ -514,3 +520,9 @@ class AvailableVLANsView(ObjectValidationMixin, APIView):
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def get_serializer_class(self):
if self.request.method == "GET":
return serializers.AvailableVLANSerializer
return serializers.VLANSerializer