serializers.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. from rest_framework import serializers
  2. from ipam.models import IPAddress
  3. from dcim.models import (
  4. CONNECTION_STATUS_CHOICES, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device,
  5. DeviceBay, DeviceBayTemplate, DeviceType, DeviceRole, IFACE_FF_CHOICES, IFACE_ORDERING_CHOICES, Interface,
  6. InterfaceConnection, InterfaceTemplate, Manufacturer, Module, Platform, PowerOutlet, PowerOutletTemplate, PowerPort,
  7. PowerPortTemplate, Rack, RackGroup, RackReservation, RackRole, RACK_FACE_CHOICES, RACK_TYPE_CHOICES,
  8. RACK_WIDTH_CHOICES, Site, STATUS_CHOICES, SUBDEVICE_ROLE_CHOICES,
  9. )
  10. from extras.api.serializers import CustomFieldModelSerializer
  11. from tenancy.api.serializers import NestedTenantSerializer
  12. from utilities.api import ChoiceFieldSerializer
  13. #
  14. # Sites
  15. #
  16. class SiteSerializer(CustomFieldModelSerializer):
  17. tenant = NestedTenantSerializer()
  18. class Meta:
  19. model = Site
  20. fields = [
  21. 'id', 'name', 'slug', 'tenant', 'facility', 'asn', 'physical_address', 'shipping_address', 'contact_name',
  22. 'contact_phone', 'contact_email', 'comments', 'custom_fields', 'count_prefixes', 'count_vlans',
  23. 'count_racks', 'count_devices', 'count_circuits',
  24. ]
  25. class NestedSiteSerializer(serializers.ModelSerializer):
  26. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:site-detail')
  27. class Meta:
  28. model = Site
  29. fields = ['id', 'url', 'name', 'slug']
  30. class WritableSiteSerializer(serializers.ModelSerializer):
  31. class Meta:
  32. model = Site
  33. fields = [
  34. 'id', 'name', 'slug', 'tenant', 'facility', 'asn', 'physical_address', 'shipping_address', 'contact_name',
  35. 'contact_phone', 'contact_email', 'comments',
  36. ]
  37. #
  38. # Rack groups
  39. #
  40. class RackGroupSerializer(serializers.ModelSerializer):
  41. site = NestedSiteSerializer()
  42. class Meta:
  43. model = RackGroup
  44. fields = ['id', 'name', 'slug', 'site']
  45. class NestedRackGroupSerializer(serializers.ModelSerializer):
  46. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackgroup-detail')
  47. class Meta:
  48. model = RackGroup
  49. fields = ['id', 'url', 'name', 'slug']
  50. class WritableRackGroupSerializer(serializers.ModelSerializer):
  51. class Meta:
  52. model = RackGroup
  53. fields = ['id', 'name', 'slug', 'site']
  54. #
  55. # Rack roles
  56. #
  57. class RackRoleSerializer(serializers.ModelSerializer):
  58. class Meta:
  59. model = RackRole
  60. fields = ['id', 'name', 'slug', 'color']
  61. class NestedRackRoleSerializer(serializers.ModelSerializer):
  62. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackrole-detail')
  63. class Meta:
  64. model = RackRole
  65. fields = ['id', 'url', 'name', 'slug']
  66. #
  67. # Racks
  68. #
  69. class RackSerializer(CustomFieldModelSerializer):
  70. site = NestedSiteSerializer()
  71. group = NestedRackGroupSerializer()
  72. tenant = NestedTenantSerializer()
  73. role = NestedRackRoleSerializer()
  74. type = ChoiceFieldSerializer(choices=RACK_TYPE_CHOICES)
  75. width = ChoiceFieldSerializer(choices=RACK_WIDTH_CHOICES)
  76. class Meta:
  77. model = Rack
  78. fields = [
  79. 'id', 'name', 'facility_id', 'display_name', 'site', 'group', 'tenant', 'role', 'type', 'width', 'u_height',
  80. 'desc_units', 'comments', 'custom_fields',
  81. ]
  82. class NestedRackSerializer(serializers.ModelSerializer):
  83. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rack-detail')
  84. class Meta:
  85. model = Rack
  86. fields = ['id', 'url', 'name', 'display_name']
  87. class WritableRackSerializer(serializers.ModelSerializer):
  88. class Meta:
  89. model = Rack
  90. fields = [
  91. 'id', 'name', 'facility_id', 'site', 'group', 'tenant', 'role', 'type', 'width', 'u_height', 'desc_units',
  92. 'comments',
  93. ]
  94. #
  95. # Rack reservations
  96. #
  97. class RackReservationSerializer(serializers.ModelSerializer):
  98. rack = NestedRackSerializer()
  99. class Meta:
  100. model = RackReservation
  101. fields = ['id', 'rack', 'units', 'created', 'user', 'description']
  102. #
  103. # Manufacturers
  104. #
  105. class ManufacturerSerializer(serializers.ModelSerializer):
  106. class Meta:
  107. model = Manufacturer
  108. fields = ['id', 'name', 'slug']
  109. class NestedManufacturerSerializer(serializers.ModelSerializer):
  110. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:manufacturer-detail')
  111. class Meta:
  112. model = Manufacturer
  113. fields = ['id', 'url', 'name', 'slug']
  114. #
  115. # Device types
  116. #
  117. class DeviceTypeSerializer(CustomFieldModelSerializer):
  118. manufacturer = NestedManufacturerSerializer()
  119. interface_ordering = ChoiceFieldSerializer(choices=IFACE_ORDERING_CHOICES)
  120. subdevice_role = ChoiceFieldSerializer(choices=SUBDEVICE_ROLE_CHOICES)
  121. instance_count = serializers.IntegerField(source='instances.count', read_only=True)
  122. class Meta:
  123. model = DeviceType
  124. fields = [
  125. 'id', 'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'interface_ordering',
  126. 'is_console_server', 'is_pdu', 'is_network_device', 'subdevice_role', 'comments', 'custom_fields',
  127. 'instance_count',
  128. ]
  129. class NestedDeviceTypeSerializer(serializers.ModelSerializer):
  130. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicetype-detail')
  131. manufacturer = NestedManufacturerSerializer()
  132. class Meta:
  133. model = DeviceType
  134. fields = ['id', 'url', 'manufacturer', 'model', 'slug']
  135. class WritableDeviceTypeSerializer(serializers.ModelSerializer):
  136. class Meta:
  137. model = DeviceType
  138. fields = [
  139. 'id', 'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'interface_ordering',
  140. 'is_console_server', 'is_pdu', 'is_network_device', 'subdevice_role', 'comments',
  141. ]
  142. #
  143. # Console port templates
  144. #
  145. class ConsolePortTemplateSerializer(serializers.ModelSerializer):
  146. device_type = NestedDeviceTypeSerializer()
  147. class Meta:
  148. model = ConsolePortTemplate
  149. fields = ['id', 'device_type', 'name']
  150. class WritableConsolePortTemplateSerializer(serializers.ModelSerializer):
  151. class Meta:
  152. model = ConsolePortTemplate
  153. fields = ['id', 'device_type', 'name']
  154. #
  155. # Console server port templates
  156. #
  157. class ConsoleServerPortTemplateSerializer(serializers.ModelSerializer):
  158. device_type = NestedDeviceTypeSerializer()
  159. class Meta:
  160. model = ConsoleServerPortTemplate
  161. fields = ['id', 'device_type', 'name']
  162. class WritableConsoleServerPortTemplateSerializer(serializers.ModelSerializer):
  163. class Meta:
  164. model = ConsoleServerPortTemplate
  165. fields = ['id', 'device_type', 'name']
  166. #
  167. # Power port templates
  168. #
  169. class PowerPortTemplateSerializer(serializers.ModelSerializer):
  170. device_type = NestedDeviceTypeSerializer()
  171. class Meta:
  172. model = PowerPortTemplate
  173. fields = ['id', 'device_type', 'name']
  174. class WritablePowerPortTemplateSerializer(serializers.ModelSerializer):
  175. class Meta:
  176. model = PowerPortTemplate
  177. fields = ['id', 'device_type', 'name']
  178. #
  179. # Power outlet templates
  180. #
  181. class PowerOutletTemplateSerializer(serializers.ModelSerializer):
  182. device_type = NestedDeviceTypeSerializer()
  183. class Meta:
  184. model = PowerOutletTemplate
  185. fields = ['id', 'device_type', 'name']
  186. class WritablePowerOutletTemplateSerializer(serializers.ModelSerializer):
  187. class Meta:
  188. model = PowerOutletTemplate
  189. fields = ['id', 'device_type', 'name']
  190. #
  191. # Interface templates
  192. #
  193. class InterfaceTemplateSerializer(serializers.ModelSerializer):
  194. device_type = NestedDeviceTypeSerializer()
  195. form_factor = ChoiceFieldSerializer(choices=IFACE_FF_CHOICES)
  196. class Meta:
  197. model = InterfaceTemplate
  198. fields = ['id', 'device_type', 'name', 'form_factor', 'mgmt_only']
  199. class WritableInterfaceTemplateSerializer(serializers.ModelSerializer):
  200. class Meta:
  201. model = InterfaceTemplate
  202. fields = ['id', 'device_type', 'name', 'form_factor', 'mgmt_only']
  203. #
  204. # Device bay templates
  205. #
  206. class DeviceBayTemplateSerializer(serializers.ModelSerializer):
  207. device_type = NestedDeviceTypeSerializer()
  208. class Meta:
  209. model = DeviceBayTemplate
  210. fields = ['id', 'device_type', 'name']
  211. class WritableDeviceBayTemplateSerializer(serializers.ModelSerializer):
  212. class Meta:
  213. model = DeviceBayTemplate
  214. fields = ['id', 'device_type', 'name']
  215. #
  216. # Device roles
  217. #
  218. class DeviceRoleSerializer(serializers.ModelSerializer):
  219. class Meta:
  220. model = DeviceRole
  221. fields = ['id', 'name', 'slug', 'color']
  222. class NestedDeviceRoleSerializer(serializers.ModelSerializer):
  223. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicerole-detail')
  224. class Meta:
  225. model = DeviceRole
  226. fields = ['id', 'url', 'name', 'slug']
  227. #
  228. # Platforms
  229. #
  230. class PlatformSerializer(serializers.ModelSerializer):
  231. class Meta:
  232. model = Platform
  233. fields = ['id', 'name', 'slug', 'rpc_client']
  234. class NestedPlatformSerializer(serializers.ModelSerializer):
  235. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:platform-detail')
  236. class Meta:
  237. model = Platform
  238. fields = ['id', 'url', 'name', 'slug']
  239. #
  240. # Devices
  241. #
  242. # Cannot import ipam.api.NestedIPAddressSerializer due to circular dependency
  243. class DeviceIPAddressSerializer(serializers.ModelSerializer):
  244. url = serializers.HyperlinkedIdentityField(view_name='ipam-api:ipaddress-detail')
  245. class Meta:
  246. model = IPAddress
  247. fields = ['id', 'url', 'family', 'address']
  248. class DeviceSerializer(CustomFieldModelSerializer):
  249. device_type = NestedDeviceTypeSerializer()
  250. device_role = NestedDeviceRoleSerializer()
  251. tenant = NestedTenantSerializer()
  252. platform = NestedPlatformSerializer()
  253. site = NestedSiteSerializer()
  254. rack = NestedRackSerializer()
  255. face = ChoiceFieldSerializer(choices=RACK_FACE_CHOICES)
  256. status = ChoiceFieldSerializer(choices=STATUS_CHOICES)
  257. primary_ip = DeviceIPAddressSerializer()
  258. primary_ip4 = DeviceIPAddressSerializer()
  259. primary_ip6 = DeviceIPAddressSerializer()
  260. parent_device = serializers.SerializerMethodField()
  261. class Meta:
  262. model = Device
  263. fields = [
  264. 'id', 'name', 'display_name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag',
  265. 'site', 'rack', 'position', 'face', 'parent_device', 'status', 'primary_ip', 'primary_ip4', 'primary_ip6',
  266. 'comments', 'custom_fields',
  267. ]
  268. def get_parent_device(self, obj):
  269. try:
  270. device_bay = obj.parent_bay
  271. except DeviceBay.DoesNotExist:
  272. return None
  273. return {
  274. 'id': device_bay.device.pk,
  275. 'name': device_bay.device.name,
  276. 'device_bay': {
  277. 'id': device_bay.pk,
  278. 'name': device_bay.name,
  279. }
  280. }
  281. class NestedDeviceSerializer(serializers.ModelSerializer):
  282. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:device-detail')
  283. class Meta:
  284. model = Device
  285. fields = ['id', 'url', 'name', 'display_name']
  286. class WritableDeviceSerializer(serializers.ModelSerializer):
  287. class Meta:
  288. model = Device
  289. fields = [
  290. 'id', 'name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag', 'rack', 'position',
  291. 'face', 'status', 'primary_ip4', 'primary_ip6', 'comments',
  292. ]
  293. #
  294. # Console server ports
  295. #
  296. class ConsoleServerPortSerializer(serializers.ModelSerializer):
  297. device = NestedDeviceSerializer()
  298. class Meta:
  299. model = ConsoleServerPort
  300. fields = ['id', 'device', 'name', 'connected_console']
  301. class WritableConsoleServerPortSerializer(serializers.ModelSerializer):
  302. class Meta:
  303. model = ConsoleServerPort
  304. fields = ['id', 'device', 'name', 'connected_console']
  305. #
  306. # Console ports
  307. #
  308. class ConsolePortSerializer(serializers.ModelSerializer):
  309. device = NestedDeviceSerializer()
  310. cs_port = ConsoleServerPortSerializer()
  311. class Meta:
  312. model = ConsolePort
  313. fields = ['id', 'device', 'name', 'cs_port', 'connection_status']
  314. class WritableConsolePortSerializer(serializers.ModelSerializer):
  315. class Meta:
  316. model = ConsolePort
  317. fields = ['id', 'device', 'name', 'cs_port', 'connection_status']
  318. #
  319. # Power outlets
  320. #
  321. class PowerOutletSerializer(serializers.ModelSerializer):
  322. device = NestedDeviceSerializer()
  323. class Meta:
  324. model = PowerOutlet
  325. fields = ['id', 'device', 'name', 'connected_port']
  326. class WritablePowerOutletSerializer(serializers.ModelSerializer):
  327. class Meta:
  328. model = PowerOutlet
  329. fields = ['id', 'device', 'name', 'connected_port']
  330. #
  331. # Power ports
  332. #
  333. class PowerPortSerializer(serializers.ModelSerializer):
  334. device = NestedDeviceSerializer()
  335. power_outlet = PowerOutletSerializer()
  336. class Meta:
  337. model = PowerPort
  338. fields = ['id', 'device', 'name', 'power_outlet', 'connection_status']
  339. class WritablePowerPortSerializer(serializers.ModelSerializer):
  340. class Meta:
  341. model = PowerPort
  342. fields = ['id', 'device', 'name', 'power_outlet', 'connection_status']
  343. #
  344. # Interfaces
  345. #
  346. class InterfaceSerializer(serializers.ModelSerializer):
  347. device = NestedDeviceSerializer()
  348. form_factor = ChoiceFieldSerializer(choices=IFACE_FF_CHOICES)
  349. connection = serializers.SerializerMethodField(read_only=True)
  350. connected_interface = serializers.SerializerMethodField(read_only=True)
  351. class Meta:
  352. model = Interface
  353. fields = [
  354. 'id', 'device', 'name', 'form_factor', 'lag', 'mac_address', 'mgmt_only', 'description', 'connection',
  355. 'connected_interface',
  356. ]
  357. def get_connection(self, obj):
  358. if obj.connection:
  359. return NestedInterfaceConnectionSerializer(obj.connection, context=self.context).data
  360. return None
  361. def get_connected_interface(self, obj):
  362. if obj.connected_interface:
  363. return PeerInterfaceSerializer(obj.connected_interface, context=self.context).data
  364. return None
  365. class PeerInterfaceSerializer(serializers.ModelSerializer):
  366. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail')
  367. device = NestedDeviceSerializer()
  368. class Meta:
  369. model = Interface
  370. fields = ['id', 'url', 'device', 'name', 'form_factor', 'mac_address', 'mgmt_only', 'description']
  371. class WritableInterfaceSerializer(serializers.ModelSerializer):
  372. class Meta:
  373. model = Interface
  374. fields = ['id', 'device', 'name', 'form_factor', 'lag', 'mac_address', 'mgmt_only', 'description']
  375. #
  376. # Device bays
  377. #
  378. class DeviceBaySerializer(serializers.ModelSerializer):
  379. device = NestedDeviceSerializer()
  380. installed_device = NestedDeviceSerializer()
  381. class Meta:
  382. model = DeviceBay
  383. fields = ['id', 'device', 'name', 'installed_device']
  384. class WritableDeviceBaySerializer(serializers.ModelSerializer):
  385. class Meta:
  386. model = DeviceBay
  387. fields = ['id', 'device', 'name']
  388. #
  389. # Modules
  390. #
  391. class ModuleSerializer(serializers.ModelSerializer):
  392. device = NestedDeviceSerializer()
  393. manufacturer = NestedManufacturerSerializer()
  394. class Meta:
  395. model = Module
  396. fields = ['id', 'device', 'parent', 'name', 'manufacturer', 'part_id', 'serial', 'discovered']
  397. class WritableModuleSerializer(serializers.ModelSerializer):
  398. class Meta:
  399. model = Module
  400. fields = ['id', 'device', 'parent', 'name', 'manufacturer', 'part_id', 'serial', 'discovered']
  401. #
  402. # Interface connections
  403. #
  404. class InterfaceConnectionSerializer(serializers.ModelSerializer):
  405. interface_a = PeerInterfaceSerializer()
  406. interface_b = PeerInterfaceSerializer()
  407. connection_status = ChoiceFieldSerializer(choices=CONNECTION_STATUS_CHOICES)
  408. class Meta:
  409. model = InterfaceConnection
  410. fields = ['id', 'interface_a', 'interface_b', 'connection_status']
  411. class NestedInterfaceConnectionSerializer(serializers.ModelSerializer):
  412. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interfaceconnection-detail')
  413. class Meta:
  414. model = InterfaceConnection
  415. fields = ['id', 'url', 'connection_status']
  416. class WritableInterfaceConnectionSerializer(serializers.ModelSerializer):
  417. class Meta:
  418. model = InterfaceConnection
  419. fields = ['id', 'interface_a', 'interface_b', 'connection_status']