162 lines
5.8 KiB
Python
162 lines
5.8 KiB
Python
import django_tables2 as tables
|
|
from django.utils.html import escape, format_html
|
|
from django.utils.safestring import mark_safe
|
|
from netbox.tables.columns import ToggleColumn
|
|
from utilities.paginator import EnhancedPaginator
|
|
|
|
from netbox_librenms_plugin.utils import (
|
|
get_table_paginate_count,
|
|
get_virtual_chassis_member,
|
|
)
|
|
|
|
|
|
class LibreNMSCableTable(tables.Table):
|
|
"""
|
|
Table for displaying LibreNMS cable data.
|
|
"""
|
|
|
|
selection = ToggleColumn(
|
|
accessor="local_port_id",
|
|
orderable=False,
|
|
visible=True,
|
|
attrs={"td": {"data-col": "selection"}, "input": {"name": "select"}},
|
|
)
|
|
|
|
local_port = tables.Column(verbose_name="Local Port", attrs={"td": {"data-col": "local_port"}})
|
|
remote_port = tables.Column(
|
|
accessor="remote_port_name",
|
|
verbose_name="Remote Port",
|
|
attrs={"td": {"data-col": "remote_port"}},
|
|
)
|
|
remote_device = tables.Column(verbose_name="Remote Device", attrs={"td": {"data-col": "remote_device"}})
|
|
cable_status = tables.Column(verbose_name="Cable Status", attrs={"td": {"data-col": "cable_status"}})
|
|
actions = tables.TemplateColumn(
|
|
template_code="""
|
|
{% if record.can_create_cable %}
|
|
<button type="submit"
|
|
class="btn btn-sm btn-primary"
|
|
onclick="document.getElementById('selected_port').value='{{ record.local_port_id }}'">
|
|
Sync Cable
|
|
</button>
|
|
{% endif %}
|
|
""",
|
|
verbose_name="",
|
|
orderable=False,
|
|
attrs={"td": {"data-col": "actions"}},
|
|
)
|
|
|
|
def __init__(self, *args, device=None, **kwargs):
|
|
"""Initialize table with optional device context."""
|
|
self.device = device
|
|
super().__init__(*args, **kwargs)
|
|
self.tab = "cables"
|
|
self.htmx_url = None
|
|
self.prefix = "cables_"
|
|
|
|
def render_remote_device(self, value, record):
|
|
"""Render remote device name as a link if URL is available."""
|
|
if url := record.get("remote_device_url"):
|
|
return format_html('<a href="{}">{}</a>', url, value)
|
|
return value
|
|
|
|
def render_local_port(self, value, record):
|
|
"""Render local port name as a link if URL is available."""
|
|
if url := record.get("local_port_url"):
|
|
return format_html('<a href="{}">{}</a>', url, value)
|
|
return value
|
|
|
|
def render_remote_port(self, value, record):
|
|
"""Render remote port name as a link if URL is available."""
|
|
if url := record.get("remote_port_url"):
|
|
return format_html('<a href="{}">{}</a>', url, value)
|
|
return value
|
|
|
|
def render_cable_status(self, value, record):
|
|
"""Render cable status as a link if cable URL is available."""
|
|
if url := record.get("cable_url"):
|
|
return format_html('<a href="{}">{}</a>', url, value)
|
|
return value
|
|
|
|
def configure(self, request):
|
|
"""Configure pagination for the table using the current request."""
|
|
paginate = {
|
|
"paginator_class": EnhancedPaginator,
|
|
"per_page": get_table_paginate_count(request, self.prefix),
|
|
}
|
|
tables.RequestConfig(request, paginate).configure(self)
|
|
|
|
class Meta:
|
|
"""Define column sequence, row attributes, and table styling."""
|
|
|
|
sequence = [
|
|
"selection",
|
|
"local_port",
|
|
"remote_port",
|
|
"remote_device",
|
|
"cable_status",
|
|
"actions",
|
|
]
|
|
row_attrs = {
|
|
"data-interface": lambda record: record["local_port_id"],
|
|
"data-device": lambda record: record["device_id"],
|
|
"data-name": lambda record: record["local_port"],
|
|
}
|
|
attrs = {"class": "table table-hover object-list", "id": "librenms-cable-table"}
|
|
|
|
|
|
class VCCableTable(LibreNMSCableTable):
|
|
"""
|
|
Table for displaying LibreNMS cable data for Virtual Chassis devices.
|
|
"""
|
|
|
|
device_selection = tables.Column(
|
|
verbose_name="Virtual Chassis Member",
|
|
accessor="local_port_id",
|
|
attrs={"td": {"class": "device-selection-col", "data-col": "device_selection"}},
|
|
)
|
|
|
|
def __init__(self, *args, device=None, **kwargs):
|
|
"""Initialize the VC cable table with device context."""
|
|
super().__init__(*args, device=device, **kwargs)
|
|
|
|
def render_device_selection(self, value, record):
|
|
"""Render a dropdown to select the virtual chassis member for a port."""
|
|
members = self.device.virtual_chassis.members.all()
|
|
chassis_member = get_virtual_chassis_member(self.device, record["local_port"])
|
|
selected_member_id = chassis_member.id if chassis_member else self.device.id
|
|
port_id = record["local_port_id"]
|
|
|
|
options = [
|
|
f'<option value="{member.id}"{" selected" if member.id == selected_member_id else ""}>{escape(member.name)}</option>'
|
|
for member in members
|
|
]
|
|
|
|
return format_html(
|
|
'<select name="device_selection_{0}" id="device_selection_{0}" class="form-select" data-interface="{0}" data-row-id="{0}">{1}</select>',
|
|
port_id,
|
|
mark_safe("".join(options)),
|
|
)
|
|
|
|
class Meta(LibreNMSCableTable.Meta):
|
|
"""Define column sequence and attributes for the VC cable table."""
|
|
|
|
sequence = [
|
|
"selection",
|
|
"device_selection",
|
|
"local_port",
|
|
"remote_port",
|
|
"remote_device",
|
|
"cable_status",
|
|
"actions",
|
|
]
|
|
row_attrs = {
|
|
"data-interface": lambda record: record["local_port_id"],
|
|
"data-device": lambda record: record["device_id"],
|
|
"data-name": lambda record: record["local_port"],
|
|
"id": lambda record: record["local_port_id"],
|
|
}
|
|
attrs = {
|
|
"class": "table table-hover object-list",
|
|
"id": "librenms-cable-table-vc",
|
|
}
|