e9d4ef60ff
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@729 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
389 lines
11 KiB
Perl
Executable File
389 lines
11 KiB
Perl
Executable File
#!/usr/bin/env perl
|
|
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
|
BEGIN
|
|
{
|
|
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
|
|
}
|
|
use lib "$::XCATROOT/lib/perl";
|
|
use Sys::Syslog;
|
|
use xCAT::Table;
|
|
use xCAT_plugin::ipmi;
|
|
use xCAT_monitoring::monitorctrl;
|
|
|
|
#-------------------------------------------------------------------------------
|
|
=head1 xcat_traphandler
|
|
=head2 Description
|
|
Script for SNMP trap handling.
|
|
|
|
=cut
|
|
#-------------------------------------------------------------------------------
|
|
# admin needs to create a mail aliase called alerts
|
|
# put "alerts: emailadd,emailaddr.." to /etc/aliases file
|
|
# then run newaliases command
|
|
my $MAILTO="alerts";
|
|
|
|
my $message, $briefmsg;
|
|
my $pair;
|
|
my $node1;
|
|
my $info;
|
|
my $severity_type;
|
|
my $severity;
|
|
|
|
#get settings
|
|
$EMAIL=0, $LOG=0, $RUNCMD=0, $INGNORE=0;
|
|
%hashI=(),%hashE=(),%hashL=(),%hashR=();
|
|
my %settings=xCAT_monitoring::monitorctrl->getPluginSettings("snmpmon");
|
|
my $i=$settings{'ignore'};
|
|
if ($i) { %hashI =parseSettings($i); }
|
|
my $e=$settings{'email'};
|
|
if ($e) { %hashE=parseSettings($e); }
|
|
my $l=$settings{'log'};
|
|
if ($l) { %hashL=parseSettings($l); }
|
|
my $r=$settings{'runcmd'};
|
|
if ($r) { %hashR=parseSettings($r); }
|
|
|
|
# read host name
|
|
my $host=<STDIN>;
|
|
chomp($host);
|
|
|
|
# read the host ip
|
|
my $ip=<STDIN>;
|
|
chomp($ip);
|
|
|
|
# read uptime
|
|
my $uptimeline=<STDIN>;
|
|
chomp($uptimeline);
|
|
my @a=split(/ /, $uptimeline);
|
|
my $oid=shift @a;
|
|
my $value=join(' ', @a);
|
|
$message .= " $oid=$value\n";
|
|
|
|
# read trapid
|
|
my $trapidline=<STDIN>;
|
|
chomp($trapidline);
|
|
@a=split(/ /, $trapidline);
|
|
$oid=shift @a;
|
|
$value=join(' ', @a);
|
|
$message .= " $oid=$value\n";
|
|
checkWithOid($oid, $value);
|
|
#print "I=$IGNORE,E=$EMAIL, L=$LOG, R=$RUNCMD\n";
|
|
if ($IGNORE) { print "out\n"; exit 0;}
|
|
|
|
#for ipmi traps, the values is: SNMPv2-SMI::enterprises.3183.1.1.0.x, x is the ipmi trap id.
|
|
$value =~ s/(SNMPv2-SMI::enterprises\.3183\.1\.1\.0\.)//g;
|
|
my $trapid=$value;
|
|
|
|
#print "trapid=$trapid\n";
|
|
|
|
|
|
|
|
my $holder;
|
|
my $begin=1;
|
|
my $pair;
|
|
while ($temp=<STDIN>) {
|
|
chomp($temp);
|
|
my $temp1=$temp; #save the one with quotes
|
|
$temp1 =~ s/\"//g;
|
|
my $c1=length($temp);
|
|
my $c2=length($temp1);
|
|
|
|
|
|
if (($c1-$c2)%2 == 0) {
|
|
if ($begin==1) { # single line
|
|
$pair=$temp;
|
|
}
|
|
else { # middle multi-line
|
|
$pair .= " $temp";
|
|
next;
|
|
}
|
|
} else { # multi line
|
|
if ($begin==1) {
|
|
$pair=$temp; #start of multi-line
|
|
$begin=0;
|
|
next;
|
|
} else {
|
|
$pair .= " $temp"; #end of multi-line
|
|
$begin=1;
|
|
}
|
|
}
|
|
|
|
@a=split(/ /, $pair);
|
|
$oid=shift @a;
|
|
$value=join(' ', @a);
|
|
|
|
|
|
#for BladeCenter MM traps and RSA II traps, creat a brief message
|
|
if ($oid =~ /BLADESPPALT-MIB::spTrapAppId|RSASPPALT-MIB::ibmSpTrapAppId/) {
|
|
$briefmsg .= " App ID: $value\n";
|
|
}
|
|
elsif ($oid =~ /BLADESPPALT-MIB::spTrapAppType|RSASPPALT-MIB::ibmSpTrapAppType/) {
|
|
$briefmsg .= " App Alert Type: $value\n";
|
|
}
|
|
elsif ($oid =~ /BLADESPPALT-MIB::spTrapMsgText|RSASPPALT-MIB::ibmSpTrapMsgText/) {
|
|
$briefmsg .= " Message: $value\n";
|
|
}
|
|
elsif ($oid =~ /BLADESPPALT-MIB::spTrapBladeName/) {
|
|
my $temp="$value";
|
|
$temp =~ /^\"(.*)\"/;
|
|
if ($1) {
|
|
$briefmsg .= " Blade Name: $value\n";
|
|
$node1=$1;
|
|
}
|
|
}
|
|
elsif (($oid =~ /BLADESPPALT-MIB::spTrapSourceId/)) {
|
|
$briefmsg .= " Error Source=$value\n";
|
|
}
|
|
elsif ($oid =~ /BLADESPPALT-MIB::spTrapPriority|RSASPPALT-MIB::ibmSpTrapPriority/) {
|
|
# Critical Alert(0), Major(1), Non-Critical Alert(2), System Alert(4),
|
|
# Recovery Alert(8), Informational Only Alert(255)
|
|
if ($value==0) {
|
|
$severity="Critical Alert";
|
|
$severity_type="Critical";
|
|
} elsif ($value==1) {
|
|
$severity="Major Alert";
|
|
$severity_type="Critical";
|
|
} elsif ($value==2) {
|
|
$severity="Non-Critical Alert";
|
|
$severity_type="Warning";
|
|
} elsif ($value==4) {
|
|
$severity="System Alert";
|
|
$severity_type="Warning";
|
|
} elsif ($value==8) {
|
|
$severity="Recovery Alert";
|
|
$severity_type="Informational";
|
|
} elsif ($value==255) {
|
|
$severity="Informational Alert";
|
|
$severity_type="Informational";
|
|
}
|
|
}
|
|
elsif ($oid =~ /enterprises\.3183\.1\.1\.1/) { #IPMI PRTs (traps)
|
|
$node1=$host;
|
|
$node1 =~ s/(-(eth|man)\d+)?(\..*)?$//;
|
|
|
|
$value =~ s/\"//g;
|
|
my @varray=split(/ /, $value);
|
|
#print "\n\n\ntrapid=$trapid\nhost=$host\npet=$value\n";
|
|
my $error = xCAT_plugin::ipmi->decodealert($trapid, $host, \@varray);
|
|
$briefmsg .= $error;
|
|
#print "error=$error\n";
|
|
|
|
#severity value from decodealert are:
|
|
#LOG,INFORMATION,OK,CRITICAL,NON-RECOVERABLE,MONITOR and UNKNOWN-SEVERITY
|
|
$severity_type="Warning";
|
|
if ($error) {
|
|
@tempArray=split(/\:/, $error);
|
|
$severity=$tempArray[0];
|
|
if ($severity eq "LOG") {
|
|
$severity_type="Informational";
|
|
}
|
|
elsif($severity eq "INFORMATION") {
|
|
$severity_type="Informational";
|
|
}
|
|
elsif($severity eq "OK") {
|
|
$severity_type="Informational";
|
|
}
|
|
elsif($severity eq "CRITICAL") {
|
|
$severity_type="Critical";
|
|
}
|
|
elsif($severity eq "NON-RECOVERABLE") {
|
|
$severity_type="Critical";
|
|
}
|
|
}
|
|
}
|
|
|
|
$message .= " $oid=$value\n";
|
|
|
|
#check agains the settings
|
|
$value =~ s/\"//g;
|
|
checkWithOid($oid, $value);
|
|
#print "I=$IGNORE,E=$EMAIL, L=$LOG, R=$RUNCMD\n";
|
|
if ($IGNORE) { print "out\n"; exit 0;}
|
|
}
|
|
|
|
if (!$severity_type) { $severity_type="Warning"; }
|
|
if ((!$IGNORE) && exists($hashI{$severity_type})) { print "out\n"; exit 0; }
|
|
if ((!$EMAIL) && exists($hashE{$severity_type})) { $EMAIL=1; }
|
|
if ((!$LOG) && exists($hashL{$severity_type})) { $LOG=1; }
|
|
if ((!$RUNCMD) && exists($hashR{severity_type})) { $RUNCMD=1; }
|
|
#print "I=$IGNORE,E=$EMAIL, L=$LOG, R=$RUNCMD\n";
|
|
|
|
#email 'alerts' aliase
|
|
if ($EMAIL || ((keys(%hashE)==0) && ($severity_type =~/Critical|Warning/))) {
|
|
print "email\n";
|
|
#($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
|
|
#$datetime=sprintf "%2d-%02d-%04d %02d:%02d:%02d", $mon+1,$mday,$year+1900,$hour,$min,$sec;
|
|
#my $head="SNMP $severity received from $host($ip) on $datetime\n$briefmsg\n";
|
|
my $head="SNMP $severity received from $host($ip)\n$briefmsg\n";
|
|
my $middle="Trap details:\n$message\n";
|
|
my $end;
|
|
if ($node1) {$info= getMoreInfo($node1);}
|
|
if ($info) {
|
|
$end ="Additonal Info from xCAT:\n$info\n";
|
|
}
|
|
|
|
#email the full message to the alerts aliase
|
|
my $cmd="echo \'$head$middle$end\' \| mail -s \"$severity_type: Cluster SNMP Alert\!\" $MAILTO";
|
|
`$cmd`;
|
|
}
|
|
|
|
#log to syslog if needed. default is log all
|
|
if ($LOG || (keys(%hashL)==0)) {
|
|
print "log\n";
|
|
my $head="SNMP $severity received from $host($ip).";
|
|
my $body;
|
|
if ($briefmsg) { $body=$briefmsg;}
|
|
else { $body=$message; }
|
|
|
|
openlog("xCATMon Event","","local4");
|
|
if ($severity_type eq "Informational") {
|
|
syslog("local4|info", "$head\n$body\n");
|
|
} else {
|
|
syslog("local4|err", "$head\n$body\n");
|
|
}
|
|
closelog();
|
|
}
|
|
|
|
#run user defined commands if needed.
|
|
if ($RUNCMD) {
|
|
print "runcmd\n";
|
|
my $scripts=$settings{'cmds'};
|
|
while ($scripts =~ s/^([^,]+)(,)*//) {
|
|
my $cmd="echo \'host=$host\nip=$ip\n$message\n\' \| $1";
|
|
`$cmd`;
|
|
}
|
|
}
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 getMoreInfo
|
|
This function returns the node module/type, serial number, position etc.
|
|
Arguments:
|
|
node-- name of the node.
|
|
Returns:
|
|
A string with node info ready to display.
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub getMoreInfo {
|
|
my $node=shift;
|
|
my $pos,$vpd;
|
|
|
|
#get module name and serial number from the xCAT DB.
|
|
my $table=xCAT::Table->new("vpd", -create =>1);
|
|
if ($table) {
|
|
(my $ref) = $table->getAttribs({'node' => $node}, ('serial', 'mtm'));
|
|
if ($ref) {
|
|
if($ref->{mtm}) { $vpd .= " Type/Mudule: ". $ref->{mtm} ."\n"; }
|
|
if($ref->{serial}) { $vpd .= " Serial Number: ". $ref->{serial} ."\n";}
|
|
}
|
|
$table->close();
|
|
}
|
|
|
|
# get the info from rinv command if nothing in the vpd table
|
|
if (!$vpd) {
|
|
my $result=`$XCATROOT/bin/rinv $node all 2>&1 | egrep -i '(model|serial)' | grep -v Univ`;
|
|
if ($? == 0) {#success
|
|
chomp($result);
|
|
my @b=split(/\n/, $result);
|
|
foreach (@b) {
|
|
s/^(.*)\:(.*)\:(.*)$/$2: $3/;
|
|
$vpd .= " $_\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#get the position
|
|
my $table1=xCAT::Table->new("nodepos", -create =>1);
|
|
if ($table1) {
|
|
(my $ref1) = $table1->getAttribs({'node' => $node}, ('rack', 'u', 'chassis', 'slot', 'room'));
|
|
if ($ref1) {
|
|
if($ref1->{room}) { $pos .= " Room: ". $ref1->{room} ."\n"; }
|
|
if($ref1->{rack}) { $pos .= " Rack: ". $ref1->{rack} ."\n"; }
|
|
if($ref1->{u}) { $pos .= " Vertial position: ". $ref1->{u} ."\n"; }
|
|
if($ref1->{chassis}) { $pos .= " Chassis: ". $ref1->{chassis} ."\n"; }
|
|
if($ref1->{slot}) { $pos .= " Slot: ". $ref1->{slot} ."\n"; }
|
|
}
|
|
$table1->close();
|
|
}
|
|
|
|
if (($pos) || ($vpd)) {
|
|
return " Node: $node\n$vpd$pos";
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 parseSettings
|
|
This function takes a setting string which looks like "key1=value1,key2=value2..."
|
|
and returns a hash (key1=>value1, key2=>value2...).
|
|
Arguments:
|
|
setting the setting string.
|
|
Returns:
|
|
A hash.
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub parseSettings {
|
|
my $settings=shift;
|
|
my %ret=();
|
|
while (($settings =~ s/^(Informational|Warning|Critical|All|None)()(,)*//) ||
|
|
($settings =~ s/^([^\=]+)=(\"[^\"]+\")(,)*//) ||
|
|
($settings =~ s/^([^\=]+)=([^\"\,]+)(,)*//)) {
|
|
# print "$1=$2\n";
|
|
$ret{$1}=$2;
|
|
}
|
|
|
|
return %ret;
|
|
}
|
|
|
|
#--------------------------------------------------------------------------------
|
|
=head3 checkWithOid
|
|
This function checks the input strings with the setting to see what
|
|
actions need to be done for this event.
|
|
Arguments:
|
|
oid the oid string
|
|
value the value string
|
|
Returns:
|
|
none. The variables $EMAIL, $LOG, $IGNORE and $RUNCMD may be changed.
|
|
=cut
|
|
#--------------------------------------------------------------------------------
|
|
sub checkWithOid {
|
|
$o=shift;
|
|
$v=shift;
|
|
|
|
sub checking {
|
|
my $hashX=shift;
|
|
|
|
if (exists($hashX->{'All'})) { return 1; }
|
|
if (exists($hashX->{'None'})) { return 0; }
|
|
if (exists($hashX->{$o}) && ($hashX->{$oid} eq $v)) {return 1; }
|
|
return 0;
|
|
}
|
|
|
|
if ((!$IGNORE) && (keys(%hashI)>0)) {
|
|
$IGNORE=checking(\%hashI);
|
|
if ($IGNORE) { return;}
|
|
}
|
|
|
|
if ((!$EMAIL) && (keys(%hashE)>0)) {
|
|
$EMAIL=checking(\%hashE);
|
|
}
|
|
|
|
if ((!$LOG) && (keys(%hashL)>0)) {
|
|
$LOG=checking(\%hashL);
|
|
}
|
|
|
|
if ((!$RUNCMD) && (keys(%hashR)>0)) {
|
|
$RUNCMD=checking(\%hashR);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|