From 73bf3b949802a8332c36d1b534a28297b52ea545 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 16 Oct 2020 10:39:13 -0400 Subject: [PATCH] Reorganize DCIM tables --- netbox/dcim/tables.py | 1018 --------------------------- netbox/dcim/tables/__init__.py | 114 +++ netbox/dcim/tables/cables.py | 64 ++ netbox/dcim/tables/devices.py | 366 ++++++++++ netbox/dcim/tables/devicetypes.py | 192 +++++ netbox/dcim/tables/power.py | 83 +++ netbox/dcim/tables/racks.py | 167 +++++ netbox/dcim/tables/sites.py | 62 ++ netbox/dcim/tables/template_code.py | 65 ++ netbox/virtualization/tables.py | 2 +- 10 files changed, 1114 insertions(+), 1019 deletions(-) delete mode 100644 netbox/dcim/tables.py create mode 100644 netbox/dcim/tables/__init__.py create mode 100644 netbox/dcim/tables/cables.py create mode 100644 netbox/dcim/tables/devices.py create mode 100644 netbox/dcim/tables/devicetypes.py create mode 100644 netbox/dcim/tables/power.py create mode 100644 netbox/dcim/tables/racks.py create mode 100644 netbox/dcim/tables/sites.py create mode 100644 netbox/dcim/tables/template_code.py diff --git a/netbox/dcim/tables.py b/netbox/dcim/tables.py deleted file mode 100644 index 437daaf29..000000000 --- a/netbox/dcim/tables.py +++ /dev/null @@ -1,1018 +0,0 @@ -import django_tables2 as tables -from django_tables2.utils import Accessor - -from tenancy.tables import COL_TENANT -from utilities.tables import ( - BaseTable, BooleanColumn, ButtonsColumn, ChoiceFieldColumn, ColorColumn, ColoredLabelColumn, LinkedCountColumn, - TagColumn, ToggleColumn, -) -from .models import ( - Cable, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay, - DeviceBayTemplate, DeviceRole, DeviceType, FrontPort, FrontPortTemplate, Interface, InterfaceTemplate, - InventoryItem, Manufacturer, Platform, PowerFeed, PowerOutlet, PowerOutletTemplate, PowerPanel, PowerPort, - PowerPortTemplate, Rack, RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site, - VirtualChassis, -) - -MPTT_LINK = """ -{% if record.get_children %} - -{% else %} - -{% endif %} - {{ record.name }} - -""" - -DEVICE_LINK = """ - - {{ record.name|default:'Unnamed device' }} - -""" - -RACKGROUP_ELEVATIONS = """ - - - -""" - -UTILIZATION_GRAPH = """ -{% load helpers %} -{% utilization_graph value %} -""" - -CABLE_TERMINATION_PARENT = """ -{% if value.device %} - {{ value.device }} -{% elif value.circuit %} - {{ value.circuit }} -{% elif value.power_panel %} - {{ value.power_panel }} -{% endif %} -""" - -CABLE_LENGTH = """ -{% if record.length %}{{ record.length }} {{ record.get_length_unit_display }}{% else %}—{% endif %} -""" - -INTERFACE_IPADDRESSES = """ -{% for ip in record.ip_addresses.unrestricted %} - {{ ip }}
-{% endfor %} -""" - -INTERFACE_TAGGED_VLANS = """ -{% for vlan in record.tagged_vlans.unrestricted %} - {{ vlan }}
-{% endfor %} -""" - -POWERFEED_CABLE = """ -{{ value }} - - - -""" - -POWERFEED_CABLETERMINATION = """ -{{ value.parent }} - -{{ value }} -""" - - -# -# Regions -# - -class RegionTable(BaseTable): - pk = ToggleColumn() - name = tables.TemplateColumn( - template_code=MPTT_LINK, - orderable=False - ) - site_count = tables.Column( - verbose_name='Sites' - ) - actions = ButtonsColumn(Region) - - class Meta(BaseTable.Meta): - model = Region - fields = ('pk', 'name', 'slug', 'site_count', 'description', 'actions') - default_columns = ('pk', 'name', 'site_count', 'description', 'actions') - - -# -# Sites -# - -class SiteTable(BaseTable): - pk = ToggleColumn() - name = tables.LinkColumn( - order_by=('_name',) - ) - status = ChoiceFieldColumn() - region = tables.Column( - linkify=True - ) - tenant = tables.TemplateColumn( - template_code=COL_TENANT - ) - tags = TagColumn( - url_name='dcim:site_list' - ) - - class Meta(BaseTable.Meta): - model = Site - fields = ( - 'pk', 'name', 'slug', 'status', 'facility', 'region', 'tenant', 'asn', 'time_zone', 'description', - 'physical_address', 'shipping_address', 'latitude', 'longitude', 'contact_name', 'contact_phone', - 'contact_email', 'tags', - ) - default_columns = ('pk', 'name', 'status', 'facility', 'region', 'tenant', 'asn', 'description') - - -# -# Rack groups -# - -class RackGroupTable(BaseTable): - pk = ToggleColumn() - name = tables.TemplateColumn( - template_code=MPTT_LINK, - orderable=False - ) - site = tables.LinkColumn( - viewname='dcim:site', - args=[Accessor('site__slug')], - verbose_name='Site' - ) - rack_count = tables.Column( - verbose_name='Racks' - ) - actions = ButtonsColumn( - model=RackGroup, - prepend_template=RACKGROUP_ELEVATIONS - ) - - class Meta(BaseTable.Meta): - model = RackGroup - fields = ('pk', 'name', 'site', 'rack_count', 'description', 'slug', 'actions') - default_columns = ('pk', 'name', 'site', 'rack_count', 'description', 'actions') - - -# -# Rack roles -# - -class RackRoleTable(BaseTable): - pk = ToggleColumn() - name = tables.Column(linkify=True) - rack_count = tables.Column(verbose_name='Racks') - color = ColorColumn() - actions = ButtonsColumn(RackRole) - - class Meta(BaseTable.Meta): - model = RackRole - fields = ('pk', 'name', 'rack_count', 'color', 'description', 'slug', 'actions') - default_columns = ('pk', 'name', 'rack_count', 'color', 'description', 'actions') - - -# -# Racks -# - -class RackTable(BaseTable): - pk = ToggleColumn() - name = tables.LinkColumn( - order_by=('_name',) - ) - site = tables.LinkColumn( - viewname='dcim:site', - args=[Accessor('site__slug')] - ) - tenant = tables.TemplateColumn( - template_code=COL_TENANT - ) - status = ChoiceFieldColumn() - role = ColoredLabelColumn() - u_height = tables.TemplateColumn( - template_code="{{ record.u_height }}U", - verbose_name='Height' - ) - - class Meta(BaseTable.Meta): - model = Rack - fields = ( - 'pk', 'name', 'site', 'group', 'status', 'facility_id', 'tenant', 'role', 'serial', 'asset_tag', 'type', - 'width', 'u_height', - ) - default_columns = ('pk', 'name', 'site', 'group', 'status', 'facility_id', 'tenant', 'role', 'u_height') - - -class RackDetailTable(RackTable): - device_count = LinkedCountColumn( - viewname='dcim:device_list', - url_params={'rack_id': 'pk'}, - verbose_name='Devices' - ) - get_utilization = tables.TemplateColumn( - template_code=UTILIZATION_GRAPH, - orderable=False, - verbose_name='Space' - ) - get_power_utilization = tables.TemplateColumn( - template_code=UTILIZATION_GRAPH, - orderable=False, - verbose_name='Power' - ) - tags = TagColumn( - url_name='dcim:rack_list' - ) - - class Meta(RackTable.Meta): - fields = ( - 'pk', 'name', 'site', 'group', 'status', 'facility_id', 'tenant', 'role', 'serial', 'asset_tag', 'type', - 'width', 'u_height', 'device_count', 'get_utilization', 'get_power_utilization', 'tags', - ) - default_columns = ( - 'pk', 'name', 'site', 'group', 'status', 'facility_id', 'tenant', 'role', 'u_height', 'device_count', - 'get_utilization', 'get_power_utilization', - ) - - -# -# Rack reservations -# - -class RackReservationTable(BaseTable): - pk = ToggleColumn() - reservation = tables.Column( - accessor='pk', - linkify=True - ) - site = tables.Column( - accessor=Accessor('rack__site'), - linkify=True - ) - tenant = tables.TemplateColumn( - template_code=COL_TENANT - ) - rack = tables.Column( - linkify=True - ) - unit_list = tables.Column( - orderable=False, - verbose_name='Units' - ) - tags = TagColumn( - url_name='dcim:rackreservation_list' - ) - actions = ButtonsColumn(RackReservation) - - class Meta(BaseTable.Meta): - model = RackReservation - fields = ( - 'pk', 'reservation', 'site', 'rack', 'unit_list', 'user', 'created', 'tenant', 'description', 'tags', - 'actions', - ) - default_columns = ( - 'pk', 'reservation', 'site', 'rack', 'unit_list', 'user', 'description', 'actions', - ) - - -# -# Manufacturers -# - -class ManufacturerTable(BaseTable): - pk = ToggleColumn() - name = tables.LinkColumn() - devicetype_count = tables.Column( - verbose_name='Device Types' - ) - inventoryitem_count = tables.Column( - verbose_name='Inventory Items' - ) - platform_count = tables.Column( - verbose_name='Platforms' - ) - slug = tables.Column() - actions = ButtonsColumn(Manufacturer, pk_field='slug') - - class Meta(BaseTable.Meta): - model = Manufacturer - fields = ( - 'pk', 'name', 'devicetype_count', 'inventoryitem_count', 'platform_count', 'description', 'slug', 'actions', - ) - - -# -# Device types -# - -class DeviceTypeTable(BaseTable): - pk = ToggleColumn() - model = tables.Column( - linkify=True, - verbose_name='Device Type' - ) - is_full_depth = BooleanColumn( - verbose_name='Full Depth' - ) - instance_count = LinkedCountColumn( - viewname='dcim:device_list', - url_params={'device_type_id': 'pk'}, - verbose_name='Instances' - ) - tags = TagColumn( - url_name='dcim:devicetype_list' - ) - - class Meta(BaseTable.Meta): - model = DeviceType - fields = ( - 'pk', 'model', 'manufacturer', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role', - 'instance_count', 'tags', - ) - default_columns = ( - 'pk', 'model', 'manufacturer', 'part_number', 'u_height', 'is_full_depth', 'instance_count', - ) - - -# -# Device type components -# - -class ComponentTemplateTable(BaseTable): - pk = ToggleColumn() - name = tables.Column( - order_by=('_name',) - ) - - -class ConsolePortTemplateTable(ComponentTemplateTable): - actions = ButtonsColumn( - model=ConsolePortTemplate, - buttons=('edit', 'delete') - ) - - class Meta(BaseTable.Meta): - model = ConsolePortTemplate - fields = ('pk', 'name', 'label', 'type', 'description', 'actions') - empty_text = "None" - - -class ConsoleServerPortTemplateTable(ComponentTemplateTable): - actions = ButtonsColumn( - model=ConsoleServerPortTemplate, - buttons=('edit', 'delete') - ) - - class Meta(BaseTable.Meta): - model = ConsoleServerPortTemplate - fields = ('pk', 'name', 'label', 'type', 'description', 'actions') - empty_text = "None" - - -class PowerPortTemplateTable(ComponentTemplateTable): - actions = ButtonsColumn( - model=PowerPortTemplate, - buttons=('edit', 'delete') - ) - - class Meta(BaseTable.Meta): - model = PowerPortTemplate - fields = ('pk', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description', 'actions') - empty_text = "None" - - -class PowerOutletTemplateTable(ComponentTemplateTable): - actions = ButtonsColumn( - model=PowerOutletTemplate, - buttons=('edit', 'delete') - ) - - class Meta(BaseTable.Meta): - model = PowerOutletTemplate - fields = ('pk', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description', 'actions') - empty_text = "None" - - -class InterfaceTemplateTable(ComponentTemplateTable): - mgmt_only = BooleanColumn( - verbose_name='Management Only' - ) - actions = ButtonsColumn( - model=InterfaceTemplate, - buttons=('edit', 'delete') - ) - - class Meta(BaseTable.Meta): - model = InterfaceTemplate - fields = ('pk', 'name', 'label', 'mgmt_only', 'type', 'description', 'actions') - empty_text = "None" - - -class FrontPortTemplateTable(ComponentTemplateTable): - rear_port_position = tables.Column( - verbose_name='Position' - ) - actions = ButtonsColumn( - model=FrontPortTemplate, - buttons=('edit', 'delete') - ) - - class Meta(BaseTable.Meta): - model = FrontPortTemplate - fields = ('pk', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description', 'actions') - empty_text = "None" - - -class RearPortTemplateTable(ComponentTemplateTable): - actions = ButtonsColumn( - model=RearPortTemplate, - buttons=('edit', 'delete') - ) - - class Meta(BaseTable.Meta): - model = RearPortTemplate - fields = ('pk', 'name', 'label', 'type', 'positions', 'description', 'actions') - empty_text = "None" - - -class DeviceBayTemplateTable(ComponentTemplateTable): - actions = ButtonsColumn( - model=DeviceBayTemplate, - buttons=('edit', 'delete') - ) - - class Meta(BaseTable.Meta): - model = DeviceBayTemplate - fields = ('pk', 'name', 'label', 'description', 'actions') - empty_text = "None" - - -# -# Device roles -# - -class DeviceRoleTable(BaseTable): - pk = ToggleColumn() - device_count = LinkedCountColumn( - viewname='dcim:device_list', - url_params={'role': 'slug'}, - verbose_name='Devices' - ) - vm_count = LinkedCountColumn( - viewname='virtualization:virtualmachine_list', - url_params={'role': 'slug'}, - verbose_name='VMs' - ) - color = ColorColumn() - vm_role = BooleanColumn() - actions = ButtonsColumn(DeviceRole, pk_field='slug') - - class Meta(BaseTable.Meta): - model = DeviceRole - fields = ('pk', 'name', 'device_count', 'vm_count', 'color', 'vm_role', 'description', 'slug', 'actions') - default_columns = ('pk', 'name', 'device_count', 'vm_count', 'color', 'vm_role', 'description', 'actions') - - -# -# Platforms -# - -class PlatformTable(BaseTable): - pk = ToggleColumn() - device_count = LinkedCountColumn( - viewname='dcim:device_list', - url_params={'platform': 'slug'}, - verbose_name='Devices' - ) - vm_count = LinkedCountColumn( - viewname='virtualization:virtualmachine_list', - url_params={'platform': 'slug'}, - verbose_name='VMs' - ) - actions = ButtonsColumn(Platform, pk_field='slug') - - class Meta(BaseTable.Meta): - model = Platform - fields = ( - 'pk', 'name', 'manufacturer', 'device_count', 'vm_count', 'slug', 'napalm_driver', 'napalm_args', - 'description', 'actions', - ) - default_columns = ( - 'pk', 'name', 'manufacturer', 'device_count', 'vm_count', 'napalm_driver', 'description', 'actions', - ) - - -# -# Devices -# - -class DeviceTable(BaseTable): - pk = ToggleColumn() - name = tables.TemplateColumn( - order_by=('_name',), - template_code=DEVICE_LINK - ) - status = ChoiceFieldColumn() - tenant = tables.TemplateColumn( - template_code=COL_TENANT - ) - site = tables.Column( - linkify=True - ) - rack = tables.Column( - linkify=True - ) - device_role = ColoredLabelColumn( - verbose_name='Role' - ) - device_type = tables.LinkColumn( - viewname='dcim:devicetype', - args=[Accessor('device_type__pk')], - verbose_name='Type', - text=lambda record: record.device_type.display_name - ) - primary_ip = tables.Column( - linkify=True, - verbose_name='IP Address' - ) - primary_ip4 = tables.Column( - linkify=True, - verbose_name='IPv4 Address' - ) - primary_ip6 = tables.Column( - linkify=True, - verbose_name='IPv6 Address' - ) - cluster = tables.LinkColumn( - viewname='virtualization:cluster', - args=[Accessor('cluster__pk')] - ) - virtual_chassis = tables.LinkColumn( - viewname='dcim:virtualchassis', - args=[Accessor('virtual_chassis__pk')] - ) - vc_position = tables.Column( - verbose_name='VC Position' - ) - vc_priority = tables.Column( - verbose_name='VC Priority' - ) - tags = TagColumn( - url_name='dcim:device_list' - ) - - class Meta(BaseTable.Meta): - model = Device - fields = ( - 'pk', 'name', 'status', 'tenant', 'device_role', 'device_type', 'platform', 'serial', 'asset_tag', 'site', - 'rack', 'position', 'face', 'primary_ip', 'primary_ip4', 'primary_ip6', 'cluster', 'virtual_chassis', - 'vc_position', 'vc_priority', 'tags', - ) - default_columns = ( - 'pk', 'name', 'status', 'tenant', 'site', 'rack', 'device_role', 'device_type', 'primary_ip', - ) - - -class DeviceImportTable(BaseTable): - name = tables.TemplateColumn( - template_code=DEVICE_LINK - ) - status = ChoiceFieldColumn() - tenant = tables.TemplateColumn( - template_code=COL_TENANT - ) - site = tables.Column( - linkify=True - ) - rack = tables.Column( - linkify=True - ) - device_role = tables.Column( - verbose_name='Role' - ) - device_type = tables.Column( - verbose_name='Type' - ) - - class Meta(BaseTable.Meta): - model = Device - fields = ('name', 'status', 'tenant', 'site', 'rack', 'position', 'device_role', 'device_type') - empty_text = False - - -# -# Device components -# - -class DeviceComponentTable(BaseTable): - pk = ToggleColumn() - device = tables.Column( - linkify=True - ) - name = tables.Column( - linkify=True, - order_by=('_name',) - ) - cable = tables.Column( - linkify=True - ) - - class Meta(BaseTable.Meta): - order_by = ('device', 'name') - - -class ConsolePortTable(DeviceComponentTable): - tags = TagColumn( - url_name='dcim:consoleport_list' - ) - - class Meta(DeviceComponentTable.Meta): - model = ConsolePort - fields = ('pk', 'device', 'name', 'label', 'type', 'description', 'cable', 'tags') - default_columns = ('pk', 'device', 'name', 'label', 'type', 'description') - - -class ConsoleServerPortTable(DeviceComponentTable): - tags = TagColumn( - url_name='dcim:consoleserverport_list' - ) - - class Meta(DeviceComponentTable.Meta): - model = ConsoleServerPort - fields = ('pk', 'device', 'name', 'label', 'type', 'description', 'cable', 'tags') - default_columns = ('pk', 'device', 'name', 'label', 'type', 'description') - - -class PowerPortTable(DeviceComponentTable): - tags = TagColumn( - url_name='dcim:powerport_list' - ) - - class Meta(DeviceComponentTable.Meta): - model = PowerPort - fields = ( - 'pk', 'device', 'name', 'label', 'type', 'description', 'maximum_draw', 'allocated_draw', 'cable', 'tags', - ) - default_columns = ('pk', 'device', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description') - - -class PowerOutletTable(DeviceComponentTable): - tags = TagColumn( - url_name='dcim:poweroutlet_list' - ) - - class Meta(DeviceComponentTable.Meta): - model = PowerOutlet - fields = ('pk', 'device', 'name', 'label', 'type', 'description', 'power_port', 'feed_leg', 'cable', 'tags') - default_columns = ('pk', 'device', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description') - - -class BaseInterfaceTable(BaseTable): - enabled = BooleanColumn() - ip_addresses = tables.TemplateColumn( - template_code=INTERFACE_IPADDRESSES, - orderable=False, - verbose_name='IP Addresses' - ) - untagged_vlan = tables.Column(linkify=True) - tagged_vlans = tables.TemplateColumn( - template_code=INTERFACE_TAGGED_VLANS, - orderable=False, - verbose_name='Tagged VLANs' - ) - - -class InterfaceTable(DeviceComponentTable, BaseInterfaceTable): - tags = TagColumn( - url_name='dcim:interface_list' - ) - - class Meta(DeviceComponentTable.Meta): - model = Interface - fields = ( - 'pk', 'device', 'name', 'label', 'enabled', 'type', 'mgmt_only', 'mtu', 'mode', 'mac_address', - 'description', 'cable', 'tags', 'ip_addresses', 'untagged_vlan', 'tagged_vlans', - ) - default_columns = ('pk', 'device', 'name', 'label', 'enabled', 'type', 'description') - - -class FrontPortTable(DeviceComponentTable): - rear_port_position = tables.Column( - verbose_name='Position' - ) - tags = TagColumn( - url_name='dcim:frontport_list' - ) - - class Meta(DeviceComponentTable.Meta): - model = FrontPort - fields = ( - 'pk', 'device', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description', 'cable', 'tags', - ) - default_columns = ('pk', 'device', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description') - - -class RearPortTable(DeviceComponentTable): - tags = TagColumn( - url_name='dcim:rearport_list' - ) - - class Meta(DeviceComponentTable.Meta): - model = RearPort - fields = ('pk', 'device', 'name', 'label', 'type', 'positions', 'description', 'cable', 'tags') - default_columns = ('pk', 'device', 'name', 'label', 'type', 'description') - - -class DeviceBayTable(DeviceComponentTable): - installed_device = tables.Column( - linkify=True - ) - tags = TagColumn( - url_name='dcim:devicebay_list' - ) - - class Meta(DeviceComponentTable.Meta): - model = DeviceBay - fields = ('pk', 'device', 'name', 'label', 'installed_device', 'description', 'tags') - default_columns = ('pk', 'device', 'name', 'label', 'installed_device', 'description') - - -class InventoryItemTable(DeviceComponentTable): - manufacturer = tables.Column( - linkify=True - ) - discovered = BooleanColumn() - tags = TagColumn( - url_name='dcim:inventoryitem_list' - ) - cable = None # Override DeviceComponentTable - - class Meta(DeviceComponentTable.Meta): - model = InventoryItem - fields = ( - 'pk', 'device', 'name', 'label', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'description', - 'discovered', 'tags', - ) - default_columns = ('pk', 'device', 'name', 'label', 'manufacturer', 'part_id', 'serial', 'asset_tag') - - -# -# Cables -# - -class CableTable(BaseTable): - pk = ToggleColumn() - id = tables.Column( - linkify=True, - verbose_name='ID' - ) - termination_a_parent = tables.TemplateColumn( - template_code=CABLE_TERMINATION_PARENT, - accessor=Accessor('termination_a'), - orderable=False, - verbose_name='Side A' - ) - termination_a = tables.LinkColumn( - accessor=Accessor('termination_a'), - orderable=False, - verbose_name='Termination A' - ) - termination_b_parent = tables.TemplateColumn( - template_code=CABLE_TERMINATION_PARENT, - accessor=Accessor('termination_b'), - orderable=False, - verbose_name='Side B' - ) - termination_b = tables.LinkColumn( - accessor=Accessor('termination_b'), - orderable=False, - verbose_name='Termination B' - ) - status = ChoiceFieldColumn() - length = tables.TemplateColumn( - template_code=CABLE_LENGTH, - order_by='_abs_length' - ) - color = ColorColumn() - tags = TagColumn( - url_name='dcim:cable_list' - ) - - class Meta(BaseTable.Meta): - model = Cable - fields = ( - 'pk', 'id', 'label', 'termination_a_parent', 'termination_a', 'termination_b_parent', 'termination_b', - 'status', 'type', 'color', 'length', 'tags', - ) - default_columns = ( - 'pk', 'id', 'label', 'termination_a_parent', 'termination_a', 'termination_b_parent', 'termination_b', - 'status', 'type', - ) - - -# -# Device connections -# - -class ConsoleConnectionTable(BaseTable): - console_server = tables.Column( - accessor=Accessor('_path__destination__device'), - orderable=False, - linkify=True, - verbose_name='Console Server' - ) - console_server_port = tables.Column( - accessor=Accessor('_path__destination'), - orderable=False, - linkify=True, - verbose_name='Port' - ) - device = tables.Column( - linkify=True - ) - name = tables.Column( - linkify=True, - verbose_name='Console Port' - ) - reachable = BooleanColumn( - accessor=Accessor('_path__is_active'), - verbose_name='Reachable' - ) - - add_prefetch = False - - class Meta(BaseTable.Meta): - model = ConsolePort - fields = ('device', 'name', 'console_server', 'console_server_port', 'reachable') - - -class PowerConnectionTable(BaseTable): - pdu = tables.Column( - accessor=Accessor('_path__destination__device'), - orderable=False, - linkify=True, - verbose_name='PDU' - ) - outlet = tables.Column( - accessor=Accessor('_path__destination'), - orderable=False, - linkify=True, - verbose_name='Outlet' - ) - device = tables.Column( - linkify=True - ) - name = tables.Column( - linkify=True, - verbose_name='Power Port' - ) - reachable = BooleanColumn( - accessor=Accessor('_path__is_active'), - verbose_name='Reachable' - ) - - add_prefetch = False - - class Meta(BaseTable.Meta): - model = PowerPort - fields = ('device', 'name', 'pdu', 'outlet', 'reachable') - - -class InterfaceConnectionTable(BaseTable): - device_a = tables.Column( - accessor=Accessor('device'), - linkify=True, - verbose_name='Device A' - ) - interface_a = tables.Column( - accessor=Accessor('name'), - linkify=True, - verbose_name='Interface A' - ) - device_b = tables.Column( - accessor=Accessor('_path__destination__device'), - orderable=False, - linkify=True, - verbose_name='Device B' - ) - interface_b = tables.Column( - accessor=Accessor('_path__destination'), - orderable=False, - linkify=True, - verbose_name='Interface B' - ) - reachable = BooleanColumn( - accessor=Accessor('_path__is_active'), - verbose_name='Reachable' - ) - - add_prefetch = False - - class Meta(BaseTable.Meta): - model = Interface - fields = ('device_a', 'interface_a', 'device_b', 'interface_b', 'reachable') - - -# -# Virtual chassis -# - -class VirtualChassisTable(BaseTable): - pk = ToggleColumn() - name = tables.Column( - linkify=True - ) - master = tables.Column( - linkify=True - ) - member_count = LinkedCountColumn( - viewname='dcim:device_list', - url_params={'virtual_chassis_id': 'pk'}, - verbose_name='Members' - ) - tags = TagColumn( - url_name='dcim:virtualchassis_list' - ) - - class Meta(BaseTable.Meta): - model = VirtualChassis - fields = ('pk', 'name', 'domain', 'master', 'member_count', 'tags') - default_columns = ('pk', 'name', 'domain', 'master', 'member_count') - - -# -# Power panels -# - -class PowerPanelTable(BaseTable): - pk = ToggleColumn() - name = tables.LinkColumn() - site = tables.LinkColumn( - viewname='dcim:site', - args=[Accessor('site__slug')] - ) - powerfeed_count = LinkedCountColumn( - viewname='dcim:powerfeed_list', - url_params={'power_panel_id': 'pk'}, - verbose_name='Feeds' - ) - tags = TagColumn( - url_name='dcim:powerpanel_list' - ) - - class Meta(BaseTable.Meta): - model = PowerPanel - fields = ('pk', 'name', 'site', 'rack_group', 'powerfeed_count', 'tags') - default_columns = ('pk', 'name', 'site', 'rack_group', 'powerfeed_count') - - -# -# Power feeds -# - -class PowerFeedTable(BaseTable): - pk = ToggleColumn() - name = tables.LinkColumn() - power_panel = tables.Column( - linkify=True - ) - rack = tables.Column( - linkify=True - ) - status = ChoiceFieldColumn() - type = ChoiceFieldColumn() - max_utilization = tables.TemplateColumn( - template_code="{{ value }}%" - ) - cable = tables.TemplateColumn( - template_code=POWERFEED_CABLE, - orderable=False - ) - connection = tables.TemplateColumn( - accessor='get_cable_peer', - template_code=POWERFEED_CABLETERMINATION, - orderable=False - ) - available_power = tables.Column( - verbose_name='Available power (VA)' - ) - tags = TagColumn( - url_name='dcim:powerfeed_list' - ) - - class Meta(BaseTable.Meta): - model = PowerFeed - fields = ( - 'pk', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase', - 'max_utilization', 'cable', 'connection', 'available_power', 'tags', - ) - default_columns = ( - 'pk', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase', 'cable', - 'connection', - ) diff --git a/netbox/dcim/tables/__init__.py b/netbox/dcim/tables/__init__.py new file mode 100644 index 000000000..e68779e3d --- /dev/null +++ b/netbox/dcim/tables/__init__.py @@ -0,0 +1,114 @@ +import django_tables2 as tables +from django_tables2.utils import Accessor + +from utilities.tables import BaseTable, BooleanColumn +from dcim.models import ConsolePort, Interface, PowerPort +from .cables import * +from .devices import * +from .devicetypes import * +from .power import * +from .racks import * +from .sites import * + + +# +# Device connections +# + +class ConsoleConnectionTable(BaseTable): + console_server = tables.Column( + accessor=Accessor('_path__destination__device'), + orderable=False, + linkify=True, + verbose_name='Console Server' + ) + console_server_port = tables.Column( + accessor=Accessor('_path__destination'), + orderable=False, + linkify=True, + verbose_name='Port' + ) + device = tables.Column( + linkify=True + ) + name = tables.Column( + linkify=True, + verbose_name='Console Port' + ) + reachable = BooleanColumn( + accessor=Accessor('_path__is_active'), + verbose_name='Reachable' + ) + + add_prefetch = False + + class Meta(BaseTable.Meta): + model = ConsolePort + fields = ('device', 'name', 'console_server', 'console_server_port', 'reachable') + + +class PowerConnectionTable(BaseTable): + pdu = tables.Column( + accessor=Accessor('_path__destination__device'), + orderable=False, + linkify=True, + verbose_name='PDU' + ) + outlet = tables.Column( + accessor=Accessor('_path__destination'), + orderable=False, + linkify=True, + verbose_name='Outlet' + ) + device = tables.Column( + linkify=True + ) + name = tables.Column( + linkify=True, + verbose_name='Power Port' + ) + reachable = BooleanColumn( + accessor=Accessor('_path__is_active'), + verbose_name='Reachable' + ) + + add_prefetch = False + + class Meta(BaseTable.Meta): + model = PowerPort + fields = ('device', 'name', 'pdu', 'outlet', 'reachable') + + +class InterfaceConnectionTable(BaseTable): + device_a = tables.Column( + accessor=Accessor('device'), + linkify=True, + verbose_name='Device A' + ) + interface_a = tables.Column( + accessor=Accessor('name'), + linkify=True, + verbose_name='Interface A' + ) + device_b = tables.Column( + accessor=Accessor('_path__destination__device'), + orderable=False, + linkify=True, + verbose_name='Device B' + ) + interface_b = tables.Column( + accessor=Accessor('_path__destination'), + orderable=False, + linkify=True, + verbose_name='Interface B' + ) + reachable = BooleanColumn( + accessor=Accessor('_path__is_active'), + verbose_name='Reachable' + ) + + add_prefetch = False + + class Meta(BaseTable.Meta): + model = Interface + fields = ('device_a', 'interface_a', 'device_b', 'interface_b', 'reachable') diff --git a/netbox/dcim/tables/cables.py b/netbox/dcim/tables/cables.py new file mode 100644 index 000000000..cdb79f4e1 --- /dev/null +++ b/netbox/dcim/tables/cables.py @@ -0,0 +1,64 @@ +import django_tables2 as tables +from django_tables2.utils import Accessor + +from dcim.models import Cable +from utilities.tables import BaseTable, ChoiceFieldColumn, ColorColumn, TagColumn, ToggleColumn +from .template_code import CABLE_LENGTH, CABLE_TERMINATION_PARENT + +__all__ = ( + 'CableTable', +) + + +# +# Cables +# + +class CableTable(BaseTable): + pk = ToggleColumn() + id = tables.Column( + linkify=True, + verbose_name='ID' + ) + termination_a_parent = tables.TemplateColumn( + template_code=CABLE_TERMINATION_PARENT, + accessor=Accessor('termination_a'), + orderable=False, + verbose_name='Side A' + ) + termination_a = tables.LinkColumn( + accessor=Accessor('termination_a'), + orderable=False, + verbose_name='Termination A' + ) + termination_b_parent = tables.TemplateColumn( + template_code=CABLE_TERMINATION_PARENT, + accessor=Accessor('termination_b'), + orderable=False, + verbose_name='Side B' + ) + termination_b = tables.LinkColumn( + accessor=Accessor('termination_b'), + orderable=False, + verbose_name='Termination B' + ) + status = ChoiceFieldColumn() + length = tables.TemplateColumn( + template_code=CABLE_LENGTH, + order_by='_abs_length' + ) + color = ColorColumn() + tags = TagColumn( + url_name='dcim:cable_list' + ) + + class Meta(BaseTable.Meta): + model = Cable + fields = ( + 'pk', 'id', 'label', 'termination_a_parent', 'termination_a', 'termination_b_parent', 'termination_b', + 'status', 'type', 'color', 'length', 'tags', + ) + default_columns = ( + 'pk', 'id', 'label', 'termination_a_parent', 'termination_a', 'termination_b_parent', 'termination_b', + 'status', 'type', + ) diff --git a/netbox/dcim/tables/devices.py b/netbox/dcim/tables/devices.py new file mode 100644 index 000000000..c614c534b --- /dev/null +++ b/netbox/dcim/tables/devices.py @@ -0,0 +1,366 @@ +import django_tables2 as tables +from django_tables2.utils import Accessor + +from dcim.models import ( + ConsolePort, ConsoleServerPort, Device, DeviceBay, DeviceRole, FrontPort, Interface, InventoryItem, Platform, + PowerOutlet, PowerPort, RearPort, VirtualChassis, +) +from tenancy.tables import COL_TENANT +from utilities.tables import ( + BaseTable, BooleanColumn, ButtonsColumn, ChoiceFieldColumn, ColorColumn, ColoredLabelColumn, LinkedCountColumn, + TagColumn, ToggleColumn, +) +from .template_code import DEVICE_LINK, INTERFACE_IPADDRESSES, INTERFACE_TAGGED_VLANS + +__all__ = ( + 'ConsolePortTable', + 'ConsoleServerPortTable', + 'DeviceImportTable', + 'DeviceTable', + 'DeviceBayTable', + 'DeviceRoleTable', + 'FrontPortTable', + 'InterfaceTable', + 'InventoryItemTable', + 'PlatformTable', + 'PowerOutletTable', + 'PowerPortTable', + 'RearPortTable', + 'VirtualChassisTable', +) + + +# +# Device roles +# + +class DeviceRoleTable(BaseTable): + pk = ToggleColumn() + device_count = LinkedCountColumn( + viewname='dcim:device_list', + url_params={'role': 'slug'}, + verbose_name='Devices' + ) + vm_count = LinkedCountColumn( + viewname='virtualization:virtualmachine_list', + url_params={'role': 'slug'}, + verbose_name='VMs' + ) + color = ColorColumn() + vm_role = BooleanColumn() + actions = ButtonsColumn(DeviceRole, pk_field='slug') + + class Meta(BaseTable.Meta): + model = DeviceRole + fields = ('pk', 'name', 'device_count', 'vm_count', 'color', 'vm_role', 'description', 'slug', 'actions') + default_columns = ('pk', 'name', 'device_count', 'vm_count', 'color', 'vm_role', 'description', 'actions') + + +# +# Platforms +# + +class PlatformTable(BaseTable): + pk = ToggleColumn() + device_count = LinkedCountColumn( + viewname='dcim:device_list', + url_params={'platform': 'slug'}, + verbose_name='Devices' + ) + vm_count = LinkedCountColumn( + viewname='virtualization:virtualmachine_list', + url_params={'platform': 'slug'}, + verbose_name='VMs' + ) + actions = ButtonsColumn(Platform, pk_field='slug') + + class Meta(BaseTable.Meta): + model = Platform + fields = ( + 'pk', 'name', 'manufacturer', 'device_count', 'vm_count', 'slug', 'napalm_driver', 'napalm_args', + 'description', 'actions', + ) + default_columns = ( + 'pk', 'name', 'manufacturer', 'device_count', 'vm_count', 'napalm_driver', 'description', 'actions', + ) + + +# +# Devices +# + +class DeviceTable(BaseTable): + pk = ToggleColumn() + name = tables.TemplateColumn( + order_by=('_name',), + template_code=DEVICE_LINK + ) + status = ChoiceFieldColumn() + tenant = tables.TemplateColumn( + template_code=COL_TENANT + ) + site = tables.Column( + linkify=True + ) + rack = tables.Column( + linkify=True + ) + device_role = ColoredLabelColumn( + verbose_name='Role' + ) + device_type = tables.LinkColumn( + viewname='dcim:devicetype', + args=[Accessor('device_type__pk')], + verbose_name='Type', + text=lambda record: record.device_type.display_name + ) + primary_ip = tables.Column( + linkify=True, + verbose_name='IP Address' + ) + primary_ip4 = tables.Column( + linkify=True, + verbose_name='IPv4 Address' + ) + primary_ip6 = tables.Column( + linkify=True, + verbose_name='IPv6 Address' + ) + cluster = tables.LinkColumn( + viewname='virtualization:cluster', + args=[Accessor('cluster__pk')] + ) + virtual_chassis = tables.LinkColumn( + viewname='dcim:virtualchassis', + args=[Accessor('virtual_chassis__pk')] + ) + vc_position = tables.Column( + verbose_name='VC Position' + ) + vc_priority = tables.Column( + verbose_name='VC Priority' + ) + tags = TagColumn( + url_name='dcim:device_list' + ) + + class Meta(BaseTable.Meta): + model = Device + fields = ( + 'pk', 'name', 'status', 'tenant', 'device_role', 'device_type', 'platform', 'serial', 'asset_tag', 'site', + 'rack', 'position', 'face', 'primary_ip', 'primary_ip4', 'primary_ip6', 'cluster', 'virtual_chassis', + 'vc_position', 'vc_priority', 'tags', + ) + default_columns = ( + 'pk', 'name', 'status', 'tenant', 'site', 'rack', 'device_role', 'device_type', 'primary_ip', + ) + + +class DeviceImportTable(BaseTable): + name = tables.TemplateColumn( + template_code=DEVICE_LINK + ) + status = ChoiceFieldColumn() + tenant = tables.TemplateColumn( + template_code=COL_TENANT + ) + site = tables.Column( + linkify=True + ) + rack = tables.Column( + linkify=True + ) + device_role = tables.Column( + verbose_name='Role' + ) + device_type = tables.Column( + verbose_name='Type' + ) + + class Meta(BaseTable.Meta): + model = Device + fields = ('name', 'status', 'tenant', 'site', 'rack', 'position', 'device_role', 'device_type') + empty_text = False + + +# +# Device components +# + +class DeviceComponentTable(BaseTable): + pk = ToggleColumn() + device = tables.Column( + linkify=True + ) + name = tables.Column( + linkify=True, + order_by=('_name',) + ) + cable = tables.Column( + linkify=True + ) + + class Meta(BaseTable.Meta): + order_by = ('device', 'name') + + +class ConsolePortTable(DeviceComponentTable): + tags = TagColumn( + url_name='dcim:consoleport_list' + ) + + class Meta(DeviceComponentTable.Meta): + model = ConsolePort + fields = ('pk', 'device', 'name', 'label', 'type', 'description', 'cable', 'tags') + default_columns = ('pk', 'device', 'name', 'label', 'type', 'description') + + +class ConsoleServerPortTable(DeviceComponentTable): + tags = TagColumn( + url_name='dcim:consoleserverport_list' + ) + + class Meta(DeviceComponentTable.Meta): + model = ConsoleServerPort + fields = ('pk', 'device', 'name', 'label', 'type', 'description', 'cable', 'tags') + default_columns = ('pk', 'device', 'name', 'label', 'type', 'description') + + +class PowerPortTable(DeviceComponentTable): + tags = TagColumn( + url_name='dcim:powerport_list' + ) + + class Meta(DeviceComponentTable.Meta): + model = PowerPort + fields = ( + 'pk', 'device', 'name', 'label', 'type', 'description', 'maximum_draw', 'allocated_draw', 'cable', 'tags', + ) + default_columns = ('pk', 'device', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description') + + +class PowerOutletTable(DeviceComponentTable): + tags = TagColumn( + url_name='dcim:poweroutlet_list' + ) + + class Meta(DeviceComponentTable.Meta): + model = PowerOutlet + fields = ('pk', 'device', 'name', 'label', 'type', 'description', 'power_port', 'feed_leg', 'cable', 'tags') + default_columns = ('pk', 'device', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description') + + +class BaseInterfaceTable(BaseTable): + enabled = BooleanColumn() + ip_addresses = tables.TemplateColumn( + template_code=INTERFACE_IPADDRESSES, + orderable=False, + verbose_name='IP Addresses' + ) + untagged_vlan = tables.Column(linkify=True) + tagged_vlans = tables.TemplateColumn( + template_code=INTERFACE_TAGGED_VLANS, + orderable=False, + verbose_name='Tagged VLANs' + ) + + +class InterfaceTable(DeviceComponentTable, BaseInterfaceTable): + tags = TagColumn( + url_name='dcim:interface_list' + ) + + class Meta(DeviceComponentTable.Meta): + model = Interface + fields = ( + 'pk', 'device', 'name', 'label', 'enabled', 'type', 'mgmt_only', 'mtu', 'mode', 'mac_address', + 'description', 'cable', 'tags', 'ip_addresses', 'untagged_vlan', 'tagged_vlans', + ) + default_columns = ('pk', 'device', 'name', 'label', 'enabled', 'type', 'description') + + +class FrontPortTable(DeviceComponentTable): + rear_port_position = tables.Column( + verbose_name='Position' + ) + tags = TagColumn( + url_name='dcim:frontport_list' + ) + + class Meta(DeviceComponentTable.Meta): + model = FrontPort + fields = ( + 'pk', 'device', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description', 'cable', 'tags', + ) + default_columns = ('pk', 'device', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description') + + +class RearPortTable(DeviceComponentTable): + tags = TagColumn( + url_name='dcim:rearport_list' + ) + + class Meta(DeviceComponentTable.Meta): + model = RearPort + fields = ('pk', 'device', 'name', 'label', 'type', 'positions', 'description', 'cable', 'tags') + default_columns = ('pk', 'device', 'name', 'label', 'type', 'description') + + +class DeviceBayTable(DeviceComponentTable): + installed_device = tables.Column( + linkify=True + ) + tags = TagColumn( + url_name='dcim:devicebay_list' + ) + + class Meta(DeviceComponentTable.Meta): + model = DeviceBay + fields = ('pk', 'device', 'name', 'label', 'installed_device', 'description', 'tags') + default_columns = ('pk', 'device', 'name', 'label', 'installed_device', 'description') + + +class InventoryItemTable(DeviceComponentTable): + manufacturer = tables.Column( + linkify=True + ) + discovered = BooleanColumn() + tags = TagColumn( + url_name='dcim:inventoryitem_list' + ) + cable = None # Override DeviceComponentTable + + class Meta(DeviceComponentTable.Meta): + model = InventoryItem + fields = ( + 'pk', 'device', 'name', 'label', 'manufacturer', 'part_id', 'serial', 'asset_tag', 'description', + 'discovered', 'tags', + ) + default_columns = ('pk', 'device', 'name', 'label', 'manufacturer', 'part_id', 'serial', 'asset_tag') + + +# +# Virtual chassis +# + +class VirtualChassisTable(BaseTable): + pk = ToggleColumn() + name = tables.Column( + linkify=True + ) + master = tables.Column( + linkify=True + ) + member_count = LinkedCountColumn( + viewname='dcim:device_list', + url_params={'virtual_chassis_id': 'pk'}, + verbose_name='Members' + ) + tags = TagColumn( + url_name='dcim:virtualchassis_list' + ) + + class Meta(BaseTable.Meta): + model = VirtualChassis + fields = ('pk', 'name', 'domain', 'master', 'member_count', 'tags') + default_columns = ('pk', 'name', 'domain', 'master', 'member_count') diff --git a/netbox/dcim/tables/devicetypes.py b/netbox/dcim/tables/devicetypes.py new file mode 100644 index 000000000..b65289fcf --- /dev/null +++ b/netbox/dcim/tables/devicetypes.py @@ -0,0 +1,192 @@ +import django_tables2 as tables + +from dcim.models import ( + ConsolePortTemplate, ConsoleServerPortTemplate, DeviceBayTemplate, DeviceType, FrontPortTemplate, InterfaceTemplate, + Manufacturer, PowerOutletTemplate, PowerPortTemplate, RearPortTemplate, +) +from utilities.tables import BaseTable, BooleanColumn, ButtonsColumn, LinkedCountColumn, TagColumn, ToggleColumn + +__all__ = ( + 'ConsolePortTemplateTable', + 'ConsoleServerPortTemplateTable', + 'DeviceBayTemplateTable', + 'DeviceTypeTable', + 'FrontPortTemplateTable', + 'InterfaceTemplateTable', + 'ManufacturerTable', + 'PowerOutletTemplateTable', + 'PowerPortTemplateTable', + 'RearPortTemplateTable', +) + + +# +# Manufacturers +# + +class ManufacturerTable(BaseTable): + pk = ToggleColumn() + name = tables.LinkColumn() + devicetype_count = tables.Column( + verbose_name='Device Types' + ) + inventoryitem_count = tables.Column( + verbose_name='Inventory Items' + ) + platform_count = tables.Column( + verbose_name='Platforms' + ) + slug = tables.Column() + actions = ButtonsColumn(Manufacturer, pk_field='slug') + + class Meta(BaseTable.Meta): + model = Manufacturer + fields = ( + 'pk', 'name', 'devicetype_count', 'inventoryitem_count', 'platform_count', 'description', 'slug', 'actions', + ) + + +# +# Device types +# + +class DeviceTypeTable(BaseTable): + pk = ToggleColumn() + model = tables.Column( + linkify=True, + verbose_name='Device Type' + ) + is_full_depth = BooleanColumn( + verbose_name='Full Depth' + ) + instance_count = LinkedCountColumn( + viewname='dcim:device_list', + url_params={'device_type_id': 'pk'}, + verbose_name='Instances' + ) + tags = TagColumn( + url_name='dcim:devicetype_list' + ) + + class Meta(BaseTable.Meta): + model = DeviceType + fields = ( + 'pk', 'model', 'manufacturer', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role', + 'instance_count', 'tags', + ) + default_columns = ( + 'pk', 'model', 'manufacturer', 'part_number', 'u_height', 'is_full_depth', 'instance_count', + ) + + +# +# Device type components +# + +class ComponentTemplateTable(BaseTable): + pk = ToggleColumn() + name = tables.Column( + order_by=('_name',) + ) + + +class ConsolePortTemplateTable(ComponentTemplateTable): + actions = ButtonsColumn( + model=ConsolePortTemplate, + buttons=('edit', 'delete') + ) + + class Meta(BaseTable.Meta): + model = ConsolePortTemplate + fields = ('pk', 'name', 'label', 'type', 'description', 'actions') + empty_text = "None" + + +class ConsoleServerPortTemplateTable(ComponentTemplateTable): + actions = ButtonsColumn( + model=ConsoleServerPortTemplate, + buttons=('edit', 'delete') + ) + + class Meta(BaseTable.Meta): + model = ConsoleServerPortTemplate + fields = ('pk', 'name', 'label', 'type', 'description', 'actions') + empty_text = "None" + + +class PowerPortTemplateTable(ComponentTemplateTable): + actions = ButtonsColumn( + model=PowerPortTemplate, + buttons=('edit', 'delete') + ) + + class Meta(BaseTable.Meta): + model = PowerPortTemplate + fields = ('pk', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description', 'actions') + empty_text = "None" + + +class PowerOutletTemplateTable(ComponentTemplateTable): + actions = ButtonsColumn( + model=PowerOutletTemplate, + buttons=('edit', 'delete') + ) + + class Meta(BaseTable.Meta): + model = PowerOutletTemplate + fields = ('pk', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description', 'actions') + empty_text = "None" + + +class InterfaceTemplateTable(ComponentTemplateTable): + mgmt_only = BooleanColumn( + verbose_name='Management Only' + ) + actions = ButtonsColumn( + model=InterfaceTemplate, + buttons=('edit', 'delete') + ) + + class Meta(BaseTable.Meta): + model = InterfaceTemplate + fields = ('pk', 'name', 'label', 'mgmt_only', 'type', 'description', 'actions') + empty_text = "None" + + +class FrontPortTemplateTable(ComponentTemplateTable): + rear_port_position = tables.Column( + verbose_name='Position' + ) + actions = ButtonsColumn( + model=FrontPortTemplate, + buttons=('edit', 'delete') + ) + + class Meta(BaseTable.Meta): + model = FrontPortTemplate + fields = ('pk', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description', 'actions') + empty_text = "None" + + +class RearPortTemplateTable(ComponentTemplateTable): + actions = ButtonsColumn( + model=RearPortTemplate, + buttons=('edit', 'delete') + ) + + class Meta(BaseTable.Meta): + model = RearPortTemplate + fields = ('pk', 'name', 'label', 'type', 'positions', 'description', 'actions') + empty_text = "None" + + +class DeviceBayTemplateTable(ComponentTemplateTable): + actions = ButtonsColumn( + model=DeviceBayTemplate, + buttons=('edit', 'delete') + ) + + class Meta(BaseTable.Meta): + model = DeviceBayTemplate + fields = ('pk', 'name', 'label', 'description', 'actions') + empty_text = "None" diff --git a/netbox/dcim/tables/power.py b/netbox/dcim/tables/power.py new file mode 100644 index 000000000..8d90fb620 --- /dev/null +++ b/netbox/dcim/tables/power.py @@ -0,0 +1,83 @@ +import django_tables2 as tables +from django_tables2.utils import Accessor + +from dcim.models import PowerFeed, PowerPanel +from utilities.tables import BaseTable, ChoiceFieldColumn, LinkedCountColumn, TagColumn, ToggleColumn +from .template_code import POWERFEED_CABLE, POWERFEED_CABLETERMINATION + +__all__ = ( + 'PowerFeedTable', + 'PowerPanelTable', +) + + +# +# Power panels +# + +class PowerPanelTable(BaseTable): + pk = ToggleColumn() + name = tables.LinkColumn() + site = tables.LinkColumn( + viewname='dcim:site', + args=[Accessor('site__slug')] + ) + powerfeed_count = LinkedCountColumn( + viewname='dcim:powerfeed_list', + url_params={'power_panel_id': 'pk'}, + verbose_name='Feeds' + ) + tags = TagColumn( + url_name='dcim:powerpanel_list' + ) + + class Meta(BaseTable.Meta): + model = PowerPanel + fields = ('pk', 'name', 'site', 'rack_group', 'powerfeed_count', 'tags') + default_columns = ('pk', 'name', 'site', 'rack_group', 'powerfeed_count') + + +# +# Power feeds +# + +class PowerFeedTable(BaseTable): + pk = ToggleColumn() + name = tables.LinkColumn() + power_panel = tables.Column( + linkify=True + ) + rack = tables.Column( + linkify=True + ) + status = ChoiceFieldColumn() + type = ChoiceFieldColumn() + max_utilization = tables.TemplateColumn( + template_code="{{ value }}%" + ) + cable = tables.TemplateColumn( + template_code=POWERFEED_CABLE, + orderable=False + ) + connection = tables.TemplateColumn( + accessor='get_cable_peer', + template_code=POWERFEED_CABLETERMINATION, + orderable=False + ) + available_power = tables.Column( + verbose_name='Available power (VA)' + ) + tags = TagColumn( + url_name='dcim:powerfeed_list' + ) + + class Meta(BaseTable.Meta): + model = PowerFeed + fields = ( + 'pk', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase', + 'max_utilization', 'cable', 'connection', 'available_power', 'tags', + ) + default_columns = ( + 'pk', 'name', 'power_panel', 'rack', 'status', 'type', 'supply', 'voltage', 'amperage', 'phase', 'cable', + 'connection', + ) diff --git a/netbox/dcim/tables/racks.py b/netbox/dcim/tables/racks.py new file mode 100644 index 000000000..75a5c85ea --- /dev/null +++ b/netbox/dcim/tables/racks.py @@ -0,0 +1,167 @@ +import django_tables2 as tables +from django_tables2.utils import Accessor + +from dcim.models import Rack, RackGroup, RackReservation, RackRole +from tenancy.tables import COL_TENANT +from utilities.tables import ( + BaseTable, ButtonsColumn, ChoiceFieldColumn, ColorColumn, ColoredLabelColumn, LinkedCountColumn, TagColumn, + ToggleColumn, +) +from .template_code import MPTT_LINK, RACKGROUP_ELEVATIONS, UTILIZATION_GRAPH + +__all__ = ( + 'RackTable', + 'RackDetailTable', + 'RackGroupTable', + 'RackReservationTable', + 'RackRoleTable', +) + + +# +# Rack groups +# + +class RackGroupTable(BaseTable): + pk = ToggleColumn() + name = tables.TemplateColumn( + template_code=MPTT_LINK, + orderable=False + ) + site = tables.LinkColumn( + viewname='dcim:site', + args=[Accessor('site__slug')], + verbose_name='Site' + ) + rack_count = tables.Column( + verbose_name='Racks' + ) + actions = ButtonsColumn( + model=RackGroup, + prepend_template=RACKGROUP_ELEVATIONS + ) + + class Meta(BaseTable.Meta): + model = RackGroup + fields = ('pk', 'name', 'site', 'rack_count', 'description', 'slug', 'actions') + default_columns = ('pk', 'name', 'site', 'rack_count', 'description', 'actions') + + +# +# Rack roles +# + +class RackRoleTable(BaseTable): + pk = ToggleColumn() + name = tables.Column(linkify=True) + rack_count = tables.Column(verbose_name='Racks') + color = ColorColumn() + actions = ButtonsColumn(RackRole) + + class Meta(BaseTable.Meta): + model = RackRole + fields = ('pk', 'name', 'rack_count', 'color', 'description', 'slug', 'actions') + default_columns = ('pk', 'name', 'rack_count', 'color', 'description', 'actions') + + +# +# Racks +# + +class RackTable(BaseTable): + pk = ToggleColumn() + name = tables.LinkColumn( + order_by=('_name',) + ) + site = tables.LinkColumn( + viewname='dcim:site', + args=[Accessor('site__slug')] + ) + tenant = tables.TemplateColumn( + template_code=COL_TENANT + ) + status = ChoiceFieldColumn() + role = ColoredLabelColumn() + u_height = tables.TemplateColumn( + template_code="{{ record.u_height }}U", + verbose_name='Height' + ) + + class Meta(BaseTable.Meta): + model = Rack + fields = ( + 'pk', 'name', 'site', 'group', 'status', 'facility_id', 'tenant', 'role', 'serial', 'asset_tag', 'type', + 'width', 'u_height', + ) + default_columns = ('pk', 'name', 'site', 'group', 'status', 'facility_id', 'tenant', 'role', 'u_height') + + +class RackDetailTable(RackTable): + device_count = LinkedCountColumn( + viewname='dcim:device_list', + url_params={'rack_id': 'pk'}, + verbose_name='Devices' + ) + get_utilization = tables.TemplateColumn( + template_code=UTILIZATION_GRAPH, + orderable=False, + verbose_name='Space' + ) + get_power_utilization = tables.TemplateColumn( + template_code=UTILIZATION_GRAPH, + orderable=False, + verbose_name='Power' + ) + tags = TagColumn( + url_name='dcim:rack_list' + ) + + class Meta(RackTable.Meta): + fields = ( + 'pk', 'name', 'site', 'group', 'status', 'facility_id', 'tenant', 'role', 'serial', 'asset_tag', 'type', + 'width', 'u_height', 'device_count', 'get_utilization', 'get_power_utilization', 'tags', + ) + default_columns = ( + 'pk', 'name', 'site', 'group', 'status', 'facility_id', 'tenant', 'role', 'u_height', 'device_count', + 'get_utilization', 'get_power_utilization', + ) + + +# +# Rack reservations +# + +class RackReservationTable(BaseTable): + pk = ToggleColumn() + reservation = tables.Column( + accessor='pk', + linkify=True + ) + site = tables.Column( + accessor=Accessor('rack__site'), + linkify=True + ) + tenant = tables.TemplateColumn( + template_code=COL_TENANT + ) + rack = tables.Column( + linkify=True + ) + unit_list = tables.Column( + orderable=False, + verbose_name='Units' + ) + tags = TagColumn( + url_name='dcim:rackreservation_list' + ) + actions = ButtonsColumn(RackReservation) + + class Meta(BaseTable.Meta): + model = RackReservation + fields = ( + 'pk', 'reservation', 'site', 'rack', 'unit_list', 'user', 'created', 'tenant', 'description', 'tags', + 'actions', + ) + default_columns = ( + 'pk', 'reservation', 'site', 'rack', 'unit_list', 'user', 'description', 'actions', + ) diff --git a/netbox/dcim/tables/sites.py b/netbox/dcim/tables/sites.py new file mode 100644 index 000000000..76f30f507 --- /dev/null +++ b/netbox/dcim/tables/sites.py @@ -0,0 +1,62 @@ +import django_tables2 as tables + +from dcim.models import Region, Site +from tenancy.tables import COL_TENANT +from utilities.tables import BaseTable, ButtonsColumn, ChoiceFieldColumn, TagColumn, ToggleColumn +from .template_code import MPTT_LINK + +__all__ = ( + 'RegionTable', + 'SiteTable', +) + + +# +# Regions +# + +class RegionTable(BaseTable): + pk = ToggleColumn() + name = tables.TemplateColumn( + template_code=MPTT_LINK, + orderable=False + ) + site_count = tables.Column( + verbose_name='Sites' + ) + actions = ButtonsColumn(Region) + + class Meta(BaseTable.Meta): + model = Region + fields = ('pk', 'name', 'slug', 'site_count', 'description', 'actions') + default_columns = ('pk', 'name', 'site_count', 'description', 'actions') + + +# +# Sites +# + +class SiteTable(BaseTable): + pk = ToggleColumn() + name = tables.LinkColumn( + order_by=('_name',) + ) + status = ChoiceFieldColumn() + region = tables.Column( + linkify=True + ) + tenant = tables.TemplateColumn( + template_code=COL_TENANT + ) + tags = TagColumn( + url_name='dcim:site_list' + ) + + class Meta(BaseTable.Meta): + model = Site + fields = ( + 'pk', 'name', 'slug', 'status', 'facility', 'region', 'tenant', 'asn', 'time_zone', 'description', + 'physical_address', 'shipping_address', 'latitude', 'longitude', 'contact_name', 'contact_phone', + 'contact_email', 'tags', + ) + default_columns = ('pk', 'name', 'status', 'facility', 'region', 'tenant', 'asn', 'description') diff --git a/netbox/dcim/tables/template_code.py b/netbox/dcim/tables/template_code.py new file mode 100644 index 000000000..b3840b48b --- /dev/null +++ b/netbox/dcim/tables/template_code.py @@ -0,0 +1,65 @@ +CABLE_LENGTH = """ +{% if record.length %}{{ record.length }} {{ record.get_length_unit_display }}{% else %}—{% endif %} +""" + +CABLE_TERMINATION_PARENT = """ +{% if value.device %} + {{ value.device }} +{% elif value.circuit %} + {{ value.circuit }} +{% elif value.power_panel %} + {{ value.power_panel }} +{% endif %} +""" + +DEVICE_LINK = """ + + {{ record.name|default:'Unnamed device' }} + +""" + +INTERFACE_IPADDRESSES = """ +{% for ip in record.ip_addresses.unrestricted %} + {{ ip }}
+{% endfor %} +""" + +INTERFACE_TAGGED_VLANS = """ +{% for vlan in record.tagged_vlans.unrestricted %} + {{ vlan }}
+{% endfor %} +""" + +MPTT_LINK = """ +{% if record.get_children %} + +{% else %} + +{% endif %} + {{ record.name }} + +""" + +POWERFEED_CABLE = """ +{{ value }} + + + +""" + +POWERFEED_CABLETERMINATION = """ +{{ value.parent }} + +{{ value }} +""" + +RACKGROUP_ELEVATIONS = """ + + + +""" + +UTILIZATION_GRAPH = """ +{% load helpers %} +{% utilization_graph value %} +""" diff --git a/netbox/virtualization/tables.py b/netbox/virtualization/tables.py index 7acae4cc0..956c20784 100644 --- a/netbox/virtualization/tables.py +++ b/netbox/virtualization/tables.py @@ -1,6 +1,6 @@ import django_tables2 as tables -from dcim.tables import BaseInterfaceTable +from dcim.tables.devices import BaseInterfaceTable from tenancy.tables import COL_TENANT from utilities.tables import ( BaseTable, ButtonsColumn, ChoiceFieldColumn, ColoredLabelColumn, LinkedCountColumn, TagColumn, ToggleColumn,