panels.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. from django.utils.translation import gettext_lazy as _
  2. from netbox.ui import attrs, panels
  3. class SitePanel(panels.ObjectAttributesPanel):
  4. region = attrs.NestedObjectAttr('region', linkify=True)
  5. group = attrs.NestedObjectAttr('group', linkify=True)
  6. name = attrs.TextAttr('name')
  7. status = attrs.ChoiceAttr('status')
  8. tenant = attrs.RelatedObjectAttr('tenant', linkify=True, grouped_by='group')
  9. facility = attrs.TextAttr('facility')
  10. description = attrs.TextAttr('description')
  11. timezone = attrs.TimezoneAttr('time_zone')
  12. physical_address = attrs.AddressAttr('physical_address', map_url=True)
  13. shipping_address = attrs.AddressAttr('shipping_address', map_url=True)
  14. gps_coordinates = attrs.GPSCoordinatesAttr()
  15. class LocationPanel(panels.NestedGroupObjectPanel):
  16. site = attrs.RelatedObjectAttr('site', linkify=True, grouped_by='group')
  17. status = attrs.ChoiceAttr('status')
  18. tenant = attrs.RelatedObjectAttr('tenant', linkify=True, grouped_by='group')
  19. facility = attrs.TextAttr('facility')
  20. class RackDimensionsPanel(panels.ObjectAttributesPanel):
  21. form_factor = attrs.ChoiceAttr('form_factor')
  22. width = attrs.ChoiceAttr('width')
  23. height = attrs.TextAttr('u_height', format_string='{}U', label=_('Height'))
  24. outer_width = attrs.NumericAttr('outer_width', unit_accessor='get_outer_unit_display')
  25. outer_height = attrs.NumericAttr('outer_height', unit_accessor='get_outer_unit_display')
  26. outer_depth = attrs.NumericAttr('outer_depth', unit_accessor='get_outer_unit_display')
  27. mounting_depth = attrs.TextAttr('mounting_depth', format_string='{}mm')
  28. class RackNumberingPanel(panels.ObjectAttributesPanel):
  29. starting_unit = attrs.TextAttr('starting_unit')
  30. desc_units = attrs.BooleanAttr('desc_units', label=_('Descending units'))
  31. class RackPanel(panels.ObjectAttributesPanel):
  32. region = attrs.NestedObjectAttr('site.region', linkify=True)
  33. site = attrs.RelatedObjectAttr('site', linkify=True, grouped_by='group')
  34. location = attrs.NestedObjectAttr('location', linkify=True)
  35. name = attrs.TextAttr('name')
  36. facility = attrs.TextAttr('facility', label=_('Facility ID'))
  37. tenant = attrs.RelatedObjectAttr('tenant', linkify=True, grouped_by='group')
  38. status = attrs.ChoiceAttr('status')
  39. rack_type = attrs.RelatedObjectAttr('rack_type', linkify=True, grouped_by='manufacturer')
  40. role = attrs.RelatedObjectAttr('role', linkify=True)
  41. description = attrs.TextAttr('description')
  42. serial = attrs.TextAttr('serial', label=_('Serial number'), style='font-monospace', copy_button=True)
  43. asset_tag = attrs.TextAttr('asset_tag', style='font-monospace', copy_button=True)
  44. airflow = attrs.ChoiceAttr('airflow')
  45. space_utilization = attrs.UtilizationAttr('get_utilization')
  46. power_utilization = attrs.UtilizationAttr('get_power_utilization')
  47. class RackWeightPanel(panels.ObjectAttributesPanel):
  48. weight = attrs.NumericAttr('weight', unit_accessor='get_weight_unit_display')
  49. max_weight = attrs.NumericAttr('max_weight', unit_accessor='get_weight_unit_display', label=_('Maximum weight'))
  50. total_weight = attrs.TemplatedAttr('total_weight', template_name='dcim/rack/attrs/total_weight.html')
  51. class RackRolePanel(panels.OrganizationalObjectPanel):
  52. color = attrs.ColorAttr('color')
  53. class RackReservationPanel(panels.ObjectAttributesPanel):
  54. units = attrs.TextAttr('unit_list')
  55. status = attrs.ChoiceAttr('status')
  56. tenant = attrs.RelatedObjectAttr('tenant', linkify=True, grouped_by='group')
  57. user = attrs.RelatedObjectAttr('user')
  58. description = attrs.TextAttr('description')
  59. class RackTypePanel(panels.ObjectAttributesPanel):
  60. manufacturer = attrs.RelatedObjectAttr('manufacturer', linkify=True)
  61. model = attrs.TextAttr('model')
  62. description = attrs.TextAttr('description')
  63. class DevicePanel(panels.ObjectAttributesPanel):
  64. region = attrs.NestedObjectAttr('site.region', linkify=True)
  65. site = attrs.RelatedObjectAttr('site', linkify=True, grouped_by='group')
  66. location = attrs.NestedObjectAttr('location', linkify=True)
  67. rack = attrs.TemplatedAttr('rack', template_name='dcim/device/attrs/rack.html')
  68. virtual_chassis = attrs.RelatedObjectAttr('virtual_chassis', linkify=True)
  69. parent_device = attrs.TemplatedAttr('parent_bay', template_name='dcim/device/attrs/parent_device.html')
  70. gps_coordinates = attrs.GPSCoordinatesAttr()
  71. tenant = attrs.RelatedObjectAttr('tenant', linkify=True, grouped_by='group')
  72. device_type = attrs.RelatedObjectAttr('device_type', linkify=True, grouped_by='manufacturer')
  73. description = attrs.TextAttr('description')
  74. airflow = attrs.ChoiceAttr('airflow')
  75. serial = attrs.TextAttr('serial', label=_('Serial number'), style='font-monospace', copy_button=True)
  76. asset_tag = attrs.TextAttr('asset_tag', style='font-monospace', copy_button=True)
  77. config_template = attrs.RelatedObjectAttr('config_template', linkify=True)
  78. class DeviceManagementPanel(panels.ObjectAttributesPanel):
  79. title = _('Management')
  80. status = attrs.ChoiceAttr('status')
  81. role = attrs.NestedObjectAttr('role', linkify=True, max_depth=3)
  82. platform = attrs.NestedObjectAttr('platform', linkify=True, max_depth=3)
  83. primary_ip4 = attrs.TemplatedAttr(
  84. 'primary_ip4',
  85. label=_('Primary IPv4'),
  86. template_name='dcim/device/attrs/ipaddress.html',
  87. )
  88. primary_ip6 = attrs.TemplatedAttr(
  89. 'primary_ip6',
  90. label=_('Primary IPv6'),
  91. template_name='dcim/device/attrs/ipaddress.html',
  92. )
  93. oob_ip = attrs.TemplatedAttr(
  94. 'oob_ip',
  95. label=_('Out-of-band IP'),
  96. template_name='dcim/device/attrs/ipaddress.html',
  97. )
  98. cluster = attrs.RelatedObjectAttr('cluster', linkify=True)
  99. class DeviceDimensionsPanel(panels.ObjectAttributesPanel):
  100. title = _('Dimensions')
  101. height = attrs.TextAttr('device_type.u_height', format_string='{}U')
  102. total_weight = attrs.TemplatedAttr('total_weight', template_name='dcim/device/attrs/total_weight.html')
  103. class DeviceTypePanel(panels.ObjectAttributesPanel):
  104. manufacturer = attrs.RelatedObjectAttr('manufacturer', linkify=True)
  105. model = attrs.TextAttr('model')
  106. part_number = attrs.TextAttr('part_number')
  107. default_platform = attrs.RelatedObjectAttr('default_platform', linkify=True)
  108. description = attrs.TextAttr('description')
  109. height = attrs.TextAttr('u_height', format_string='{}U', label=_('Height'))
  110. exclude_from_utilization = attrs.BooleanAttr('exclude_from_utilization')
  111. full_depth = attrs.BooleanAttr('is_full_depth')
  112. weight = attrs.NumericAttr('weight', unit_accessor='get_weight_unit_display')
  113. subdevice_role = attrs.ChoiceAttr('subdevice_role', label=_('Parent/child'))
  114. airflow = attrs.ChoiceAttr('airflow')
  115. front_image = attrs.ImageAttr('front_image')
  116. rear_image = attrs.ImageAttr('rear_image')
  117. class ModuleTypeProfilePanel(panels.ObjectAttributesPanel):
  118. name = attrs.TextAttr('name')
  119. description = attrs.TextAttr('description')
  120. class VirtualChassisMembersPanel(panels.ObjectPanel):
  121. """
  122. A panel which lists all members of a virtual chassis.
  123. """
  124. template_name = 'dcim/panels/virtual_chassis_members.html'
  125. title = _('Virtual Chassis Members')
  126. def get_context(self, context):
  127. return {
  128. **super().get_context(context),
  129. 'vc_members': context.get('vc_members'),
  130. }
  131. def render(self, context):
  132. if not context.get('vc_members'):
  133. return ''
  134. return super().render(context)
  135. class PowerUtilizationPanel(panels.ObjectPanel):
  136. """
  137. A panel which displays the power utilization statistics for a device.
  138. """
  139. template_name = 'dcim/panels/power_utilization.html'
  140. title = _('Power Utilization')
  141. def get_context(self, context):
  142. return {
  143. **super().get_context(context),
  144. 'vc_members': context.get('vc_members'),
  145. }
  146. def render(self, context):
  147. obj = context['object']
  148. if not obj.powerports.exists() or not obj.poweroutlets.exists():
  149. return ''
  150. return super().render(context)