serializers.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. from __future__ import unicode_literals
  2. from collections import OrderedDict
  3. from rest_framework import serializers
  4. from rest_framework.validators import UniqueTogetherValidator
  5. from dcim.api.serializers import NestedDeviceSerializer, InterfaceSerializer, NestedSiteSerializer
  6. from extras.api.customfields import CustomFieldModelSerializer
  7. from ipam.models import (
  8. Aggregate, IPAddress, IPADDRESS_ROLE_CHOICES, IPADDRESS_STATUS_CHOICES, IP_PROTOCOL_CHOICES, Prefix,
  9. PREFIX_STATUS_CHOICES, RIR, Role, Service, VLAN, VLAN_STATUS_CHOICES, VLANGroup, VRF,
  10. )
  11. from tenancy.api.serializers import NestedTenantSerializer
  12. from utilities.api import ChoiceFieldSerializer, ValidatedModelSerializer
  13. from virtualization.api.serializers import NestedVirtualMachineSerializer
  14. #
  15. # VRFs
  16. #
  17. class VRFSerializer(CustomFieldModelSerializer):
  18. tenant = NestedTenantSerializer()
  19. class Meta:
  20. model = VRF
  21. fields = ['id', 'name', 'rd', 'tenant', 'enforce_unique', 'description', 'display_name', 'custom_fields']
  22. class NestedVRFSerializer(serializers.ModelSerializer):
  23. url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vrf-detail')
  24. class Meta:
  25. model = VRF
  26. fields = ['id', 'url', 'name', 'rd']
  27. class WritableVRFSerializer(CustomFieldModelSerializer):
  28. class Meta:
  29. model = VRF
  30. fields = ['id', 'name', 'rd', 'tenant', 'enforce_unique', 'description', 'custom_fields']
  31. #
  32. # Roles
  33. #
  34. class RoleSerializer(ValidatedModelSerializer):
  35. class Meta:
  36. model = Role
  37. fields = ['id', 'name', 'slug', 'weight']
  38. class NestedRoleSerializer(serializers.ModelSerializer):
  39. url = serializers.HyperlinkedIdentityField(view_name='ipam-api:role-detail')
  40. class Meta:
  41. model = Role
  42. fields = ['id', 'url', 'name', 'slug']
  43. #
  44. # RIRs
  45. #
  46. class RIRSerializer(ValidatedModelSerializer):
  47. class Meta:
  48. model = RIR
  49. fields = ['id', 'name', 'slug', 'is_private']
  50. class NestedRIRSerializer(serializers.ModelSerializer):
  51. url = serializers.HyperlinkedIdentityField(view_name='ipam-api:rir-detail')
  52. class Meta:
  53. model = RIR
  54. fields = ['id', 'url', 'name', 'slug']
  55. #
  56. # Aggregates
  57. #
  58. class AggregateSerializer(CustomFieldModelSerializer):
  59. rir = NestedRIRSerializer()
  60. class Meta:
  61. model = Aggregate
  62. fields = ['id', 'family', 'prefix', 'rir', 'date_added', 'description', 'custom_fields']
  63. class NestedAggregateSerializer(serializers.ModelSerializer):
  64. url = serializers.HyperlinkedIdentityField(view_name='ipam-api:aggregate-detail')
  65. class Meta(AggregateSerializer.Meta):
  66. model = Aggregate
  67. fields = ['id', 'url', 'family', 'prefix']
  68. class WritableAggregateSerializer(CustomFieldModelSerializer):
  69. class Meta:
  70. model = Aggregate
  71. fields = ['id', 'prefix', 'rir', 'date_added', 'description', 'custom_fields']
  72. #
  73. # VLAN groups
  74. #
  75. class VLANGroupSerializer(serializers.ModelSerializer):
  76. site = NestedSiteSerializer()
  77. class Meta:
  78. model = VLANGroup
  79. fields = ['id', 'name', 'slug', 'site']
  80. class NestedVLANGroupSerializer(serializers.ModelSerializer):
  81. url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlangroup-detail')
  82. class Meta:
  83. model = VLANGroup
  84. fields = ['id', 'url', 'name', 'slug']
  85. class WritableVLANGroupSerializer(serializers.ModelSerializer):
  86. class Meta:
  87. model = VLANGroup
  88. fields = ['id', 'name', 'slug', 'site']
  89. validators = []
  90. def validate(self, data):
  91. # Validate uniqueness of name and slug if a site has been assigned.
  92. if data.get('site', None):
  93. for field in ['name', 'slug']:
  94. validator = UniqueTogetherValidator(queryset=VLANGroup.objects.all(), fields=('site', field))
  95. validator.set_context(self)
  96. validator(data)
  97. # Enforce model validation
  98. super(WritableVLANGroupSerializer, self).validate(data)
  99. return data
  100. #
  101. # VLANs
  102. #
  103. class VLANSerializer(CustomFieldModelSerializer):
  104. site = NestedSiteSerializer()
  105. group = NestedVLANGroupSerializer()
  106. tenant = NestedTenantSerializer()
  107. status = ChoiceFieldSerializer(choices=VLAN_STATUS_CHOICES)
  108. role = NestedRoleSerializer()
  109. class Meta:
  110. model = VLAN
  111. fields = [
  112. 'id', 'site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description', 'display_name',
  113. 'custom_fields',
  114. ]
  115. class NestedVLANSerializer(serializers.ModelSerializer):
  116. url = serializers.HyperlinkedIdentityField(view_name='ipam-api:vlan-detail')
  117. class Meta:
  118. model = VLAN
  119. fields = ['id', 'url', 'vid', 'name', 'display_name']
  120. class WritableVLANSerializer(CustomFieldModelSerializer):
  121. class Meta:
  122. model = VLAN
  123. fields = ['id', 'site', 'group', 'vid', 'name', 'tenant', 'status', 'role', 'description', 'custom_fields']
  124. validators = []
  125. def validate(self, data):
  126. # Validate uniqueness of vid and name if a group has been assigned.
  127. if data.get('group', None):
  128. for field in ['vid', 'name']:
  129. validator = UniqueTogetherValidator(queryset=VLAN.objects.all(), fields=('group', field))
  130. validator.set_context(self)
  131. validator(data)
  132. # Enforce model validation
  133. super(WritableVLANSerializer, self).validate(data)
  134. return data
  135. #
  136. # Prefixes
  137. #
  138. class PrefixSerializer(CustomFieldModelSerializer):
  139. site = NestedSiteSerializer()
  140. vrf = NestedVRFSerializer()
  141. tenant = NestedTenantSerializer()
  142. vlan = NestedVLANSerializer()
  143. status = ChoiceFieldSerializer(choices=PREFIX_STATUS_CHOICES)
  144. role = NestedRoleSerializer()
  145. class Meta:
  146. model = Prefix
  147. fields = [
  148. 'id', 'family', 'prefix', 'site', 'vrf', 'tenant', 'vlan', 'status', 'role', 'is_pool', 'description',
  149. 'custom_fields',
  150. ]
  151. class NestedPrefixSerializer(serializers.ModelSerializer):
  152. url = serializers.HyperlinkedIdentityField(view_name='ipam-api:prefix-detail')
  153. class Meta:
  154. model = Prefix
  155. fields = ['id', 'url', 'family', 'prefix']
  156. class WritablePrefixSerializer(CustomFieldModelSerializer):
  157. class Meta:
  158. model = Prefix
  159. fields = [
  160. 'id', 'prefix', 'site', 'vrf', 'tenant', 'vlan', 'status', 'role', 'is_pool', 'description',
  161. 'custom_fields',
  162. ]
  163. #
  164. # IP addresses
  165. #
  166. class IPAddressSerializer(CustomFieldModelSerializer):
  167. vrf = NestedVRFSerializer()
  168. tenant = NestedTenantSerializer()
  169. status = ChoiceFieldSerializer(choices=IPADDRESS_STATUS_CHOICES)
  170. role = ChoiceFieldSerializer(choices=IPADDRESS_ROLE_CHOICES)
  171. interface = InterfaceSerializer()
  172. class Meta:
  173. model = IPAddress
  174. fields = [
  175. 'id', 'family', 'address', 'vrf', 'tenant', 'status', 'role', 'interface', 'description', 'nat_inside',
  176. 'nat_outside', 'custom_fields',
  177. ]
  178. class NestedIPAddressSerializer(serializers.ModelSerializer):
  179. url = serializers.HyperlinkedIdentityField(view_name='ipam-api:ipaddress-detail')
  180. class Meta:
  181. model = IPAddress
  182. fields = ['id', 'url', 'family', 'address']
  183. IPAddressSerializer._declared_fields['nat_inside'] = NestedIPAddressSerializer()
  184. IPAddressSerializer._declared_fields['nat_outside'] = NestedIPAddressSerializer()
  185. class WritableIPAddressSerializer(CustomFieldModelSerializer):
  186. class Meta:
  187. model = IPAddress
  188. fields = [
  189. 'id', 'address', 'vrf', 'tenant', 'status', 'role', 'interface', 'description', 'nat_inside',
  190. 'custom_fields',
  191. ]
  192. class AvailableIPSerializer(serializers.Serializer):
  193. def to_representation(self, instance):
  194. if self.context.get('vrf'):
  195. vrf = NestedVRFSerializer(self.context['vrf'], context={'request': self.context['request']}).data
  196. else:
  197. vrf = None
  198. return OrderedDict([
  199. ('family', self.context['prefix'].version),
  200. ('address', '{}/{}'.format(instance, self.context['prefix'].prefixlen)),
  201. ('vrf', vrf),
  202. ])
  203. #
  204. # Services
  205. #
  206. class ServiceSerializer(serializers.ModelSerializer):
  207. device = NestedDeviceSerializer()
  208. virtual_machine = NestedVirtualMachineSerializer()
  209. protocol = ChoiceFieldSerializer(choices=IP_PROTOCOL_CHOICES)
  210. ipaddresses = NestedIPAddressSerializer(many=True)
  211. class Meta:
  212. model = Service
  213. fields = ['id', 'device', 'virtual_machine', 'name', 'port', 'protocol', 'ipaddresses', 'description']
  214. # TODO: Figure out how to use model validation with ManyToManyFields. Calling clean() yields a ValueError.
  215. class WritableServiceSerializer(serializers.ModelSerializer):
  216. class Meta:
  217. model = Service
  218. fields = ['id', 'device', 'virtual_machine', 'name', 'port', 'protocol', 'ipaddresses', 'description']