serializers.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771
  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 circuits.models import Circuit, CircuitTermination
  6. from dcim.constants import (
  7. CONNECTION_STATUS_CHOICES, IFACE_FF_CHOICES, IFACE_ORDERING_CHOICES, RACK_FACE_CHOICES, RACK_TYPE_CHOICES,
  8. RACK_WIDTH_CHOICES, STATUS_CHOICES, SUBDEVICE_ROLE_CHOICES,
  9. )
  10. from dcim.models import (
  11. ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
  12. DeviceBayTemplate, DeviceType, DeviceRole, Interface, InterfaceConnection, InterfaceTemplate, Manufacturer,
  13. InventoryItem, Platform, PowerOutlet, PowerOutletTemplate, PowerPort, PowerPortTemplate, Rack, RackGroup,
  14. RackReservation, RackRole, Region, Site,
  15. )
  16. from extras.api.customfields import CustomFieldModelSerializer
  17. from ipam.models import IPAddress
  18. from tenancy.api.serializers import NestedTenantSerializer
  19. from utilities.api import ChoiceFieldSerializer, ValidatedModelSerializer
  20. from virtualization.models import Cluster
  21. #
  22. # Regions
  23. #
  24. class NestedRegionSerializer(serializers.ModelSerializer):
  25. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:region-detail')
  26. class Meta:
  27. model = Region
  28. fields = ['id', 'url', 'name', 'slug']
  29. class RegionSerializer(serializers.ModelSerializer):
  30. parent = NestedRegionSerializer()
  31. class Meta:
  32. model = Region
  33. fields = ['id', 'name', 'slug', 'parent']
  34. class WritableRegionSerializer(ValidatedModelSerializer):
  35. class Meta:
  36. model = Region
  37. fields = ['id', 'name', 'slug', 'parent']
  38. #
  39. # Sites
  40. #
  41. class SiteSerializer(CustomFieldModelSerializer):
  42. region = NestedRegionSerializer()
  43. tenant = NestedTenantSerializer()
  44. class Meta:
  45. model = Site
  46. fields = [
  47. 'id', 'name', 'slug', 'region', 'tenant', 'facility', 'asn', 'physical_address', 'shipping_address',
  48. 'contact_name', 'contact_phone', 'contact_email', 'comments', 'custom_fields', 'count_prefixes',
  49. 'count_vlans', 'count_racks', 'count_devices', 'count_circuits',
  50. ]
  51. class NestedSiteSerializer(serializers.ModelSerializer):
  52. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:site-detail')
  53. class Meta:
  54. model = Site
  55. fields = ['id', 'url', 'name', 'slug']
  56. class WritableSiteSerializer(CustomFieldModelSerializer):
  57. class Meta:
  58. model = Site
  59. fields = [
  60. 'id', 'name', 'slug', 'region', 'tenant', 'facility', 'asn', 'physical_address', 'shipping_address',
  61. 'contact_name', 'contact_phone', 'contact_email', 'comments', 'custom_fields',
  62. ]
  63. #
  64. # Rack groups
  65. #
  66. class RackGroupSerializer(serializers.ModelSerializer):
  67. site = NestedSiteSerializer()
  68. class Meta:
  69. model = RackGroup
  70. fields = ['id', 'name', 'slug', 'site']
  71. class NestedRackGroupSerializer(serializers.ModelSerializer):
  72. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackgroup-detail')
  73. class Meta:
  74. model = RackGroup
  75. fields = ['id', 'url', 'name', 'slug']
  76. class WritableRackGroupSerializer(ValidatedModelSerializer):
  77. class Meta:
  78. model = RackGroup
  79. fields = ['id', 'name', 'slug', 'site']
  80. #
  81. # Rack roles
  82. #
  83. class RackRoleSerializer(ValidatedModelSerializer):
  84. class Meta:
  85. model = RackRole
  86. fields = ['id', 'name', 'slug', 'color']
  87. class NestedRackRoleSerializer(serializers.ModelSerializer):
  88. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rackrole-detail')
  89. class Meta:
  90. model = RackRole
  91. fields = ['id', 'url', 'name', 'slug']
  92. #
  93. # Racks
  94. #
  95. class RackSerializer(CustomFieldModelSerializer):
  96. site = NestedSiteSerializer()
  97. group = NestedRackGroupSerializer()
  98. tenant = NestedTenantSerializer()
  99. role = NestedRackRoleSerializer()
  100. type = ChoiceFieldSerializer(choices=RACK_TYPE_CHOICES)
  101. width = ChoiceFieldSerializer(choices=RACK_WIDTH_CHOICES)
  102. class Meta:
  103. model = Rack
  104. fields = [
  105. 'id', 'name', 'facility_id', 'display_name', 'site', 'group', 'tenant', 'role', 'serial', 'type', 'width',
  106. 'u_height', 'desc_units', 'comments', 'custom_fields',
  107. ]
  108. class NestedRackSerializer(serializers.ModelSerializer):
  109. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rack-detail')
  110. class Meta:
  111. model = Rack
  112. fields = ['id', 'url', 'name', 'display_name']
  113. class WritableRackSerializer(CustomFieldModelSerializer):
  114. class Meta:
  115. model = Rack
  116. fields = [
  117. 'id', 'name', 'facility_id', 'site', 'group', 'tenant', 'role', 'serial', 'type', 'width', 'u_height',
  118. 'desc_units', 'comments', 'custom_fields',
  119. ]
  120. # Omit the UniqueTogetherValidator that would be automatically added to validate (site, facility_id). This
  121. # prevents facility_id from being interpreted as a required field.
  122. validators = [
  123. UniqueTogetherValidator(queryset=Rack.objects.all(), fields=('site', 'name'))
  124. ]
  125. def validate(self, data):
  126. # Validate uniqueness of (site, facility_id) since we omitted the automatically-created validator from Meta.
  127. if data.get('facility_id', None):
  128. validator = UniqueTogetherValidator(queryset=Rack.objects.all(), fields=('site', 'facility_id'))
  129. validator.set_context(self)
  130. validator(data)
  131. # Enforce model validation
  132. super(WritableRackSerializer, self).validate(data)
  133. return data
  134. #
  135. # Rack units
  136. #
  137. class NestedDeviceSerializer(serializers.ModelSerializer):
  138. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:device-detail')
  139. class Meta:
  140. model = Device
  141. fields = ['id', 'url', 'name', 'display_name']
  142. class RackUnitSerializer(serializers.Serializer):
  143. """
  144. A rack unit is an abstraction formed by the set (rack, position, face); it does not exist as a row in the database.
  145. """
  146. id = serializers.IntegerField(read_only=True)
  147. name = serializers.CharField(read_only=True)
  148. face = serializers.IntegerField(read_only=True)
  149. device = NestedDeviceSerializer(read_only=True)
  150. #
  151. # Rack reservations
  152. #
  153. class RackReservationSerializer(serializers.ModelSerializer):
  154. rack = NestedRackSerializer()
  155. class Meta:
  156. model = RackReservation
  157. fields = ['id', 'rack', 'units', 'created', 'user', 'description']
  158. class WritableRackReservationSerializer(ValidatedModelSerializer):
  159. class Meta:
  160. model = RackReservation
  161. fields = ['id', 'rack', 'units', 'user', 'description']
  162. #
  163. # Manufacturers
  164. #
  165. class ManufacturerSerializer(ValidatedModelSerializer):
  166. class Meta:
  167. model = Manufacturer
  168. fields = ['id', 'name', 'slug']
  169. class NestedManufacturerSerializer(serializers.ModelSerializer):
  170. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:manufacturer-detail')
  171. class Meta:
  172. model = Manufacturer
  173. fields = ['id', 'url', 'name', 'slug']
  174. #
  175. # Device types
  176. #
  177. class DeviceTypeSerializer(CustomFieldModelSerializer):
  178. manufacturer = NestedManufacturerSerializer()
  179. interface_ordering = ChoiceFieldSerializer(choices=IFACE_ORDERING_CHOICES)
  180. subdevice_role = ChoiceFieldSerializer(choices=SUBDEVICE_ROLE_CHOICES)
  181. instance_count = serializers.IntegerField(source='instances.count', read_only=True)
  182. class Meta:
  183. model = DeviceType
  184. fields = [
  185. 'id', 'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'interface_ordering',
  186. 'is_console_server', 'is_pdu', 'is_network_device', 'subdevice_role', 'comments', 'custom_fields',
  187. 'instance_count',
  188. ]
  189. class NestedDeviceTypeSerializer(serializers.ModelSerializer):
  190. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicetype-detail')
  191. manufacturer = NestedManufacturerSerializer()
  192. class Meta:
  193. model = DeviceType
  194. fields = ['id', 'url', 'manufacturer', 'model', 'slug']
  195. class WritableDeviceTypeSerializer(CustomFieldModelSerializer):
  196. class Meta:
  197. model = DeviceType
  198. fields = [
  199. 'id', 'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'interface_ordering',
  200. 'is_console_server', 'is_pdu', 'is_network_device', 'subdevice_role', 'comments', 'custom_fields',
  201. ]
  202. #
  203. # Console port templates
  204. #
  205. class ConsolePortTemplateSerializer(serializers.ModelSerializer):
  206. device_type = NestedDeviceTypeSerializer()
  207. class Meta:
  208. model = ConsolePortTemplate
  209. fields = ['id', 'device_type', 'name']
  210. class WritableConsolePortTemplateSerializer(ValidatedModelSerializer):
  211. class Meta:
  212. model = ConsolePortTemplate
  213. fields = ['id', 'device_type', 'name']
  214. #
  215. # Console server port templates
  216. #
  217. class ConsoleServerPortTemplateSerializer(serializers.ModelSerializer):
  218. device_type = NestedDeviceTypeSerializer()
  219. class Meta:
  220. model = ConsoleServerPortTemplate
  221. fields = ['id', 'device_type', 'name']
  222. class WritableConsoleServerPortTemplateSerializer(ValidatedModelSerializer):
  223. class Meta:
  224. model = ConsoleServerPortTemplate
  225. fields = ['id', 'device_type', 'name']
  226. #
  227. # Power port templates
  228. #
  229. class PowerPortTemplateSerializer(serializers.ModelSerializer):
  230. device_type = NestedDeviceTypeSerializer()
  231. class Meta:
  232. model = PowerPortTemplate
  233. fields = ['id', 'device_type', 'name']
  234. class WritablePowerPortTemplateSerializer(ValidatedModelSerializer):
  235. class Meta:
  236. model = PowerPortTemplate
  237. fields = ['id', 'device_type', 'name']
  238. #
  239. # Power outlet templates
  240. #
  241. class PowerOutletTemplateSerializer(serializers.ModelSerializer):
  242. device_type = NestedDeviceTypeSerializer()
  243. class Meta:
  244. model = PowerOutletTemplate
  245. fields = ['id', 'device_type', 'name']
  246. class WritablePowerOutletTemplateSerializer(ValidatedModelSerializer):
  247. class Meta:
  248. model = PowerOutletTemplate
  249. fields = ['id', 'device_type', 'name']
  250. #
  251. # Interface templates
  252. #
  253. class InterfaceTemplateSerializer(serializers.ModelSerializer):
  254. device_type = NestedDeviceTypeSerializer()
  255. form_factor = ChoiceFieldSerializer(choices=IFACE_FF_CHOICES)
  256. class Meta:
  257. model = InterfaceTemplate
  258. fields = ['id', 'device_type', 'name', 'form_factor', 'mgmt_only']
  259. class WritableInterfaceTemplateSerializer(ValidatedModelSerializer):
  260. class Meta:
  261. model = InterfaceTemplate
  262. fields = ['id', 'device_type', 'name', 'form_factor', 'mgmt_only']
  263. #
  264. # Device bay templates
  265. #
  266. class DeviceBayTemplateSerializer(serializers.ModelSerializer):
  267. device_type = NestedDeviceTypeSerializer()
  268. class Meta:
  269. model = DeviceBayTemplate
  270. fields = ['id', 'device_type', 'name']
  271. class WritableDeviceBayTemplateSerializer(ValidatedModelSerializer):
  272. class Meta:
  273. model = DeviceBayTemplate
  274. fields = ['id', 'device_type', 'name']
  275. #
  276. # Device roles
  277. #
  278. class DeviceRoleSerializer(ValidatedModelSerializer):
  279. class Meta:
  280. model = DeviceRole
  281. fields = ['id', 'name', 'slug', 'color', 'vm_role']
  282. class NestedDeviceRoleSerializer(serializers.ModelSerializer):
  283. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicerole-detail')
  284. class Meta:
  285. model = DeviceRole
  286. fields = ['id', 'url', 'name', 'slug']
  287. #
  288. # Platforms
  289. #
  290. class PlatformSerializer(ValidatedModelSerializer):
  291. class Meta:
  292. model = Platform
  293. fields = ['id', 'name', 'slug', 'napalm_driver', 'rpc_client']
  294. class NestedPlatformSerializer(serializers.ModelSerializer):
  295. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:platform-detail')
  296. class Meta:
  297. model = Platform
  298. fields = ['id', 'url', 'name', 'slug']
  299. #
  300. # Devices
  301. #
  302. # Cannot import ipam.api.NestedIPAddressSerializer due to circular dependency
  303. class DeviceIPAddressSerializer(serializers.ModelSerializer):
  304. url = serializers.HyperlinkedIdentityField(view_name='ipam-api:ipaddress-detail')
  305. class Meta:
  306. model = IPAddress
  307. fields = ['id', 'url', 'family', 'address']
  308. # Cannot import virtualization.api.NestedClusterSerializer due to circular dependency
  309. class NestedClusterSerializer(serializers.ModelSerializer):
  310. url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:cluster-detail')
  311. class Meta:
  312. model = Cluster
  313. fields = ['id', 'url', 'name']
  314. class DeviceSerializer(CustomFieldModelSerializer):
  315. device_type = NestedDeviceTypeSerializer()
  316. device_role = NestedDeviceRoleSerializer()
  317. tenant = NestedTenantSerializer()
  318. platform = NestedPlatformSerializer()
  319. site = NestedSiteSerializer()
  320. rack = NestedRackSerializer()
  321. face = ChoiceFieldSerializer(choices=RACK_FACE_CHOICES)
  322. status = ChoiceFieldSerializer(choices=STATUS_CHOICES)
  323. primary_ip = DeviceIPAddressSerializer()
  324. primary_ip4 = DeviceIPAddressSerializer()
  325. primary_ip6 = DeviceIPAddressSerializer()
  326. parent_device = serializers.SerializerMethodField()
  327. cluster = NestedClusterSerializer()
  328. class Meta:
  329. model = Device
  330. fields = [
  331. 'id', 'name', 'display_name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag',
  332. 'site', 'rack', 'position', 'face', 'parent_device', 'status', 'primary_ip', 'primary_ip4', 'primary_ip6',
  333. 'cluster', 'comments', 'custom_fields',
  334. ]
  335. def get_parent_device(self, obj):
  336. try:
  337. device_bay = obj.parent_bay
  338. except DeviceBay.DoesNotExist:
  339. return None
  340. context = {'request': self.context['request']}
  341. data = NestedDeviceSerializer(instance=device_bay.device, context=context).data
  342. data['device_bay'] = NestedDeviceBaySerializer(instance=device_bay, context=context).data
  343. return data
  344. class WritableDeviceSerializer(CustomFieldModelSerializer):
  345. class Meta:
  346. model = Device
  347. fields = [
  348. 'id', 'name', 'device_type', 'device_role', 'tenant', 'platform', 'serial', 'asset_tag', 'site', 'rack',
  349. 'position', 'face', 'status', 'primary_ip4', 'primary_ip6', 'cluster', 'comments', 'custom_fields',
  350. ]
  351. validators = []
  352. def validate(self, data):
  353. # Validate uniqueness of (rack, position, face) since we omitted the automatically-created validator from Meta.
  354. if data.get('rack') and data.get('position') and data.get('face'):
  355. validator = UniqueTogetherValidator(queryset=Device.objects.all(), fields=('rack', 'position', 'face'))
  356. validator.set_context(self)
  357. validator(data)
  358. # Enforce model validation
  359. super(WritableDeviceSerializer, self).validate(data)
  360. return data
  361. #
  362. # Console server ports
  363. #
  364. class ConsoleServerPortSerializer(serializers.ModelSerializer):
  365. device = NestedDeviceSerializer()
  366. class Meta:
  367. model = ConsoleServerPort
  368. fields = ['id', 'device', 'name', 'connected_console']
  369. read_only_fields = ['connected_console']
  370. class WritableConsoleServerPortSerializer(ValidatedModelSerializer):
  371. class Meta:
  372. model = ConsoleServerPort
  373. fields = ['id', 'device', 'name']
  374. #
  375. # Console ports
  376. #
  377. class ConsolePortSerializer(serializers.ModelSerializer):
  378. device = NestedDeviceSerializer()
  379. cs_port = ConsoleServerPortSerializer()
  380. class Meta:
  381. model = ConsolePort
  382. fields = ['id', 'device', 'name', 'cs_port', 'connection_status']
  383. class WritableConsolePortSerializer(ValidatedModelSerializer):
  384. class Meta:
  385. model = ConsolePort
  386. fields = ['id', 'device', 'name', 'cs_port', 'connection_status']
  387. #
  388. # Power outlets
  389. #
  390. class PowerOutletSerializer(serializers.ModelSerializer):
  391. device = NestedDeviceSerializer()
  392. class Meta:
  393. model = PowerOutlet
  394. fields = ['id', 'device', 'name', 'connected_port']
  395. read_only_fields = ['connected_port']
  396. class WritablePowerOutletSerializer(ValidatedModelSerializer):
  397. class Meta:
  398. model = PowerOutlet
  399. fields = ['id', 'device', 'name']
  400. #
  401. # Power ports
  402. #
  403. class PowerPortSerializer(serializers.ModelSerializer):
  404. device = NestedDeviceSerializer()
  405. power_outlet = PowerOutletSerializer()
  406. class Meta:
  407. model = PowerPort
  408. fields = ['id', 'device', 'name', 'power_outlet', 'connection_status']
  409. class WritablePowerPortSerializer(ValidatedModelSerializer):
  410. class Meta:
  411. model = PowerPort
  412. fields = ['id', 'device', 'name', 'power_outlet', 'connection_status']
  413. #
  414. # Interfaces
  415. #
  416. class NestedInterfaceSerializer(serializers.ModelSerializer):
  417. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail')
  418. class Meta:
  419. model = Interface
  420. fields = ['id', 'url', 'name']
  421. class InterfaceNestedCircuitSerializer(serializers.ModelSerializer):
  422. url = serializers.HyperlinkedIdentityField(view_name='circuits-api:circuit-detail')
  423. class Meta:
  424. model = Circuit
  425. fields = ['id', 'url', 'cid']
  426. class InterfaceCircuitTerminationSerializer(serializers.ModelSerializer):
  427. circuit = InterfaceNestedCircuitSerializer()
  428. class Meta:
  429. model = CircuitTermination
  430. fields = [
  431. 'id', 'circuit', 'term_side', 'port_speed', 'upstream_speed', 'xconnect_id', 'pp_info',
  432. ]
  433. class InterfaceSerializer(serializers.ModelSerializer):
  434. device = NestedDeviceSerializer()
  435. form_factor = ChoiceFieldSerializer(choices=IFACE_FF_CHOICES)
  436. lag = NestedInterfaceSerializer()
  437. is_connected = serializers.SerializerMethodField(read_only=True)
  438. interface_connection = serializers.SerializerMethodField(read_only=True)
  439. circuit_termination = InterfaceCircuitTerminationSerializer()
  440. class Meta:
  441. model = Interface
  442. fields = [
  443. 'id', 'device', 'name', 'form_factor', 'enabled', 'lag', 'mtu', 'mac_address', 'mgmt_only', 'description',
  444. 'is_connected', 'interface_connection', 'circuit_termination',
  445. ]
  446. def get_is_connected(self, obj):
  447. """
  448. Return True if the interface has a connected interface or circuit termination.
  449. """
  450. if obj.connection:
  451. return True
  452. try:
  453. circuit_termination = obj.circuit_termination
  454. return True
  455. except CircuitTermination.DoesNotExist:
  456. pass
  457. return False
  458. def get_interface_connection(self, obj):
  459. if obj.connection:
  460. return OrderedDict((
  461. ('interface', PeerInterfaceSerializer(obj.connected_interface, context=self.context).data),
  462. ('status', obj.connection.connection_status),
  463. ))
  464. return None
  465. class PeerInterfaceSerializer(serializers.ModelSerializer):
  466. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interface-detail')
  467. device = NestedDeviceSerializer()
  468. form_factor = ChoiceFieldSerializer(choices=IFACE_FF_CHOICES)
  469. lag = NestedInterfaceSerializer()
  470. class Meta:
  471. model = Interface
  472. fields = [
  473. 'id', 'url', 'device', 'name', 'form_factor', 'enabled', 'lag', 'mtu', 'mac_address', 'mgmt_only',
  474. 'description',
  475. ]
  476. class WritableInterfaceSerializer(ValidatedModelSerializer):
  477. class Meta:
  478. model = Interface
  479. fields = [
  480. 'id', 'device', 'name', 'form_factor', 'enabled', 'lag', 'mtu', 'mac_address', 'mgmt_only', 'description',
  481. ]
  482. #
  483. # Device bays
  484. #
  485. class DeviceBaySerializer(serializers.ModelSerializer):
  486. device = NestedDeviceSerializer()
  487. installed_device = NestedDeviceSerializer()
  488. class Meta:
  489. model = DeviceBay
  490. fields = ['id', 'device', 'name', 'installed_device']
  491. class NestedDeviceBaySerializer(serializers.ModelSerializer):
  492. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:devicebay-detail')
  493. class Meta:
  494. model = DeviceBay
  495. fields = ['id', 'url', 'name']
  496. class WritableDeviceBaySerializer(ValidatedModelSerializer):
  497. class Meta:
  498. model = DeviceBay
  499. fields = ['id', 'device', 'name', 'installed_device']
  500. #
  501. # Inventory items
  502. #
  503. class InventoryItemSerializer(serializers.ModelSerializer):
  504. device = NestedDeviceSerializer()
  505. manufacturer = NestedManufacturerSerializer()
  506. class Meta:
  507. model = InventoryItem
  508. fields = [
  509. 'id', 'device', 'parent', 'name', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'discovered',
  510. 'description',
  511. ]
  512. class WritableInventoryItemSerializer(ValidatedModelSerializer):
  513. class Meta:
  514. model = InventoryItem
  515. fields = [
  516. 'id', 'device', 'parent', 'name', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'discovered',
  517. 'description',
  518. ]
  519. #
  520. # Interface connections
  521. #
  522. class InterfaceConnectionSerializer(serializers.ModelSerializer):
  523. interface_a = PeerInterfaceSerializer()
  524. interface_b = PeerInterfaceSerializer()
  525. connection_status = ChoiceFieldSerializer(choices=CONNECTION_STATUS_CHOICES)
  526. class Meta:
  527. model = InterfaceConnection
  528. fields = ['id', 'interface_a', 'interface_b', 'connection_status']
  529. class NestedInterfaceConnectionSerializer(serializers.ModelSerializer):
  530. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interfaceconnection-detail')
  531. class Meta:
  532. model = InterfaceConnection
  533. fields = ['id', 'url', 'connection_status']
  534. class WritableInterfaceConnectionSerializer(ValidatedModelSerializer):
  535. class Meta:
  536. model = InterfaceConnection
  537. fields = ['id', 'interface_a', 'interface_b', 'connection_status']