Update static/js/pages/bgp.js

This commit is contained in:
Blackwhitebear8 2025-06-28 11:57:21 +02:00
parent 91c7a85661
commit 5efdaf19b7

View file

@ -1,169 +1,141 @@
function filterTable(searchInputId,tableId){ function filterTable(searchInputId, tableId) {
const input=document.getElementById(searchInputId); const filter = document.getElementById(searchInputId).value.toUpperCase();
const filter=input.value.toUpperCase(); const rows = document.getElementById(tableId).getElementsByTagName("tr");
const table=document.getElementById(tableId);
const tr=table.getElementsByTagName("tr");
for(let i=1;i<tr.length;i++){ for (let i = 1; i < rows.length; i++) {
tr[i].style.display="none"; rows[i].style.display = "none";
const td=tr[i].getElementsByTagName("td"); for (const cell of rows[i].getElementsByTagName("td")) {
for(let j=0;j<td.length;j++){ if ((cell.textContent || cell.innerText).toUpperCase().includes(filter)) {
if(td[j]){ rows[i].style.display = "";
const txtValue=td[j].textContent||td[j].innerText; break;
if(txtValue.toUpperCase().indexOf(filter)>-1){
tr[i].style.display="";
break;
}
} }
} }
} }
} }
function sortTable(tableId,columnIndex,th){ function sortTable(tableId, columnIndex, th) {
const table=document.getElementById(tableId); const tbody = document.getElementById(tableId).tBodies[0];
const tbody=table.tBodies[0]; const rows = Array.from(tbody.rows);
const rows=Array.from(tbody.rows); const headers = Array.from(th.parentNode.children);
const headers=Array.from(th.parentNode.children);
headers.forEach(header=>{ headers.forEach(h => h !== th && (h.className = "", h.dataset.sortState = "none"));
if(header!==th){
header.classList.remove('asc','desc');
header.setAttribute('data-sort-state','none');
}
});
let currentState=th.getAttribute('data-sort-state')||'none'; const state = th.dataset.sortState || "none";
let newState=currentState==='none'?'asc':currentState==='asc'?'desc':'none'; const newState = state === "none" ? "asc" : state === "asc" ? "desc" : "none";
th.dataset.sortState = newState;
th.className = newState !== "none" ? newState : "";
th.classList.remove('asc','desc'); if (newState === "none") {
if(newState!=='none')th.classList.add(newState); rows.sort((a, b) => a.dataset.index - b.dataset.index);
th.setAttribute('data-sort-state',newState); } else {
rows.sort((a, b) => {
if(newState==='none'){ const aTxt = a.cells[columnIndex].textContent.trim();
rows.sort((a,b)=>parseInt(a.getAttribute('data-index'))-parseInt(b.getAttribute('data-index'))); const bTxt = b.cells[columnIndex].textContent.trim();
}else{ const aNum = parseFloat(aTxt.replace(/[^0-9.-]/g, ""));
rows.sort((a,b)=>{ const bNum = parseFloat(bTxt.replace(/[^0-9.-]/g, ""));
const aText=a.cells[columnIndex].textContent.trim(); const numeric = !isNaN(aNum) && !isNaN(bNum);
const bText=b.cells[columnIndex].textContent.trim(); const cmp = numeric ? aNum - bNum : aTxt.localeCompare(bTxt);
return newState === "asc" ? cmp : -cmp;
const aNum=parseFloat(aText.replace(/[^0-9.-]/g,''));
const bNum=parseFloat(bText.replace(/[^0-9.-]/g,''));
const isNumeric=!isNaN(aNum)&&!isNaN(bNum);
return newState==='asc'
?(isNumeric?aNum-bNum:aText.localeCompare(bText))
:(isNumeric?bNum-aNum:bText.localeCompare(aText));
}); });
} }
rows.forEach(r => tbody.appendChild(r));
rows.forEach(row=>tbody.appendChild(row));
} }
async function loadBgpTables(){ async function loadBgpTables() {
const ipv4SummaryEl=document.getElementById("ipv4Summary"); const ipv4Sum = document.getElementById("ipv4Summary");
const ipv6SummaryEl=document.getElementById("ipv6Summary"); const ipv6Sum = document.getElementById("ipv6Summary");
const ipv4Body=document.getElementById("ipv4TableBody"); const ipv4Body = document.getElementById("ipv4TableBody");
const ipv6Body=document.getElementById("ipv6TableBody"); const ipv6Body = document.getElementById("ipv6TableBody");
try{ try {
const response=await fetch("/bgp/json"); const res = await fetch("/bgp/json");
const data=await response.json(); const data = await res.json();
ipv4SummaryEl.innerHTML=` ipv4Sum.innerHTML = summaryHtml(data.ipv4_info);
<p>BGP Router ID: ${data.ipv4_info.router_id}, Local AS Number: <a href="https://bgp.tools/search?q=${data.ipv4_info.local_as}" target="_blank" rel="noopener noreferrer">${data.ipv4_info.local_as}</a>, VRF ID: ${data.ipv4_info.vrf_id}</p> ipv6Sum.innerHTML = summaryHtml(data.ipv6_info);
<p>BGP Table Version:${data.ipv4_info.table_version}</p>
<p>RIB Entries:${data.ipv4_info.rib_entries},using ${data.ipv4_info.rib_memory}</p>
<p>Peers:${data.ipv4_info.peers},using ${data.ipv4_info.peers_memory}</p>
`;
ipv6SummaryEl.innerHTML=` renderPeers(ipv4Body, data.ipv4_peers, "ipv4Table");
<p>BGP Router ID: ${data.ipv6_info.router_id}, Local AS Number: <a href="https://bgp.tools/search?q=${data.ipv6_info.local_as}" target="_blank" rel="noopener noreferrer">${data.ipv6_info.local_as}</a>, VRF ID: ${data.ipv6_info.vrf_id}</p> renderPeers(ipv6Body, data.ipv6_peers, "ipv6Table");
<p>BGP Table Version:${data.ipv6_info.table_version}</p>
<p>RIB Entries:${data.ipv6_info.rib_entries},using ${data.ipv6_info.rib_memory}</p>
<p>Peers:${data.ipv6_info.peers},using ${data.ipv6_info.peers_memory}</p>
`;
ipv4Body.innerHTML=""; bootstrap.Popover.getInstance(document.body)?.dispose?.();
if(data.ipv4_peers.length===0){ document.querySelectorAll('[data-bs-toggle="popover"]').forEach(el => new bootstrap.Popover(el));
ipv4Body.innerHTML=`<tr><td colspan="12" class="text-center">No data available.</td></tr>`;
}else{
data.ipv4_peers.forEach((peer,index)=>{
const row=document.createElement("tr");
row.setAttribute("data-index",index);
row.innerHTML=`
<td>${peer.neighbor}</td>
<td>${peer.version}</td>
<td><a href="https://bgp.tools/search?q=${peer.as_number}" target="_blank">${peer.as_number}</a></td>
<td>${peer.msg_received}</td>
<td>${peer.msg_sent}</td>
<td>${peer.table_version}</td>
<td>${peer.in_queue}</td>
<td>${peer.out_queue}</td>
<td>${peer.up_down}</td>
<td>${peer.state_pfx_rcd}</td>
<td>${peer.prefix_sent}</td>
<td>${peer.description}</td>
`;
ipv4Body.appendChild(row);
});
}
ipv6Body.innerHTML=""; } catch (e) {
if(data.ipv6_peers.length===0){ showError(ipv4Sum, ipv4Body, "IPv4");
ipv6Body.innerHTML=`<tr><td colspan="12" class="text-center">No data available.</td></tr>`; showError(ipv6Sum, ipv6Body, "IPv6");
}else{
data.ipv6_peers.forEach((peer,index)=>{
const row=document.createElement("tr");
row.setAttribute("data-index",index);
row.innerHTML=`
<td>${peer.neighbor}</td>
<td>${peer.version}</td>
<td><a href="https://bgp.tools/search?q=${peer.as_number}" target="_blank">${peer.as_number}</a></td>
<td>${peer.msg_received}</td>
<td>${peer.msg_sent}</td>
<td>${peer.table_version}</td>
<td>${peer.in_queue}</td>
<td>${peer.out_queue}</td>
<td>${peer.up_down}</td>
<td>${peer.state_pfx_rcd}</td>
<td>${peer.prefix_sent}</td>
<td>${peer.description}</td>
`;
ipv6Body.appendChild(row);
});
}
}catch(error){
ipv4SummaryEl.textContent="Error fetching IPv4 data.";
ipv6SummaryEl.textContent="Error fetching IPv6 data.";
ipv4Body.innerHTML=`<tr><td colspan="12" class="text-center text-danger">Error retrieving data.</td></tr>`;
ipv6Body.innerHTML=`<tr><td colspan="12" class="text-center text-danger">Error retrieving data.</td></tr>`;
} }
} }
window.addEventListener("DOMContentLoaded",()=>{ function summaryHtml(info) {
loadBgpTables(); return `
}); <p>BGP Router ID: ${info.router_id},
Local AS: <a href="https://bgp.tools/search?q=${info.local_as}" target="_blank">${info.local_as}</a>,
VRF ID: ${info.vrf_id}</p>
<p>${info.rib_entries} RIB Entries, using ${info.rib_memory}</p>
<p>${info.peers} Peers, using ${info.peers_memory}</p>
<p>BGP Table Version: ${info.table_version}</p>
`;
}
function refreshBGPTable(){ function renderPeers(tbody, peers, tableId) {
const searchInput=document.getElementById("ipv4Search"); tbody.innerHTML = "";
const searchInput2=document.getElementById("ipv6Search"); if (!peers.length) {
const refreshIcon=document.getElementById("refreshIcon"); tbody.innerHTML = `<tr><td colspan="7" class="text-center">No data available.</td></tr>`;
const refreshIcon2=document.getElementById("refreshIcon2"); return;
const refreshSpinner=document.getElementById("refreshSpinner"); }
const refreshSpinner2=document.getElementById("refreshSpinner2");
searchInput.value=""; peers.forEach((p, i) => {
searchInput2.value=""; const popTitle =
`<a href="https://bgp.tools/search?q=${p.as_number}" target="_blank" rel="noopener noreferrer">${p.as_number}</a> details<a>`;
refreshIcon.classList.add("d-none"); const popContent = `
refreshIcon2.classList.add("d-none"); Messages Received: ${p.msg_received}<br>
refreshSpinner.classList.remove("d-none"); Messages Sent: ${p.msg_sent}<br>
refreshSpinner2.classList.remove("d-none"); Inbound Queue: ${p.in_queue}<br>
Outbound Queue: ${p.out_queue}
`.trim();
loadBgpTables().then(()=>{ const tr = document.createElement("tr");
refreshIcon.classList.remove("d-none"); tr.dataset.index = i;
refreshIcon2.classList.remove("d-none"); tr.innerHTML = `
refreshSpinner.classList.add("d-none"); <td>${p.neighbor}</td>
refreshSpinner2.classList.add("d-none"); <td><a href="https://bgp.tools/search?q=${p.as_number}" target="_blank">${p.as_number}</a></td>
<td>${p.up_down}</td>
<td>${p.state_pfx_rcd}</td>
<td>${p.prefix_sent}</td>
<td>${p.description}</td>
<td>
<span tabindex="0" role="button" class="info-icon"
data-bs-toggle="popover"
data-bs-trigger="focus"
data-bs-html="true"
data-bs-title='${popTitle}'
data-bs-content="${popContent}">
</span>
</td>
`;
tbody.appendChild(tr);
}); });
} }
function showError(sumEl, bodyEl, label) {
sumEl.textContent = `Error fetching ${label} data.`;
bodyEl.innerHTML = `<tr><td colspan="7" class="text-center text-danger">Error retrieving data.</td></tr>`;
}
function refreshBGPTable() {
["ipv4Search", "ipv6Search"].forEach(id => (document.getElementById(id).value = ""));
toggleRefresh(true);
loadBgpTables().finally(() => toggleRefresh(false));
}
function toggleRefresh(loading) {
document.getElementById("refreshIcon").classList.toggle("d-none", loading);
document.getElementById("refreshSpinner").classList.toggle("d-none", !loading);
document.getElementById("refreshIcon2").classList.toggle("d-none", loading);
document.getElementById("refreshSpinner2").classList.toggle("d-none", !loading);
}
document.addEventListener("DOMContentLoaded", loadBgpTables);