You've already forked greasemonkey
67 lines
2.0 KiB
JavaScript
67 lines
2.0 KiB
JavaScript
// ==UserScript==
|
|
// @name NetBox DNS Name → SSH links
|
|
// @version 1.0
|
|
// @description Trasforma la colonna "DNS Name" in link ssh:// nella lista IP addresses di NetBox
|
|
// @match *://netbox.example.com/*
|
|
// @grant none
|
|
// @run-at document-idle
|
|
// ==/UserScript==
|
|
|
|
(function () {
|
|
'use strict';
|
|
|
|
const TAG = '[ssh-links]';
|
|
const HEADER = 'dns name'; // confronto case-insensitive
|
|
const DEBUG = false;
|
|
|
|
const log = (...a) => DEBUG && console.log(TAG, ...a);
|
|
|
|
if (!location.pathname.includes('/ipam/ip-addresses')) return;
|
|
|
|
function findColumnIndex(table) {
|
|
const ths = table.querySelectorAll('thead th');
|
|
for (let i = 0; i < ths.length; i++) {
|
|
if (ths[i].textContent.trim().toLowerCase() === HEADER) return i;
|
|
}
|
|
console.warn(TAG, 'colonna DNS name non trovata');
|
|
return -1;
|
|
}
|
|
|
|
function processTable(table) {
|
|
const idx = findColumnIndex(table);
|
|
if (idx === -1) return;
|
|
|
|
let done = 0;
|
|
table.querySelectorAll('tbody > tr').forEach(tr => {
|
|
const cell = tr.children[idx];
|
|
if (!cell) return;
|
|
if (cell.querySelector('a[href^="ssh://"]')) return;
|
|
|
|
const name = cell.textContent.trim();
|
|
if (!name || name === '—' || name === '-') return;
|
|
|
|
const a = document.createElement('a');
|
|
a.href = 'ssh://' + name;
|
|
a.textContent = name;
|
|
cell.replaceChildren(a);
|
|
done++;
|
|
});
|
|
log('link creati:', done);
|
|
}
|
|
|
|
function run() {
|
|
document.querySelectorAll('table.table.table-hover.object-list').forEach(processTable);
|
|
}
|
|
|
|
run();
|
|
|
|
// NetBox usa htmx: la tabella viene rimpiazzata su sort/paginazione/filtri
|
|
let pending = false;
|
|
const mo = new MutationObserver(() => {
|
|
if (pending) return;
|
|
pending = true;
|
|
setTimeout(() => { pending = false; run(); }, 100);
|
|
});
|
|
mo.observe(document.body, { childList: true, subtree: true });
|
|
})();
|