devices.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. import decimal
  2. from django.utils.translation import gettext as _
  3. from drf_spectacular.utils import extend_schema_field
  4. from rest_framework import serializers
  5. from dcim.choices import *
  6. from dcim.models import Device, DeviceBay, Module, VirtualDeviceContext
  7. from extras.api.serializers_.configtemplates import ConfigTemplateSerializer
  8. from ipam.api.serializers_.ip import IPAddressSerializer
  9. from netbox.api.fields import ChoiceField, RelatedObjectCountField
  10. from netbox.api.serializers import NetBoxModelSerializer
  11. from tenancy.api.serializers_.tenants import TenantSerializer
  12. from virtualization.api.serializers_.clusters import ClusterSerializer
  13. from .devicetypes import *
  14. from .platforms import PlatformSerializer
  15. from .racks import RackSerializer
  16. from .roles import DeviceRoleSerializer
  17. from .sites import LocationSerializer, SiteSerializer
  18. from .virtualchassis import VirtualChassisSerializer
  19. from ..nested_serializers import *
  20. __all__ = (
  21. 'DeviceSerializer',
  22. 'DeviceWithConfigContextSerializer',
  23. 'ModuleSerializer',
  24. 'VirtualDeviceContextSerializer',
  25. )
  26. class DeviceSerializer(NetBoxModelSerializer):
  27. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:device-detail')
  28. device_type = DeviceTypeSerializer(nested=True)
  29. role = DeviceRoleSerializer(nested=True)
  30. tenant = TenantSerializer(
  31. nested=True,
  32. required=False,
  33. allow_null=True,
  34. default=None
  35. )
  36. platform = PlatformSerializer(nested=True, required=False, allow_null=True)
  37. site = SiteSerializer(nested=True)
  38. location = LocationSerializer(nested=True, required=False, allow_null=True, default=None)
  39. rack = RackSerializer(nested=True, required=False, allow_null=True, default=None)
  40. face = ChoiceField(choices=DeviceFaceChoices, allow_blank=True, default=lambda: '')
  41. position = serializers.DecimalField(
  42. max_digits=4,
  43. decimal_places=1,
  44. allow_null=True,
  45. label=_('Position (U)'),
  46. min_value=decimal.Decimal(0.5),
  47. default=None
  48. )
  49. status = ChoiceField(choices=DeviceStatusChoices, required=False)
  50. airflow = ChoiceField(choices=DeviceAirflowChoices, allow_blank=True, required=False)
  51. primary_ip = IPAddressSerializer(nested=True, read_only=True, allow_null=True)
  52. primary_ip4 = IPAddressSerializer(nested=True, required=False, allow_null=True)
  53. primary_ip6 = IPAddressSerializer(nested=True, required=False, allow_null=True)
  54. oob_ip = IPAddressSerializer(nested=True, required=False, allow_null=True)
  55. parent_device = serializers.SerializerMethodField()
  56. cluster = ClusterSerializer(nested=True, required=False, allow_null=True)
  57. virtual_chassis = VirtualChassisSerializer(nested=True, required=False, allow_null=True, default=None)
  58. vc_position = serializers.IntegerField(allow_null=True, max_value=255, min_value=0, default=None)
  59. config_template = ConfigTemplateSerializer(nested=True, required=False, allow_null=True, default=None)
  60. # Counter fields
  61. console_port_count = serializers.IntegerField(read_only=True)
  62. console_server_port_count = serializers.IntegerField(read_only=True)
  63. power_port_count = serializers.IntegerField(read_only=True)
  64. power_outlet_count = serializers.IntegerField(read_only=True)
  65. interface_count = serializers.IntegerField(read_only=True)
  66. front_port_count = serializers.IntegerField(read_only=True)
  67. rear_port_count = serializers.IntegerField(read_only=True)
  68. device_bay_count = serializers.IntegerField(read_only=True)
  69. module_bay_count = serializers.IntegerField(read_only=True)
  70. inventory_item_count = serializers.IntegerField(read_only=True)
  71. class Meta:
  72. model = Device
  73. fields = [
  74. 'id', 'url', 'display', 'name', 'device_type', 'role', 'tenant', 'platform', 'serial', 'asset_tag', 'site',
  75. 'location', 'rack', 'position', 'face', 'latitude', 'longitude', 'parent_device', 'status', 'airflow',
  76. 'primary_ip', 'primary_ip4', 'primary_ip6', 'oob_ip', 'cluster', 'virtual_chassis', 'vc_position',
  77. 'vc_priority', 'description', 'comments', 'config_template', 'local_context_data', 'tags', 'custom_fields',
  78. 'created', 'last_updated', 'console_port_count', 'console_server_port_count', 'power_port_count',
  79. 'power_outlet_count', 'interface_count', 'front_port_count', 'rear_port_count', 'device_bay_count',
  80. 'module_bay_count', 'inventory_item_count',
  81. ]
  82. brief_fields = ('id', 'url', 'display', 'name', 'description')
  83. @extend_schema_field(NestedDeviceSerializer)
  84. def get_parent_device(self, obj):
  85. try:
  86. device_bay = obj.parent_bay
  87. except DeviceBay.DoesNotExist:
  88. return None
  89. context = {'request': self.context['request']}
  90. data = NestedDeviceSerializer(instance=device_bay.device, context=context).data
  91. data['device_bay'] = NestedDeviceBaySerializer(instance=device_bay, context=context).data
  92. return data
  93. class DeviceWithConfigContextSerializer(DeviceSerializer):
  94. config_context = serializers.SerializerMethodField(read_only=True, allow_null=True)
  95. class Meta(DeviceSerializer.Meta):
  96. fields = [
  97. 'id', 'url', 'display', 'name', 'device_type', 'role', 'tenant', 'platform', 'serial', 'asset_tag', 'site',
  98. 'location', 'rack', 'position', 'face', 'latitude', 'longitude', 'parent_device', 'status', 'airflow',
  99. 'primary_ip', 'primary_ip4', 'primary_ip6', 'oob_ip', 'cluster', 'virtual_chassis', 'vc_position',
  100. 'vc_priority', 'description', 'comments', 'config_template', 'config_context', 'local_context_data', 'tags',
  101. 'custom_fields', 'created', 'last_updated', 'console_port_count', 'console_server_port_count',
  102. 'power_port_count', 'power_outlet_count', 'interface_count', 'front_port_count', 'rear_port_count',
  103. 'device_bay_count', 'module_bay_count', 'inventory_item_count',
  104. ]
  105. @extend_schema_field(serializers.JSONField(allow_null=True))
  106. def get_config_context(self, obj):
  107. return obj.get_config_context()
  108. class VirtualDeviceContextSerializer(NetBoxModelSerializer):
  109. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:virtualdevicecontext-detail')
  110. device = DeviceSerializer(nested=True)
  111. identifier = serializers.IntegerField(allow_null=True, max_value=32767, min_value=0, required=False, default=None)
  112. tenant = TenantSerializer(nested=True, required=False, allow_null=True, default=None)
  113. primary_ip = IPAddressSerializer(nested=True, read_only=True, allow_null=True)
  114. primary_ip4 = IPAddressSerializer(nested=True, required=False, allow_null=True)
  115. primary_ip6 = IPAddressSerializer(nested=True, required=False, allow_null=True)
  116. status = ChoiceField(choices=VirtualDeviceContextStatusChoices)
  117. # Related object counts
  118. interface_count = RelatedObjectCountField('interfaces')
  119. class Meta:
  120. model = VirtualDeviceContext
  121. fields = [
  122. 'id', 'url', 'display', 'name', 'device', 'identifier', 'tenant', 'primary_ip', 'primary_ip4',
  123. 'primary_ip6', 'status', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
  124. 'interface_count',
  125. ]
  126. brief_fields = ('id', 'url', 'display', 'name', 'identifier', 'device', 'description')
  127. class ModuleSerializer(NetBoxModelSerializer):
  128. url = serializers.HyperlinkedIdentityField(view_name='dcim-api:module-detail')
  129. device = DeviceSerializer(nested=True)
  130. module_bay = NestedModuleBaySerializer()
  131. module_type = ModuleTypeSerializer(nested=True)
  132. status = ChoiceField(choices=ModuleStatusChoices, required=False)
  133. class Meta:
  134. model = Module
  135. fields = [
  136. 'id', 'url', 'display', 'device', 'module_bay', 'module_type', 'status', 'serial', 'asset_tag',
  137. 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated',
  138. ]
  139. brief_fields = ('id', 'url', 'display', 'device', 'module_bay', 'module_type', 'description')