views.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. from __future__ import unicode_literals
  2. from rest_framework import status
  3. from rest_framework.decorators import detail_route
  4. from rest_framework.exceptions import PermissionDenied
  5. from rest_framework.response import Response
  6. from rest_framework.viewsets import ModelViewSet
  7. from django.conf import settings
  8. from django.shortcuts import get_object_or_404
  9. from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF
  10. from ipam import filters
  11. from extras.api.views import CustomFieldModelViewSet
  12. from utilities.api import FieldChoicesViewSet, WritableSerializerMixin
  13. from . import serializers
  14. #
  15. # Field choices
  16. #
  17. class IPAMFieldChoicesViewSet(FieldChoicesViewSet):
  18. fields = (
  19. (Aggregate, ['family']),
  20. (Prefix, ['family', 'status']),
  21. (IPAddress, ['family', 'status', 'role']),
  22. (VLAN, ['status']),
  23. (Service, ['protocol']),
  24. )
  25. #
  26. # VRFs
  27. #
  28. class VRFViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
  29. queryset = VRF.objects.select_related('tenant')
  30. serializer_class = serializers.VRFSerializer
  31. write_serializer_class = serializers.WritableVRFSerializer
  32. filter_class = filters.VRFFilter
  33. #
  34. # RIRs
  35. #
  36. class RIRViewSet(ModelViewSet):
  37. queryset = RIR.objects.all()
  38. serializer_class = serializers.RIRSerializer
  39. filter_class = filters.RIRFilter
  40. #
  41. # Aggregates
  42. #
  43. class AggregateViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
  44. queryset = Aggregate.objects.select_related('rir')
  45. serializer_class = serializers.AggregateSerializer
  46. write_serializer_class = serializers.WritableAggregateSerializer
  47. filter_class = filters.AggregateFilter
  48. #
  49. # Roles
  50. #
  51. class RoleViewSet(ModelViewSet):
  52. queryset = Role.objects.all()
  53. serializer_class = serializers.RoleSerializer
  54. filter_class = filters.RoleFilter
  55. #
  56. # Prefixes
  57. #
  58. class PrefixViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
  59. queryset = Prefix.objects.select_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role')
  60. serializer_class = serializers.PrefixSerializer
  61. write_serializer_class = serializers.WritablePrefixSerializer
  62. filter_class = filters.PrefixFilter
  63. @detail_route(url_path='available-ips', methods=['get', 'post'])
  64. def available_ips(self, request, pk=None):
  65. """
  66. A convenience method for returning available IP addresses within a prefix. By default, the number of IPs
  67. returned will be equivalent to PAGINATE_COUNT. An arbitrary limit (up to MAX_PAGE_SIZE, if set) may be passed,
  68. however results will not be paginated.
  69. """
  70. prefix = get_object_or_404(Prefix, pk=pk)
  71. # Create the next available IP within the prefix
  72. if request.method == 'POST':
  73. # Permissions check
  74. if not request.user.has_perm('ipam.add_ipaddress'):
  75. raise PermissionDenied()
  76. # Find the first available IP address in the prefix
  77. try:
  78. ipaddress = list(prefix.get_available_ips())[0]
  79. except IndexError:
  80. return Response(
  81. {
  82. "detail": "There are no available IPs within this prefix ({})".format(prefix)
  83. },
  84. status=status.HTTP_400_BAD_REQUEST
  85. )
  86. # Create the new IP address
  87. data = request.data.copy()
  88. data['address'] = '{}/{}'.format(ipaddress, prefix.prefix.prefixlen)
  89. data['vrf'] = prefix.vrf.pk if prefix.vrf else None
  90. serializer = serializers.WritableIPAddressSerializer(data=data)
  91. if serializer.is_valid():
  92. serializer.save()
  93. return Response(serializer.data, status=status.HTTP_201_CREATED)
  94. return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
  95. # Determine the maximum amount of IPs to return
  96. else:
  97. try:
  98. limit = int(request.query_params.get('limit', settings.PAGINATE_COUNT))
  99. except ValueError:
  100. limit = settings.PAGINATE_COUNT
  101. if settings.MAX_PAGE_SIZE:
  102. limit = min(limit, settings.MAX_PAGE_SIZE)
  103. # Calculate available IPs within the prefix
  104. ip_list = []
  105. for index, ip in enumerate(prefix.get_available_ips(), start=1):
  106. ip_list.append(ip)
  107. if index == limit:
  108. break
  109. serializer = serializers.AvailableIPSerializer(ip_list, many=True, context={
  110. 'request': request,
  111. 'prefix': prefix.prefix,
  112. 'vrf': prefix.vrf,
  113. })
  114. return Response(serializer.data)
  115. #
  116. # IP addresses
  117. #
  118. class IPAddressViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
  119. queryset = IPAddress.objects.select_related(
  120. 'vrf__tenant', 'tenant', 'nat_inside'
  121. ).prefetch_related(
  122. 'interface__device', 'interface__virtual_machine'
  123. )
  124. serializer_class = serializers.IPAddressSerializer
  125. write_serializer_class = serializers.WritableIPAddressSerializer
  126. filter_class = filters.IPAddressFilter
  127. #
  128. # VLAN groups
  129. #
  130. class VLANGroupViewSet(WritableSerializerMixin, ModelViewSet):
  131. queryset = VLANGroup.objects.select_related('site')
  132. serializer_class = serializers.VLANGroupSerializer
  133. write_serializer_class = serializers.WritableVLANGroupSerializer
  134. filter_class = filters.VLANGroupFilter
  135. #
  136. # VLANs
  137. #
  138. class VLANViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
  139. queryset = VLAN.objects.select_related('site', 'group', 'tenant', 'role')
  140. serializer_class = serializers.VLANSerializer
  141. write_serializer_class = serializers.WritableVLANSerializer
  142. filter_class = filters.VLANFilter
  143. #
  144. # Services
  145. #
  146. class ServiceViewSet(WritableSerializerMixin, ModelViewSet):
  147. queryset = Service.objects.select_related('device')
  148. serializer_class = serializers.ServiceSerializer
  149. write_serializer_class = serializers.WritableServiceSerializer
  150. filter_class = filters.ServiceFilter