Вообще не хватает подобного топика, все полезные скрипты или пользовательские функции разбросаны по форуму или чату в телеграмм, предлагаю публиковать и собирать всё в одной теме.
В Script Library можно добавить скрипты (либо они будут уже созданы при свежей уставноке):
Hook::StatusPoll
Hook::ConfigurationPoll
Hook::TopologyPoll
Hook::AcceptNewNode
Hook::CreateInterface
Hook::CreateSubnet
Hook::UpdateInterface
Hook::EventProcessor
Hook::InstancePoll
Hook::PostObjectCreate
Hook::DiscoveryPoll
Hook::AlarmStateChange
Hook::UnboundTunnelOpened
Hook::BoundTunnelOpened
Hook Scripts:
Hook::CreateInterface:
if ($1->name imatch "802.1Q Encapsulation Tag *|Management port|Aux*|Console*|InLoopBack0|MEeth0*|null0*|meth0*|enet0*|oob|M-Ethernet")
{
return false
}
if (($node->sysDescription ~= "^Linux ") &&
(($1->ifType == "1" ||
$1->ifType == "22" ||
$1->ifType == "24" ||
$1->ifType == "124"))
)
{
return false;
}
return true;
###########======---
if ($node->driver == "CISCO-SB"){
snmp = CreateSNMPTransport($node);
state = SNMPGetValue(snmp, ".1.3.6.1.2.1.2.2.1.8." . $1->ifIndex);
if (state == 6)
return false;
}
return true;
###########======---
if ($1->name ~= "(?i).*Teredo.*|.*isatap.*|.*Bluetooth.*|sit0")
return false;
snmp = CreateSNMPTransport($node);
state = SNMPGetValue(snmp, ".1.3.6.1.2.1.2.2.1.8." . $1->index);
if (state == 5)
return false;
return true;
###########======---
Если логическое утверждение истинно, вы получаете первую часть, а если оно ложно, вы получаете вторую.
sysDescription = ($node->sysDescription == "") ? $node->readAgentParameter("System.Uname") : $node->sysDescription;
if (sysDescription ~= "^Linux [A-z]+[0-9]+.")
Hook::AcceptNewNode:
Can be used as additional filter for network discovery to avoid unnecessary communications.
Этот хук срабатывает только на добавление новых нод - если нода уже добавлена то с ней ничего не случится.
Более того, он не срабатывает при ручном добавлении - это только дополнительный фильтр для discovery.
// macs = %(01:E8:EE:94:91:C8, 01:E8:EE:91:DD:21, 01:E8:EE:92:71:FD, 01:E8:EE:93:72:F9, 01:E8:EE:92:66:DD, 01:E8:EE:94:91:7E, 01:E8:EE:9C:32:D4);
node1 = "01:E8:EE:94:91:C8";
node2 = "01:E8:EE:91:DD:21";
node3 = "01:E8:EE:92:71:FD";
if (AddrInSubnet($ipAddr, "10.10.0.0", "255.254.0.0")
|| AddrInSubnet($ipAddr, "10.20.0.0", "255.255.254.0"))
return true;
return false;
return not ($macAddr in %(node1, node2, node3));
P.S. здесь дополнительно ещё проверка по MAC.
Конвертивание эпохи Unix в человекопонятную дату(human readable date)
return strftime("%d.%m.%Y %H:%M:%S", $1);
###########======---
Скрипт для HP ILO на примере instance discovery .1.3.6.1.4.1.232.3.2.3.1.1.4.0.{instance} и Log Drive status {instance} {instance-name}
для подмены значений в более информативный вид
switch ($1)
{
case 2:
return "ok";
break;
case 3:
return "failed";
break;
case 4:
return "unconfigured";
break;
case 5:
return "recovering";
break;
case 6:
return "readyForRebuild";
break;
case 7:
return "rebuilding";
break;
case 8:
return "wrongDevice";
break;
case 9:
return "badConnect";
break;
case 10:
return "overheating";
break;
case 11:
return "shutdown";
break;
case 12:
return "expanding";
break;
case 13:
return "notAvailable";
break;
case 14:
return "queuedForExpansion";
break;
case 15:
return "multipathAccessDegraded";
break;
case 16:
return "earsing";
break;
default:
return "other";
break;
}
Instance discovery script's:
Для Net.Interface.BytesIn({instance}), благодаря которому на выходе в графиках получаем DCI по нужным нам интерфейсам, в данном случае eth|bond для Linux сервера.
name=substr($1,rindex($1, " ")+1);
if (name ~= "eth|bond")
{
return %(true, name);
}
return false;
Для снятия ошибок с Linux интерфейсов.
ExternalParameterShellExec = Interface.errors(*):ethtool -S $1 | grep $2 | awk '{print $$2}'
В библиотеке скриптов создаём скрипт ethtool_errors_instance:
ifaces = AgentReadList($node, "Net.InterfaceNames");
instances = %();
c = 0;
for(i : ifaces)
{
if (i ~= "eth|em|p55p|p1p|eno|ens|enp") {
instances[c++] = i . ",rx_crc_errors";
instances[c++] = i . ",rx_missed_errors";
instances[c++] = i . ",rx_no_buffer_count";
}
}
return instances;
Создаём DCI Interface.errors({instance}), в Instance discovery method ставим Script и указываем имя созданного скрипта, ethtool_errors_instance.
Общее:
Скрипт с рекурсивной функцией и поиском по нужным\необходимым параметрам, в данном случае по snmp sysDescription коммутатора
sub GetTree (nodeID)
{
Tree = FindObject(nodeID);
children = GetObjectChildren(Tree);
foreach (n : children)
{
//println ("Name: " . n->name);
if (n->name != null && classof(n) == "Node")
{
if (n->sysDescription ~= "^D-Link DES-3028" && n->comments == "")
{
println ("Name: " . n->name . ", sysDescription: " . n->sysDescription . ", IP: " . n->ipAddr);
}
}
GetTree(n->id);
}
}
GetTree(2);
Примерно аналогичный скрипт, но выведет custom атрибуты по интерфейсам, все кроме .dlink.slotSize и uptime
sub GetTree (nodeID)
{
Tree = FindObject(nodeID);
children = GetObjectChildren(Tree);
foreach (i : children)
{
{
attributes = i->customAttributes;
foreach(a : attributes->keys)
{
{
if ((a != ".dlink.slotSize") && (a != "uptime"))
{
println (a . " = " . attributes[a] . "," . " Port: " . i->port . "," . " Interface name: " . i->name . "," . " Node name: " . Tree->name);
}
}
}
}
GetTree(i->id);
}
}
GetTree(2);
EPP:
Скрипт для и фильтрации по интерфейсам, например для SYS_IF_UP.
ignoreInterfaceRegEx = "^ppp([0-9]+)|802.1Q";
if ($2 ~= ignoreInterfaceRegEx)
return false;
return true;
Модуль debug (в нужном скрипте "use debug;", потом можно использовать "dbgPrintTable(table)"):
sub dbgPaddingLeft(s, len) {
if (s == NULL) {
s = "";
}
padding = "";
for (i = 0; i < len - length(s); i++) {
padding .= " ";
}
return padding . s;
}
sub dbgPaddingRight(s, len) {
if (s == NULL) {
s = "";
}
padding = "";
for (i = 0; i < len - length(s); i++) {
padding .= " ";
}
return s . padding;
}
sub dbgPrintTable(t) {
if (t == NULL) {
return;
}
array columnLen;
for (i = 0; i < t->columnCount; i++) {
columnLen[i] = length(t->columns[i]->displayName);
}
for (i = 0; i < t->rowCount; i++) {
for (j = 0; j < t->columnCount; j++) {
val = t->get(i, j);
if (val == NULL) {
val = "";
}
columnLen[j] = max(columnLen[j], length(val));
}
}
for (i = 0; i < t->columnCount; i++) {
print(dbgPaddingRight(t->columns[i]->displayName, columnLen[i]) . " | ");
}
println;
for (i = 0; i < t->columnCount; i++) {
for (j = 0; j < columnLen[i]; j++) {
print("-");
}
print("-+-");
}
println;
for (i = 0; i < t->rowCount; i++) {
for (j = 0; j < t->columnCount; j++) {
print(dbgPaddingRight(t->get(i, j), columnLen[j]) . " | ");
}
println;
}
println;
}
Получение ячейки таблицы (по большей части для того, что бы использовать ячейку таблицы как DCI):
// Warning: this script works only on the same node
//
// $1 - Description
// $2 - column name
table = GetDCIValueByDescription($node, $1);
if (table != NULL) {
col = table->getColumnIndex($2);
if (col >= 0) {
return table->get(0, col);
}
}
return 0;
Дамп потоков для Linux.
#!/bin/sh
exec='netxmsd'
if [ "x$1" != "x" ]; then
exec="$1"
fi
pid=`ps -ax | grep netxmsd | grep -v grep | grep -v capture_netxmsd_threads | awk '{ print $1; }'`
ts=`date +%Y%m%d-%H%M%S`
cmdfile="/tmp/capture_netxmsd_threads.gdb"
echo "set height 0" > $cmdfile
echo "set logging file /tmp/netxmsd-threads.$pid.$ts" >> $cmdfile
echo "set logging on" >> $cmdfile
echo "attach $pid" >> $cmdfile
echo "thread apply all bt" >> $cmdfile
echo "detach" >> $cmdfile
echo "quit" >> $cmdfile
gdb --batch-silent --command=$cmdfile "$exec"
rm $cmdfile
Cкрипт для перезагрузки свичей Edge-Core по SNMP.
print "Trying reboot switch -> ".$node->name;
println " snmpObjectId->".$node->snmpOID." ".$node->sysDescription;
switch($node->snmpOID)
{
case ".1.3.6.1.4.1.259.6.10.94":
print "ES3528M";
oid = "1.3.6.1.4.1.259.6.10.94.1.7.3.0";
break;
case ".1.3.6.1.4.1.259.10.1.27.101":
print "ECS3510-28T";
oid = "1.3.6.1.4.1.259.10.1.27.1.7.3.0";
break;
/* case ".1.3.6.1.4.1.259.8.1.5":
println "ES3510";
oid = "";
break; */
case ".1.3.6.1.4.1.259.10.1.27.102":
print "ECS3510-52T";
oid = "1.3.6.1.4.1.259.10.1.27.1.7.3.0";
break;
case ".1.3.6.1.4.1.259.8.1.11.101":
print "ES3510MA";
oid = "1.3.6.1.4.1.259.8.1.11.1.7.3.0";
break;
default:
println "Unknown switch model!";
return 1;
}println " > ResetOID=".oid;
snmpTransport = CreateSNMPTransport($node);
if ( snmpTransport == null ) return "Unable to connect";
returnValue = SNMPSet(snmpTransport,oid,"3","INTEGER");
if ( returnValue == null ) return "No response. Something went wrong.";
if ( returnValue == 0 ) return "Unable to initiate reload. No SNMP Write Access?";
if ( returnValue == 1 ) return "Reload triggered.";
Скрипт необходимо разместить в "Script Library" например с названием reboot_switch.
Затем в "Object Tools" создать новый инструмент, например "Reboot switch Edge-Core"
В поле "Script" указать "reboot_switch".
Установить "птичку" на "Command generates output".
Не помешает птичка в поле "Confirmation" с соответствующим вопросом (необязательно, но желательно).