first commit
Some checks failed
ci / deploy (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled

This commit is contained in:
Vlastislav Svatek
2026-06-05 10:39:05 +02:00
commit 673e67106e
217 changed files with 76612 additions and 0 deletions

View File

@@ -0,0 +1,161 @@
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",
}