Делимся скриптами

Started by hsvt, July 08, 2016, 04:53:56 PM

Previous topic - Next topic

hsvt

Вообще не хватает подобного топика, все полезные скрипты или пользовательские функции разбросаны по форуму или чату в телеграмм, предлагаю публиковать и собирать всё в одной теме.

В 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;

Alex Kirhenshtein

#1
Модуль 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;

hsvt

Дамп потоков для 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

askat

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" с соответствующим вопросом (необязательно, но желательно).