ip.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. from django.contrib.contenttypes.models import ContentType
  2. from rest_framework import serializers
  3. from dcim.constants import LOCATION_SCOPE_TYPES
  4. from ipam.choices import *
  5. from ipam.constants import IPADDRESS_ASSIGNMENT_MODELS
  6. from ipam.models import Aggregate, IPAddress, IPRange, Prefix
  7. from netbox.api.fields import ChoiceField, ContentTypeField
  8. from netbox.api.gfk_fields import GFKSerializerField
  9. from netbox.api.serializers import PrimaryModelSerializer
  10. from tenancy.api.serializers_.tenants import TenantSerializer
  11. from .asns import RIRSerializer
  12. from .nested import NestedIPAddressSerializer
  13. from .roles import RoleSerializer
  14. from .vlans import VLANSerializer
  15. from .vrfs import VRFSerializer
  16. from ..field_serializers import IPAddressField, IPNetworkField
  17. __all__ = (
  18. 'AggregateSerializer',
  19. 'AvailableIPSerializer',
  20. 'AvailablePrefixSerializer',
  21. 'IPAddressSerializer',
  22. 'IPRangeSerializer',
  23. 'PrefixLengthSerializer',
  24. 'PrefixSerializer',
  25. )
  26. class AggregateSerializer(PrimaryModelSerializer):
  27. family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
  28. rir = RIRSerializer(nested=True)
  29. tenant = TenantSerializer(nested=True, required=False, allow_null=True)
  30. prefix = IPNetworkField()
  31. class Meta:
  32. model = Aggregate
  33. fields = [
  34. 'id', 'url', 'display_url', 'display', 'family', 'prefix', 'rir', 'tenant', 'date_added', 'description',
  35. 'owner', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
  36. ]
  37. brief_fields = ('id', 'url', 'display', 'family', 'prefix', 'description')
  38. class PrefixSerializer(PrimaryModelSerializer):
  39. family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
  40. vrf = VRFSerializer(nested=True, required=False, allow_null=True)
  41. scope_type = ContentTypeField(
  42. queryset=ContentType.objects.filter(
  43. model__in=LOCATION_SCOPE_TYPES
  44. ),
  45. allow_null=True,
  46. required=False,
  47. default=None
  48. )
  49. scope_id = serializers.IntegerField(allow_null=True, required=False, default=None)
  50. scope = GFKSerializerField(read_only=True)
  51. tenant = TenantSerializer(nested=True, required=False, allow_null=True)
  52. vlan = VLANSerializer(nested=True, required=False, allow_null=True)
  53. status = ChoiceField(choices=PrefixStatusChoices, required=False)
  54. role = RoleSerializer(nested=True, required=False, allow_null=True)
  55. _children = serializers.IntegerField(read_only=True)
  56. _depth = serializers.IntegerField(read_only=True)
  57. prefix = IPNetworkField()
  58. class Meta:
  59. model = Prefix
  60. fields = [
  61. 'id', 'url', 'display_url', 'display', 'family', 'aggregate', 'parent', 'prefix', 'vrf', 'scope_type',
  62. 'scope_id', 'scope', 'tenant', 'vlan', 'status', 'role', 'is_pool', 'mark_utilized', 'description',
  63. 'owner', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', '_children', '_depth',
  64. ]
  65. brief_fields = ('id', 'url', 'display', 'family', 'aggregate', 'parent', 'prefix', 'description', '_depth')
  66. def get_fields(self):
  67. fields = super(PrefixSerializer, self).get_fields()
  68. fields['parent'] = PrefixSerializer(nested=True, read_only=True)
  69. return fields
  70. class PrefixLengthSerializer(serializers.Serializer):
  71. prefix_length = serializers.IntegerField()
  72. def to_internal_value(self, data):
  73. requested_prefix = data.get('prefix_length')
  74. if requested_prefix is None:
  75. raise serializers.ValidationError({
  76. 'prefix_length': 'this field can not be missing'
  77. })
  78. if not isinstance(requested_prefix, int):
  79. raise serializers.ValidationError({
  80. 'prefix_length': 'this field must be int type'
  81. })
  82. prefix = self.context.get('prefix')
  83. if prefix.family == 4 and requested_prefix > 32:
  84. raise serializers.ValidationError({
  85. 'prefix_length': 'Invalid prefix length ({}) for IPv4'.format(requested_prefix)
  86. })
  87. elif prefix.family == 6 and requested_prefix > 128:
  88. raise serializers.ValidationError({
  89. 'prefix_length': 'Invalid prefix length ({}) for IPv6'.format(requested_prefix)
  90. })
  91. return data
  92. class AvailablePrefixSerializer(serializers.Serializer):
  93. """
  94. Representation of a prefix which does not exist in the database.
  95. """
  96. family = serializers.IntegerField(read_only=True)
  97. prefix = serializers.CharField(read_only=True)
  98. vrf = VRFSerializer(nested=True, read_only=True, allow_null=True)
  99. def to_representation(self, instance):
  100. if self.context.get('vrf'):
  101. vrf = VRFSerializer(self.context['vrf'], nested=True, context={'request': self.context['request']}).data
  102. else:
  103. vrf = None
  104. return {
  105. 'family': instance.version,
  106. 'prefix': str(instance),
  107. 'vrf': vrf,
  108. }
  109. #
  110. # IP ranges
  111. #
  112. class IPRangeSerializer(PrimaryModelSerializer):
  113. prefix = PrefixSerializer(nested=True, required=False, allow_null=True)
  114. family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
  115. start_address = IPAddressField()
  116. end_address = IPAddressField()
  117. vrf = VRFSerializer(nested=True, required=False, allow_null=True)
  118. tenant = TenantSerializer(nested=True, required=False, allow_null=True)
  119. status = ChoiceField(choices=IPRangeStatusChoices, required=False)
  120. role = RoleSerializer(nested=True, required=False, allow_null=True)
  121. class Meta:
  122. model = IPRange
  123. fields = [
  124. 'id', 'url', 'display_url', 'display', 'family', 'prefix', 'start_address', 'end_address', 'size', 'vrf',
  125. 'tenant', 'status', 'role', 'description', 'owner', 'comments', 'tags', 'custom_fields', 'created',
  126. 'last_updated', 'mark_populated', 'mark_utilized',
  127. ]
  128. brief_fields = ('id', 'url', 'display', 'family', 'prefix', 'start_address', 'end_address', 'description')
  129. #
  130. # IP addresses
  131. #
  132. class IPAddressSerializer(PrimaryModelSerializer):
  133. prefix = PrefixSerializer(nested=True, required=False, allow_null=True)
  134. family = ChoiceField(choices=IPAddressFamilyChoices, read_only=True)
  135. address = IPAddressField()
  136. vrf = VRFSerializer(nested=True, required=False, allow_null=True)
  137. tenant = TenantSerializer(nested=True, required=False, allow_null=True)
  138. status = ChoiceField(choices=IPAddressStatusChoices, required=False)
  139. role = ChoiceField(choices=IPAddressRoleChoices, allow_blank=True, required=False)
  140. assigned_object_type = ContentTypeField(
  141. queryset=ContentType.objects.filter(IPADDRESS_ASSIGNMENT_MODELS),
  142. required=False,
  143. allow_null=True
  144. )
  145. assigned_object = GFKSerializerField(read_only=True)
  146. nat_inside = NestedIPAddressSerializer(required=False, allow_null=True)
  147. nat_outside = NestedIPAddressSerializer(many=True, read_only=True)
  148. class Meta:
  149. model = IPAddress
  150. fields = [
  151. 'id', 'url', 'display_url', 'display', 'family', 'prefix', 'address', 'vrf', 'tenant', 'status', 'role',
  152. 'assigned_object_type', 'assigned_object_id', 'assigned_object', 'nat_inside', 'nat_outside',
  153. 'dns_name', 'description', 'owner', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
  154. ]
  155. brief_fields = ('id', 'url', 'display', 'family', 'prefix', 'address', 'description')
  156. class AvailableIPSerializer(serializers.Serializer):
  157. """
  158. Representation of an IP address which does not exist in the database.
  159. """
  160. family = serializers.IntegerField(read_only=True)
  161. address = serializers.CharField(read_only=True)
  162. vrf = VRFSerializer(nested=True, read_only=True, allow_null=True)
  163. description = serializers.CharField(required=False)
  164. def to_representation(self, instance):
  165. if self.context.get('vrf'):
  166. vrf = VRFSerializer(self.context['vrf'], nested=True, context={'request': self.context['request']}).data
  167. else:
  168. vrf = None
  169. return {
  170. 'family': self.context['parent'].family,
  171. 'address': f"{instance}/{self.context['parent'].mask_length}",
  172. 'vrf': vrf,
  173. }