mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 11:22:27 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1387 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			1387 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| #!/usr/bin/env perl
 | |
| # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
 | |
| package xCAT_monitoring::snmpmon;
 | |
| 
 | |
| BEGIN
 | |
| {
 | |
|     $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
 | |
| }
 | |
| use lib "$::XCATROOT/lib/perl";
 | |
| use strict;
 | |
| use IO::File;
 | |
| use xCAT::Utils;
 | |
| use xCAT::MsgUtils;
 | |
| use xCAT::TableUtils;
 | |
| use xCAT::NodeRange;
 | |
| use xCAT_monitoring::monitorctrl;
 | |
| use Sys::Hostname;
 | |
| use File::Path qw/mkpath/;
 | |
| 
 | |
| #print "xCAT_monitoring::snmpmon loaded\n";
 | |
| 1;
 | |
| 
 | |
| 
 | |
| my $confdir;
 | |
| if (xCAT::Utils->isAIX()) {
 | |
|     $::snmpconfdir = "/opt/freeware/etc";
 | |
| } else {
 | |
|     if (-f "/etc/snmp/snmpd.conf") {
 | |
|         $::snmpconfdir = "/etc/snmp";
 | |
|     } else {
 | |
|         $::snmpconfdir = "/usr/share/snmp";
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head1  xCAT_monitoring:snmpmon
 | |
| =head2    Package Description
 | |
|   xCAT monitoring plugin package to handle SNMP monitoring.
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3    start
 | |
|       This function gets called by the monitorctrl module when monstart command
 | |
|      gets called and when xcatd starts.
 | |
|     Arguments:
 | |
|        p_nodes -- a pointer to an arrays of nodes to be monitored. null means all.
 | |
|        scope -- the action scope, it indicates the node type the action will take place.
 | |
|                 0 means localhost only.
 | |
|                 2 means both localhost and nodes,
 | |
|        callback -- the callback pointer for error and status displaying. It can be null.
 | |
|     Returns:
 | |
|       (return code, message)
 | |
|       if the callback is set, use callback to display the status and error.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub start {
 | |
|     print "snmpmon:start called\n";
 | |
|     my $noderef = shift;
 | |
|     if ($noderef =~ /xCAT_monitoring::snmpmon/) {
 | |
|         $noderef = shift;
 | |
|     }
 | |
|     my $scope    = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     my $localhostname = hostname();
 | |
| 
 | |
|     # get the PID of the currently running snmptrapd if it is running.
 | |
|     # then stop it and restart it again so that it reads our new
 | |
|     # snmptrapd.conf configuration file. Then the process
 | |
|     my $pid;
 | |
|     chomp($pid = `/bin/ps -ef | /bin/grep snmptrapd | /bin/grep -v grep | /bin/awk '{print \$2}'`);
 | |
|     if ($pid) {
 | |
|         `/bin/kill -9 $pid`;
 | |
|     }
 | |
| 
 | |
|     # start it up again!
 | |
|     if (xCAT::Utils->isAIX()) {
 | |
|         system("/opt/freeware/sbin/snmptrapd -m ALL");
 | |
|     } else {
 | |
|         system("/usr/sbin/snmptrapd -m ALL");
 | |
|     }
 | |
| 
 | |
|     # get the PID of the currently running snmpd if it is running.
 | |
|     # if it's running then we just leave.  Otherwise, if we don't get A PID, then we
 | |
|     # assume that it isn't running, and start it up again!
 | |
|     chomp($pid = `/bin/ps -ef | /bin/grep snmpd | /bin/grep -v grep | /bin/awk '{print \$2}'`);
 | |
|     unless ($pid) {
 | |
| 
 | |
|         # start it up!
 | |
|         system("/usr/sbin/snmpd");
 | |
|     }
 | |
| 
 | |
|     if ($scope) {
 | |
| 
 | |
|         #enable alerts on the nodes
 | |
|         if ($callback) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "$localhostname: enabling SNMP alert...";
 | |
|             $callback->($rsp);
 | |
|         }
 | |
| 
 | |
|         #enable bmcs if any
 | |
|         configBMC(1, $noderef, $callback);
 | |
| 
 | |
|         #enable MMAs if any
 | |
|         configMPA(1, $noderef, $callback);
 | |
| 
 | |
|         #enable MMAs if any
 | |
|         configSwitch(1, $noderef, $callback);
 | |
|     }
 | |
| 
 | |
|     if ($callback) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "$localhostname: done.";
 | |
|         $callback->($rsp);
 | |
|     }
 | |
| 
 | |
|     return (0, "started")
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3    stop
 | |
|       This function gets called by the monitorctrl module when monstop command gets called.
 | |
|     Arguments:
 | |
|        p_nodes -- a pointer to an arrays of nodes to be stopped for monitoring. null means all.
 | |
|        scope -- the action scope, it indicates the node type the action will take place.
 | |
|                 0 means localhost only.
 | |
|                 2 means both monservers and nodes,
 | |
|        callback -- the callback pointer for error and status displaying. It can be null.
 | |
|     Returns:
 | |
|       (return code, message)
 | |
|       if the callback is set, use callback to display the status and error.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub stop {
 | |
|     print "snmpmon:stop called\n";
 | |
|     my $noderef = shift;
 | |
|     if ($noderef =~ /xCAT_monitoring::snmpmon/) {
 | |
|         $noderef = shift;
 | |
|     }
 | |
|     my $scope    = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     my $localhostname = hostname();
 | |
| 
 | |
|     if ($scope) {
 | |
|         if ($callback) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "$localhostname: disabling SNMP alert...";
 | |
|             $callback->($rsp);
 | |
|         }
 | |
| 
 | |
|         #disable MMAs if any
 | |
|         configMPA(0, $noderef, $callback);
 | |
| 
 | |
|         #disable BMC so that it stop senging alerts (PETs) to this node
 | |
|         configBMC(0, $noderef, $callback);
 | |
| 
 | |
|         #disable switches so that it stop senging alerts (PETs) to this node
 | |
|         configSwitch(0, $noderef, $callback);
 | |
|     }
 | |
| 
 | |
| 
 | |
|     # now check to see if the daemon is running.  If it is then we need to resart or stop?
 | |
|     # it with the new snmptrapd.conf file that will not forward events to RMC.
 | |
|     chomp(my $pid = `/bin/ps -ef | /bin/grep snmptrapd | /bin/grep -v grep | /bin/awk '{print \$2}'`);
 | |
|     if ($pid) {
 | |
|         `/bin/kill -9 $pid`;
 | |
| 
 | |
|         # start it up again!
 | |
|         #system("/usr/sbin/snmptrapd");
 | |
|     }
 | |
| 
 | |
|     if ($callback) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "$localhostname: done.";
 | |
|         $callback->($rsp);
 | |
|     }
 | |
| 
 | |
|     return (0, "stopped");
 | |
| }
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3    supportNodeStatusMon
 | |
|     This function is called by the monitorctrl module to check
 | |
|     if SNMP can help monitoring and returning the node status.
 | |
|     SNMP does not support this function.
 | |
| 
 | |
|     Arguments:
 | |
|         none
 | |
|     Returns:
 | |
|          0
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub supportNodeStatusMon {
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   startNodeStatusMon
 | |
|     This function is called by the monitorctrl module when monstart gets called and
 | |
|     when xcatd starts. It starts monitoring the node status and feed them back
 | |
|     to xCAT.
 | |
|     Arguments:
 | |
|        p_nodes -- a pointer to an arrays of nodes to be monitored. null means all.
 | |
|        scope -- the action scope, it indicates the node type the action will take place.
 | |
|                 0 means loca lhost only.
 | |
|                 2 means both localhost and nodes,
 | |
|        callback -- the callback pointer for error and status displaying. It can be null.
 | |
|     note: p_nodes and scope are ignored by this plugin.
 | |
|     Returns:
 | |
|       (return code, message)
 | |
|       if the callback is set, use callback to display the status and error.
 | |
|     This function is called by the monitorctrl module to tell
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub startNodeStatusMon {
 | |
|     return (1, "This function is not supported.");
 | |
| }
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3   stopNodeStatusMon
 | |
|     This function is called by the monitorctrl module when monstop command is issued.
 | |
|     It stops feeding the node status info back to xCAT.
 | |
|     Arguments:
 | |
|        p_nodes -- a pointer to an arrays of nodes to stopped for monitoring. null means all.
 | |
|        scope -- the action scope, it indicates the node type the action will take place.
 | |
|                 0 means local host only.
 | |
|                 2 means both local host and nodes,
 | |
|        callback -- the callback pointer for error and status displaying. It can be null.
 | |
|     note: p_nodes and scope are ignored by this plugin.
 | |
|     Returns:
 | |
|       (return code, message)
 | |
|       if the callback is set, use callback to display the status and error.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub stopNodeStatusMon {
 | |
|     return (1, "This function is not supported.");
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3    config
 | |
|       This function configures the cluster for the given nodes.
 | |
|       This function is called when moncfg command is issued or when xcatd starts
 | |
|       on the service node. It will configure the cluster to include the given nodes within
 | |
|       the monitoring doamin.
 | |
|     Arguments:
 | |
|        p_nodes -- a pointer to an arrays of nodes to be added for monitoring. none means all.
 | |
|        scope -- the action scope, it indicates the node type the action will take place.
 | |
|                 0 means localhost only.
 | |
|                 2 means localhost and nodes,
 | |
|        callback -- the callback pointer for error and status displaying. It can be null.
 | |
|     Returns:
 | |
|        (error code, error message)
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub config {
 | |
|     print "snmpmon:config called\n";
 | |
|     my $noderef = shift;
 | |
|     if ($noderef =~ /xCAT_monitoring::snmpmon/) {
 | |
|         $noderef = shift;
 | |
|     }
 | |
|     my $scope    = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     my $localhostname = hostname();
 | |
| 
 | |
|     # check supported snmp package
 | |
|     my $cmd;
 | |
|     my @snmpPkg = `/bin/rpm -qa | grep snmp`;
 | |
|     my $pkginstalled = grep(/net-snmp/, @snmpPkg);
 | |
| 
 | |
|     if (!$pkginstalled) {
 | |
|         if ($callback) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "$localhostname: net-snmp is not installed.";
 | |
|             $callback->($rsp);
 | |
|         }
 | |
|         return (1, "net-snmp is not installed")
 | |
|     } else {
 | |
|         my ($ret, $err) = configSNMP(2, $noderef, $callback);
 | |
|         if ($ret != 0) { return ($ret, $err); }
 | |
|     }
 | |
| 
 | |
|     #configure mail to enabling receiving mails from trap handler
 | |
|     configMail();
 | |
| 
 | |
| 
 | |
|     if ($scope) {
 | |
|         if ($callback) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "$localhostname: setting up SNMP alert destination....";
 | |
|             $callback->($rsp);
 | |
|         }
 | |
| 
 | |
|         #enable bmcs if any
 | |
|         configBMC(2, $noderef, $callback);
 | |
| 
 | |
|         #enable MMAs if any
 | |
|         configMPA(2, $noderef, $callback);
 | |
| 
 | |
|         #enable switches if any
 | |
|         configSwitch(2, $noderef, $callback);
 | |
|     }
 | |
| 
 | |
|     if ($callback) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "$localhostname: done.";
 | |
|         $callback->($rsp);
 | |
|     }
 | |
| 
 | |
|     return (0, "")
 | |
| }
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3    deconfig
 | |
|       This function de-configures the cluster for the given nodes.
 | |
|       This function is called when mondecfg command is issued by the user.
 | |
|       It should remove the given nodes from the product for monitoring.
 | |
|     Arguments:
 | |
|        p_nodes -- a pointer to an arrays of nodes to be removed for monitoring. none means all.
 | |
|        scope -- the action scope, it indicates the node type the action will take place.
 | |
|                 0 means local host only.
 | |
|                 2 means both local host and nodes,
 | |
|        callback -- the callback pointer for error and status displaying. It can be null.
 | |
|     Returns:
 | |
|        (error code, error message)
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub deconfig {
 | |
|     print "snmpmon:deconfig called\n";
 | |
|     my $noderef = shift;
 | |
|     if ($noderef =~ /xCAT_monitoring::snmpmon/) {
 | |
|         $noderef = shift;
 | |
|     }
 | |
|     my $scope         = shift;
 | |
|     my $callback      = shift;
 | |
|     my $localhostname = hostname();
 | |
| 
 | |
|     if (-f "$::snmpconfdir/snmptrapd.conf.orig") {
 | |
| 
 | |
|         # copy back the old one
 | |
| `mv -f $::snmpconfdir/snmptrapd.conf.orig $::snmpconfdir/snmptrapd.conf`;
 | |
|     } else {
 | |
|         if (-f "$::snmpconfdir/snmptrapd.conf") {
 | |
| 
 | |
|             # if the file exists, delete all entries that have xcat_traphandler
 | |
|             my $cmd = "grep -v  xcat_traphandler $::snmpconfdir/snmptrapd.conf ";
 | |
|             $cmd .= "> $::snmpconfdir/snmptrapd.conf.unconfig ";
 | |
|             `$cmd`;
 | |
| 
 | |
|             # move it back to the snmptrapd.conf file.
 | |
| `mv -f $::snmpconfdir/snmptrapd.conf.unconfig $::snmpconfdir/snmptrapd.conf`;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     deconfigSNMP(2, $noderef, $callback);
 | |
| 
 | |
| 
 | |
|     if ($scope) {
 | |
|         if ($callback) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{data}->[0] = "$localhostname: removing SNMP destination....";
 | |
|             $callback->($rsp);
 | |
|         }
 | |
| 
 | |
|         #remove snmp destination for switches
 | |
|         configSwitch(3, $noderef, $callback);
 | |
|     }
 | |
| 
 | |
|     if ($callback) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = "$localhostname: done.";
 | |
|         $callback->($rsp);
 | |
|     }
 | |
| 
 | |
|     return (0, "");
 | |
| }
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3    deconfigSNMP
 | |
|       This function remove xcat_traphanlder from the snmptrapd.conf file,
 | |
|       remove the node configurations from snmptrapd.conf, and
 | |
|       restarts the snmptrapd with the new configuration.
 | |
|     Arguments:
 | |
|       none.
 | |
|     Returns:
 | |
|       (return code, message)
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub deconfigSNMP {
 | |
|    return (0, "");
 | |
| }
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| =head3    configBMC
 | |
|       This function configures BMC to setup the snmp destination, enable/disable
 | |
|     PEF policy table entry number 1.
 | |
|     Arguments:
 | |
|       actioon -- 0 disable alert. 1 enable alert. 2 setup snmp destination
 | |
| 
 | |
|       p_nodes -- a pointer to an arrays of nodes to be monitored. null means all.
 | |
|       callback -- the callback pointer for error and status displaying. It can be null.
 | |
|     Returns:
 | |
|       (return code, message)
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub configBMC {
 | |
|     my $action   = shift;
 | |
|     my $noderef  = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     my $ret_text = "";
 | |
|     my $ret_val  = 0;
 | |
| 
 | |
|     #the identification of this node
 | |
|     my @hostinfo = xCAT::NetworkUtils->determinehostname();
 | |
|     my $isSV     = xCAT::Utils->isServiceNode();
 | |
|     my %iphash   = ();
 | |
|     foreach (@hostinfo) { $iphash{$_} = 1; }
 | |
|     if (!$isSV) { $iphash{'noservicenode'} = 1; }
 | |
| 
 | |
|     my $pPairHash = xCAT_monitoring::monitorctrl->getNodeMonServerPair($noderef, 0);
 | |
|     if (ref($pPairHash) eq 'ARRAY') {
 | |
|         if ($callback) {
 | |
|             my $rsp = {};
 | |
|             if ($ret_val) {
 | |
|                 $rsp->{data}->[0] = $pPairHash->[1];
 | |
|             }
 | |
|             $callback->($rsp);
 | |
|         } else {
 | |
|             xCAT::MsgUtils->message('S', "[mon]: " . $pPairHash->[1]);
 | |
|         }
 | |
|         return (0, "");
 | |
|     }
 | |
| 
 | |
| 
 | |
|     my %masterhash = ();
 | |
|     my @node_a     = ();
 | |
|     my $table      = xCAT::Table->new("ipmi");
 | |
|     if ($table) {
 | |
|         my @tmp1 = $table->getAllNodeAttribs([ 'node', 'bmc' ]);
 | |
|         if (@tmp1 > 0) {
 | |
|             foreach (@tmp1) {
 | |
|                 my $node = $_->{node};
 | |
|                 my $bmc  = $_->{bmc};
 | |
|                 if (!exists($pPairHash->{$node})) { next; }
 | |
| 
 | |
|                 my $pairs     = $pPairHash->{$node};
 | |
|                 my @a_temp    = split(':', $pairs);
 | |
|                 my $monserver = $a_temp[0];
 | |
|                 my $master    = $a_temp[1];
 | |
| 
 | |
|                 if ($monserver) {
 | |
|                     if (!$iphash{$monserver}) { next; } #skip if has sn but not localhost
 | |
|                 } else {
 | |
|                     if ($isSV) { next; } #skip if does not have sn but localhost is a sn
 | |
|                 }
 | |
| 
 | |
|                 push(@node_a, $node);
 | |
| 
 | |
|                 # find the master node and add the node in the hash
 | |
|                 if (exists($masterhash{$master})) {
 | |
|                     my $ref = $masterhash{$master};
 | |
|                     push(@$ref, $node);
 | |
|                 } else { $masterhash{$master} = [$node]; }
 | |
|             }    #foreach
 | |
|         }
 | |
|         $table->close();
 | |
|     }
 | |
| 
 | |
|     if (@node_a == 0) { return ($ret_val, $ret_text); }    #nothing to handle
 | |
|            #print "configBMC: node_a=@node_a\n";
 | |
| 
 | |
|     #now doing the real thing: enable PEF alert policy table
 | |
|     my $noderange = join(',', @node_a);
 | |
|     if ($action == 0) {
 | |
|         print "XCATBYPASS=Y rspconfig $noderange alert=dis\n";
 | |
|         my $result = `XCATBYPASS=Y rspconfig $noderange alert=dis 2>&1`;
 | |
|         if ($?) {
 | |
|             $ret_val = 1;
 | |
|             xCAT::MsgUtils->message('S', "[mon]: Changeing SNMP PEF policy for IPMI nodes $noderange:\n  $result\n");
 | |
|             $ret_text .= "Changeing SNMP PEF policy for IPMI nodes $noderange:\n  $result\n";
 | |
|         }
 | |
|     } elsif ($action == 1) {
 | |
|         print "XCATBYPASS=Y rspconfig $noderange alert=en community=public\n";
 | |
|         my $result = `XCATBYPASS=Y rspconfig $noderange alert=en community=public 2>&1`;
 | |
|         if ($?) {
 | |
|             $ret_val = 1;
 | |
|             xCAT::MsgUtils->message('S', "[mon]: Changeing SNMP PEF policy for IPMI nodes $noderange:\n  $result\n");
 | |
|             $ret_text .= "Changeing SNMP PEF policy for IPMI nodes $noderange:\n  $result\n";
 | |
|         }
 | |
|     } else {
 | |
| 
 | |
|         #setup the snmp destination
 | |
|         foreach (keys(%masterhash)) {
 | |
|             my $ref2 = $masterhash{$_};
 | |
|             if (@$ref2 == 0) { next; }
 | |
|             my $nr2   = join(',', @$ref2);
 | |
|             my @tmp_a = xCAT::NetworkUtils::toIP($_);
 | |
|             my $ptmp  = $tmp_a[0];
 | |
|             if ($ptmp->[0] > 0) {
 | |
|                 xCAT::MsgUtils->message('S', "[mon]: Converting to IP: $ptmp->[1]\n");
 | |
|                 $ret_val = 1;
 | |
|                 $ret_text .= "Converting to IP: $ptmp->[1]\n";
 | |
|             } else {
 | |
|                 print "XCATBYPASS=Y rspconfig $nr2 snmpdest=$ptmp->[1] community=public\n";
 | |
|                 my $result2 = `XCATBYPASS=Y rspconfig $nr2 snmpdest=$ptmp->[1] community=public 2>&1`;
 | |
|                 if ($?) {
 | |
|                     $ret_val = 1;
 | |
|                     xCAT::MsgUtils->message('S', "[mon]: Changing SNMP destination for IPMI nodes $nr2:\n  $result2\n");
 | |
|                     $ret_text .= "Changing SNMP destination for IPMI nodes $nr2:\n  $result2\n";
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if ($callback) {
 | |
|         my $rsp = {};
 | |
|         if ($ret_val) {
 | |
|             $rsp->{data}->[0] = "$ret_text";
 | |
|         }
 | |
|         $callback->($rsp);
 | |
|     }
 | |
| 
 | |
|     return ($ret_val, $ret_text);
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3    configMPA
 | |
|       This function configures Blade Center Management Module to setup the snmp destination,
 | |
|       enable/disable remote alert notification.
 | |
|     Arguments:
 | |
|       actioon -- 1 enable remote alert notification. 0 disable remote alert notification.
 | |
|                  2 setting up snmp destination.
 | |
|       p_nodes -- a pointer to an arrays of nodes to be monitored. null means all.
 | |
|       callback -- the callback pointer for error and status displaying. It can be null.
 | |
|     Returns:
 | |
|       (return code, message)
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub configMPA {
 | |
|     my $action   = shift;
 | |
|     my $noderef  = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     my $ret_val  = 0;
 | |
|     my $ret_text = "";
 | |
| 
 | |
|     #the identification of this node
 | |
|     my @hostinfo = xCAT::NetworkUtils->determinehostname();
 | |
|     my $isSV     = xCAT::Utils->isServiceNode();
 | |
|     my %iphash   = ();
 | |
|     foreach (@hostinfo) { $iphash{$_} = 1; }
 | |
|     if (!$isSV) { $iphash{'noservicenode'} = 1; }
 | |
| 
 | |
|     my $all      = 0;
 | |
|     my %nodehash = ();
 | |
|     if ((!$noderef) || (@$noderef == 0)) { $all = 1; }
 | |
|     else {
 | |
|         foreach (@$noderef) { $nodehash{$_} = 1; }
 | |
|     }
 | |
| 
 | |
|     my %mpa_hash   = ();
 | |
|     my %masterhash = ();
 | |
|     my @node_a     = ();
 | |
|     my $table      = xCAT::Table->new("mp");
 | |
|     if ($table) {
 | |
|         my @tmp1 = $table->getAllNodeAttribs([ 'node', 'mpa' ]);
 | |
|         if (@tmp1 > 0) {
 | |
|             foreach (@tmp1) {
 | |
|                 my $node = $_->{node};
 | |
|                 my $mpa  = $_->{mpa};
 | |
|                 if ((!$all) && (!exists($nodehash{$node})) && (!exists($nodehash{$mpa}))) { next; }
 | |
| 
 | |
|                 if ($mpa_hash{$mpa}) { next; }    #already handled
 | |
| 
 | |
|                 $mpa_hash{$mpa} = 1;
 | |
| 
 | |
|                 my $pHash = xCAT_monitoring::monitorctrl->getNodeMonServerPair([$mpa], 0);
 | |
|                 if (ref($pHash) eq 'ARRAY') {
 | |
|                     if ($callback) {
 | |
|                         my $rsp = {};
 | |
|                         if ($ret_val) {
 | |
|                             $rsp->{data}->[0] = $pHash->[1];
 | |
|                         }
 | |
|                         $callback->($rsp);
 | |
|                     } else {
 | |
|                         xCAT::MsgUtils->message('S', "[mon]: " . $pHash->[1]);
 | |
|                     }
 | |
|                     return (0, "");
 | |
|                 }
 | |
| 
 | |
|                 my $pairs     = $pHash->{$mpa};
 | |
|                 my @a_temp    = split(':', $pairs);
 | |
|                 my $monserver = $a_temp[0];
 | |
|                 my $master    = $a_temp[1];
 | |
| 
 | |
|                 if ($monserver) {
 | |
|                     if (!$iphash{$monserver}) { next; } #skip if has sn but not localhost
 | |
|                 } else {
 | |
|                     if ($isSV) { next; } #skip if does not have sn but localhost is a sn
 | |
|                 }
 | |
| 
 | |
|                 push(@node_a, $mpa);
 | |
| 
 | |
|                 # find the master node and add the node in the hash
 | |
|                 if (exists($masterhash{$master})) {
 | |
|                     my $ref = $masterhash{$master};
 | |
|                     push(@$ref, $mpa);
 | |
|                 } else { $masterhash{$master} = [$mpa]; }
 | |
|             }    #foreach
 | |
|         }
 | |
|         $table->close();
 | |
|     }
 | |
| 
 | |
|     if (@node_a == 0) { return ($ret_val, $ret_text); }    #nothing to handle
 | |
|            #print "configMPA: node_a=@node_a\n";
 | |
| 
 | |
| 
 | |
|     #now doing the real thing: enable PEF alert policy table
 | |
|     my $noderange = join(',', @node_a);
 | |
|     if ($action == 0) {
 | |
|         print "XCATBYPASS=Y rspconfig $noderange alert=dis\n";
 | |
|         my $result = `XCATBYPASS=Y rspconfig $noderange alert=dis 2>&1`;
 | |
|         if ($?) {
 | |
|             $ret_val = 1;
 | |
|             xCAT::MsgUtils->message('S', "[mon]: Changeing SNMP remote alert profile for Blade Center MM $noderange:\n  $result\n");
 | |
|             $ret_text .= "Changeing SNMP remote alert profile for Blade Center MM $noderange:\n  $result\n";
 | |
|         }
 | |
|     } elsif ($action == 1) {
 | |
|         print "XCATBYPASS=Y rspconfig $noderange alert=en\n";
 | |
|         my $result = `XCATBYPASS=Y rspconfig $noderange alert=en 2>&1`;
 | |
|         if ($?) {
 | |
|             $ret_val = 1;
 | |
|             xCAT::MsgUtils->message('S', "[mon]: Changeing SNMP remote alert profile for Blade Center MM $noderange:\n  $result\n");
 | |
|             $ret_text .= "Changeing SNMP remote alert profile for Blade Center MM $noderange:\n  $result\n";
 | |
|         }
 | |
|     } else {
 | |
| 
 | |
|         #setup the snmp destination
 | |
|         foreach (keys(%masterhash)) {
 | |
|             my $ref2 = $masterhash{$_};
 | |
|             if (@$ref2 == 0) { next; }
 | |
|             my $nr2   = join(',', @$ref2);
 | |
|             my @tmp_a = xCAT::NetworkUtils::toIP($_);
 | |
|             my $ptmp  = $tmp_a[0];
 | |
|             if ($ptmp->[0] > 0) {
 | |
|                 xCAT::MsgUtils->message('S', "[mon]: Converting to IP: $ptmp->[1]\n");
 | |
|                 $ret_val = 1;
 | |
|                 $ret_text .= "Converting to IP: $ptmp->[1]\n";
 | |
|             } else {
 | |
|                 print "XCATBYPASS=Y rspconfig $nr2 snmpdest=$ptmp->[1]\n";
 | |
|                 my $result2 = `XCATBYPASS=Y rspconfig $nr2 snmpdest=$ptmp->[1] 2>&1`;
 | |
|                 if ($?) {
 | |
|                     $ret_val = 1;
 | |
|                     xCAT::MsgUtils->message('S', "[mon]: Changing SNMP destination for Blade Center MM $nr2:\n  $result2\n");
 | |
|                     $ret_text .= "Changing SNMP destination for Blade Center MM $nr2:\n  $result2\n";
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if ($callback) {
 | |
|         my $rsp = {};
 | |
|         if ($ret_val) {
 | |
|             $rsp->{data}->[0] = "$ret_text";
 | |
|         }
 | |
|         $callback->($rsp);
 | |
|     }
 | |
| 
 | |
|     return ($ret_val, $ret_text);
 | |
| }
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3    configSwitch
 | |
|       This function configures switches to setup the snmp destination, enable/disable
 | |
|     alerts.
 | |
|     Arguments:
 | |
|       actioon -- 0 disable alert (called mon monstop).
 | |
|                  1 enable alert. (called by monstart)
 | |
|                  2 setup snmp destination (called by moncfg)
 | |
|                  3 remove the snmp destination (called by mondecfg)
 | |
|     p_nodes -- a pointer to an arrays of nodes to be monitored. null means all.
 | |
|       callback -- the callback pointer for error and status displaying. It can be null.
 | |
|     Returns:
 | |
|       (return code, message)
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub configSwitch {
 | |
|     my $action   = shift;
 | |
|     my $noderef  = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     my $ret_text = "";
 | |
|     my $ret_val  = 0;
 | |
| 
 | |
|     #the identification of this node
 | |
|     my @hostinfo = xCAT::NetworkUtils->determinehostname();
 | |
|     my $isSV     = xCAT::Utils->isServiceNode();
 | |
|     my %iphash   = ();
 | |
|     foreach (@hostinfo) { $iphash{$_} = 1; }
 | |
|     if (!$isSV) { $iphash{'noservicenode'} = 1; }
 | |
| 
 | |
|     my $pPairHash = xCAT_monitoring::monitorctrl->getNodeMonServerPair($noderef, 0);
 | |
|     if (ref($pPairHash) eq 'ARRAY') {
 | |
|         if ($callback) {
 | |
|             my $rsp = {};
 | |
|             if ($ret_val) {
 | |
|                 $rsp->{data}->[0] = $pPairHash->[1];
 | |
|             }
 | |
|             $callback->($rsp);
 | |
|         } else {
 | |
|             xCAT::MsgUtils->message('S', "[mon]: " . $pPairHash->[1]);
 | |
|         }
 | |
|         return (0, "");
 | |
|     }
 | |
| 
 | |
| 
 | |
|     my @node_a = ();
 | |
|     my $table = xCAT::Table->new('switches', -create => 0);
 | |
|     if ($table) {
 | |
|         my @tmp1 = $table->getAllAttribs(('switch'));
 | |
|         if (scalar @tmp1 > 0) {
 | |
|             foreach (@tmp1) {
 | |
|                 my @switches_tmp = noderange($_->{switch});
 | |
|                 if (@switches_tmp == 0) { push @switches_tmp, $_->{switch}; }
 | |
|                 foreach my $node (@switches_tmp) {
 | |
|                     if (!exists($pPairHash->{$node})) { next; }
 | |
|                     my $pairs     = $pPairHash->{$node};
 | |
|                     my @a_temp    = split(':', $pairs);
 | |
|                     my $monserver = $a_temp[0];
 | |
|                     my $master    = $a_temp[1];
 | |
| 
 | |
|                     if ($monserver) {
 | |
|                         if (!$iphash{$monserver}) { next; } #skip if has sn but not localhost
 | |
|                     } else {
 | |
|                         if ($isSV) { next; } #skip if does not have sn but localhost is a sn
 | |
|                     }
 | |
| 
 | |
|                     push(@node_a, $node);
 | |
|                 }    #foreach
 | |
|             }
 | |
|             $table->close();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if (@node_a == 0) { return ($ret_val, $ret_text); }    #nothing to handle
 | |
|     print "configSwitch: node_a=@node_a\n";
 | |
| 
 | |
|     #now doing the real thing: enable PEF alert policy table
 | |
|     foreach my $noderange (@node_a) {
 | |
|         $ret_val  = 0;
 | |
|         $ret_text = "";
 | |
|         if ($action == 0) {
 | |
|             print "XCATBYPASS=Y rspconfig $noderange alert=dis\n";
 | |
|             my $result = `XCATBYPASS=Y rspconfig $noderange alert=dis 2>&1`;
 | |
|             if (($result =~ /Error:/) || ($?)) {
 | |
|                 $ret_val = 1;
 | |
|                 xCAT::MsgUtils->message('S', "[mon]: Disabling SNMP alert for switches $noderange:\n  $result\n");
 | |
|                 $ret_text .= "Disabling SNMP alert.\n  $result\n";
 | |
|             }
 | |
|         } elsif ($action == 1) {
 | |
|             print "XCATBYPASS=Y rspconfig $noderange alert=en\n";
 | |
|             my $result = `XCATBYPASS=Y rspconfig $noderange alert=en 2>&1`;
 | |
|             if (($result =~ /Error:/) || ($?)) {
 | |
|                 $ret_val = 1;
 | |
|                 xCAT::MsgUtils->message('S', "[mon]: Enabling SNMP alert for switches $noderange:\n  $result\n");
 | |
|                 $ret_text .= "Enabling SNMP alert.\n  $result\n";
 | |
|             }
 | |
|         } elsif ($action == 2) {
 | |
|             print "XCATBYPASS=Y rspconfig $noderange sshcfg\n";
 | |
|             my $result = `XCATBYPASS=Y rspconfig $noderange sshcfg 2>&1`;
 | |
|             if ($result !~ /enabled/) {
 | |
|                 print "XCATBYPASS=Y rspconfig $noderange sshcfg=en\n";
 | |
|                 my $result = `XCATBYPASS=Y rspconfig $noderange sshcfg=en 2>&1`;
 | |
|                 if (($result =~ /Error:/) || ($?)) {
 | |
|                     $ret_val = 1;
 | |
|                     xCAT::MsgUtils->message('S', "[mon]: Setting up SSH for switches $noderange:\n  $result\n");
 | |
|                     $ret_text .= "Setting up SSH.\n  $result\n";
 | |
|                 }
 | |
|             } else {
 | |
|                 print "XCATBYPASS=Y rspconfig $noderange snmpcfg\n";
 | |
|                 my $result = `XCATBYPASS=Y rspconfig $noderange snmpcfg 2>&1`;
 | |
|                 if ($result !~ /enabled/) {
 | |
|                     print "XCATBYPASS=Y rspconfig $noderange snmpcfg=en\n";
 | |
|                     my $result = `XCATBYPASS=Y rspconfig $noderange snmpcfg=en 2>&1`;
 | |
|                     if (($result =~ /Error:/) || ($?)) {
 | |
|                         $ret_val = 1;
 | |
|                         xCAT::MsgUtils->message('S', "[mon]: Enabling SNMP for switches $noderange:\n  $result\n");
 | |
|                         $ret_text .= "Enabling SNMP.\n  $result\n";
 | |
|                     }
 | |
|                 } else {
 | |
| 
 | |
|                     #setup the snmp destination
 | |
|                     my $pairs     = $pPairHash->{$noderange};
 | |
|                     my @a_temp    = split(':', $pairs);
 | |
|                     my $monserver = $a_temp[0];
 | |
|                     my $master    = $a_temp[1];
 | |
|                     my @tmp_a     = xCAT::NetworkUtils::toIP($master);
 | |
|                     my $ptmp      = $tmp_a[0];
 | |
|                     if ($ptmp->[0] > 0) {
 | |
|                         xCAT::MsgUtils->message('S', "[mon]: Converting to IP: $ptmp->[1]\n");
 | |
|                         $ret_val = 1;
 | |
|                         $ret_text .= "Converting to IP: $ptmp->[1]\n";
 | |
|                     } else {
 | |
|                         print "XCATBYPASS=Y rspconfig $noderange snmpdest=$ptmp->[1]\n";
 | |
|                         my $result = `XCATBYPASS=Y rspconfig $noderange snmpdest=$ptmp->[1] 2>&1`;
 | |
|                         if (($result =~ /Error:/) || ($?)) {
 | |
|                             $ret_val = 1;
 | |
|                             xCAT::MsgUtils->message('S', "[mon]: Changing SNMP destination for switches $noderange:\n  $result\n");
 | |
|                             $ret_text .= "Changing SNMP destination\n  $result\n";
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|         } elsif ($action == 3) {
 | |
| 
 | |
|             #remove the snmp destination
 | |
|             my $pairs     = $pPairHash->{$noderange};
 | |
|             my @a_temp    = split(':', $pairs);
 | |
|             my $monserver = $a_temp[0];
 | |
|             my $master    = $a_temp[1];
 | |
|             my @tmp_a     = xCAT::NetworkUtils::toIP($master);
 | |
|             my $ptmp      = $tmp_a[0];
 | |
|             if ($ptmp->[0] > 0) {
 | |
|                 xCAT::MsgUtils->message('S', "[mon]: Converting to IP: $ptmp->[1]\n");
 | |
|                 $ret_val = 1;
 | |
|                 $ret_text .= "Converting to IP: $ptmp->[1]\n";
 | |
|             } else {
 | |
|                 print "XCATBYPASS=Y rspconfig $noderange snmpdest=$ptmp->[1] remove\n";
 | |
|                 my $result = `XCATBYPASS=Y rspconfig $noderange snmpdest=$ptmp->[1] remove 2>&1`;
 | |
|                 if (($result =~ /Error:/) || ($?)) {
 | |
|                     $ret_val = 1;
 | |
|                     xCAT::MsgUtils->message('S', "[mon]: Removing SNMP destination for switches $noderange:\n  $result\n");
 | |
|                     $ret_text .= "Removing SNMP destination\n  $result\n";
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if ($callback) {
 | |
|             my $rsp = {};
 | |
|             if ($ret_val) {
 | |
|                 $rsp->{data}->[0] = "$noderange: $ret_text";
 | |
|             } else {
 | |
|                 $rsp->{data}->[0] = "$noderange: done.\n $ret_text"
 | |
|             }
 | |
|             $callback->($rsp);
 | |
|         }
 | |
|     }
 | |
| 
 | |
| 
 | |
| 
 | |
|     return ($ret_val, $ret_text);
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3    configSNMP
 | |
|       This function puts xcat_traphanlder into the snmptrapd.conf file and
 | |
|       restarts the snmptrapd with the new configuration.
 | |
|     Arguments:
 | |
|       none.
 | |
|     Returns:
 | |
|       (return code, message)
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub configSNMP {
 | |
|     my $action   = shift;
 | |
|     my $noderef  = shift;
 | |
|     my $callback = shift;
 | |
| 
 | |
|     my $ret_val  = 0;
 | |
|     my $ret_text = "";
 | |
| 
 | |
|     print "configSNMP called \n";
 | |
|     my $isSN   = xCAT::Utils->isServiceNode();
 | |
|     my $master = xCAT::TableUtils->get_site_Master();
 | |
|     my $cmd;
 | |
| 
 | |
|     # now move $::snmpconfdir/snmptrapd.conf to $::snmpconfdir/snmptrapd.conf.orig
 | |
|     # if it exists.
 | |
|     mkpath("$::snmpconfdir");
 | |
|     if (-f "$::snmpconfdir/snmptrapd.conf") {
 | |
| 
 | |
|         # if the file exists and has references to xcat_traphandler in mn or 'forward' in sn
 | |
|         # then there is nothing that needs to be done.
 | |
|         if ($isSN) {
 | |
| `/bin/grep "forward default $master" $::snmpconfdir/snmptrapd.conf > /dev/null`;
 | |
|         } else {
 | |
| `/bin/grep  xcat_traphandler $::snmpconfdir/snmptrapd.conf > /dev/null`;
 | |
|         }
 | |
| 
 | |
|         # if the return code is 1, then there is no xcat_traphandler, or 'forward'
 | |
|         # references and we need to put them in.
 | |
|         if ($? >> 8) {
 | |
| 
 | |
|             # back up the original file.
 | |
| `/bin/cp -f $::snmpconfdir/snmptrapd.conf $::snmpconfdir/snmptrapd.conf.orig`;
 | |
| 
 | |
|             # if the file exists and does not have  "authCommunity execute,net public" then add it.
 | |
|             open(FILE1, "<$::snmpconfdir/snmptrapd.conf");
 | |
|             open(FILE,  ">$::snmpconfdir/snmptrapd.conf.tmp");
 | |
|             my $found           = 0;
 | |
|             my $forward_handled = 0;
 | |
|             while (readline(FILE1)) {
 | |
|                 if (/\s*authCommunity.*public/) {
 | |
|                     $found = 1;
 | |
|                     if (!/\s*authCommunity\s*.*execute.*public/) {
 | |
| s/authCommunity\s*(.*)\s* public/authCommunity $1,execute public/; #modify it to have 'execute' if found
 | |
|                     }
 | |
|                     if (!/\s*authCommunity\s*.*net.*public/) {
 | |
| s/authCommunity\s*(.*)\s* public/authCommunity $1,net public/; #modify it to have 'net' if found
 | |
|                     }
 | |
|                 } elsif (/\s*forward\s*default/) {
 | |
|                     if (($isSN) && (!/$master/)) {
 | |
|                         s/\s*forward/\#forward/;    #comment out the old one
 | |
|                         if (!$forward_handled) {
 | |
|                             print FILE "forward default $master\n";
 | |
|                             $forward_handled = 1;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 print FILE $_;
 | |
|             }
 | |
| 
 | |
| 
 | |
| 
 | |
|             if (!$found) {    #add new one if not found
 | |
|                 print FILE "authCommunity log,execute,net public\n";
 | |
|             }
 | |
| 
 | |
|             # now add the new traphandle commands:
 | |
|             if (!$isSN) {
 | |
|                 print FILE "traphandle default $::XCATROOT/sbin/xcat_traphandler\n";
 | |
|             }
 | |
| 
 | |
|             close(FILE1);
 | |
|             close(FILE);
 | |
| `mv -f $::snmpconfdir/snmptrapd.conf.tmp $::snmpconfdir/snmptrapd.conf`;
 | |
|         }
 | |
|     }
 | |
|     else {    # The snmptrapd.conf file does not exists
 | |
|               # create the file:
 | |
|         my $handle = new IO::File;
 | |
|         open($handle, ">$::snmpconfdir/snmptrapd.conf");
 | |
|         print $handle "authCommunity log,execute,net public\n";
 | |
|         if ($isSN) {
 | |
|             print $handle "forward default $master\n"; #forward the trap from sn to mn
 | |
|         } else {
 | |
|             print $handle "traphandle default $::XCATROOT/sbin/xcat_traphandler\n";
 | |
|         }
 | |
|         close($handle);
 | |
|     }
 | |
| 
 | |
| 
 | |
|     # Configure SNMPv3 on AIX
 | |
|     #  if(xCAT::Utils->isAIX()){
 | |
|     #the identification of this node
 | |
|     my @hostinfo = xCAT::NetworkUtils->determinehostname();
 | |
|     my $isSV     = xCAT::Utils->isServiceNode();
 | |
|     my %iphash   = ();
 | |
|     foreach (@hostinfo) { $iphash{$_} = 1; }
 | |
|     if (!$isSV) { $iphash{'noservicenode'} = 1; }
 | |
| 
 | |
|     my $all      = 0;
 | |
|     my %nodehash = ();
 | |
|     if ((!$noderef) || (@$noderef == 0)) { $all = 1; }
 | |
|     else {
 | |
|         foreach (@$noderef) { $nodehash{$_} = 1; }
 | |
|     }
 | |
| 
 | |
|     my %mpa_hash   = ();
 | |
|     my %masterhash = ();
 | |
|     my @node_a     = ();
 | |
|     my $table      = xCAT::Table->new("mp");
 | |
|     if ($table) {
 | |
|         my @tmp1 = $table->getAllNodeAttribs([ 'node', 'mpa' ]);
 | |
|         if (@tmp1 > 0) {
 | |
|             foreach (@tmp1) {
 | |
|                 my $node = $_->{node};
 | |
|                 my $mpa  = $_->{mpa};
 | |
|                 if ((!$all) && (!exists($nodehash{$node})) && (!exists($nodehash{$mpa}))) { next; }
 | |
| 
 | |
|                 if ($mpa_hash{$mpa}) { next; }    #already handled
 | |
| 
 | |
|                 $mpa_hash{$mpa} = 1;
 | |
| 
 | |
|                 my $pHash = xCAT_monitoring::monitorctrl->getNodeMonServerPair([$mpa], 0);
 | |
|                 if (ref($pHash) eq 'ARRAY') {
 | |
|                     if ($callback) {
 | |
|                         my $rsp = {};
 | |
|                         if ($ret_val) {
 | |
|                             $rsp->{data}->[0] = $pHash->[1];
 | |
|                         }
 | |
|                         $callback->($rsp);
 | |
|                     } else {
 | |
|                         xCAT::MsgUtils->message('S', "[mon]: " . $pHash->[1]);
 | |
|                     }
 | |
|                     return (0, "");
 | |
|                 }
 | |
| 
 | |
|                 my $pairs     = $pHash->{$mpa};
 | |
|                 my @a_temp    = split(':', $pairs);
 | |
|                 my $monserver = $a_temp[0];
 | |
|                 my $master    = $a_temp[1];
 | |
| 
 | |
|                 if ($monserver) {
 | |
|                     if (!$iphash{$monserver}) { next; } #skip if has sn but not localhost
 | |
|                 } else {
 | |
|                     if ($isSV) { next; } #skip if does not have sn but localhost is a sn
 | |
|                 }
 | |
| 
 | |
|                 push(@node_a, $mpa);
 | |
| 
 | |
|                 # find the master node and add the node in the hash
 | |
|                 if (exists($masterhash{$master})) {
 | |
|                     my $ref = $masterhash{$master};
 | |
|                     push(@$ref, $mpa);
 | |
|                 } else { $masterhash{$master} = [$mpa]; }
 | |
|             }    #foreach
 | |
|         }
 | |
|         $table->close();
 | |
|     }
 | |
| 
 | |
|     if (@node_a == 0) { return ($ret_val, $ret_text); }    #nothing to handle
 | |
| 
 | |
|     # Read username, password, and mac from DB.
 | |
|     foreach my $mpa (@node_a) {
 | |
|         my $mac;
 | |
|         my $user;
 | |
|         my $password;
 | |
| 
 | |
|         my $mpatable = xCAT::Table->new("mpa");
 | |
|         if ($mpatable) {
 | |
|             my $mpa_a = $mpatable->getAttribs({ mpa => $mpa }, 'username', 'password');
 | |
|             if ($mpa_a and $mpa_a->{username} and $mpa_a->{password}) {
 | |
|                 $user     = $mpa_a->{username};
 | |
|                 $password = $mpa_a->{password};
 | |
|             } else {
 | |
|                 xCAT::MsgUtils->message('E', "No username or password found for $mpa");
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         my $mactable = xCAT::Table->new("mac");
 | |
|         if ($mactable) {
 | |
|             my $mac_a = $mactable->getAttribs({ node => $mpa }, 'mac');
 | |
|             if ($mac_a and $mac_a->{mac}) {
 | |
|                 $mac = $mac_a->{mac};
 | |
|             } else {
 | |
|                 xCAT::MsgUtils->message('E', "No mac found for $mpa");
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         my $found1 = 0;
 | |
|         my $found2 = 0;
 | |
|         if ($mac and $user and $password) {
 | |
| 
 | |
|             #write configuration file
 | |
|             open(FILE1, "<$::snmpconfdir/snmptrapd.conf");
 | |
|             open(FILE,  ">$::snmpconfdir/snmptrapd.conf.tmp");
 | |
|             while (readline(FILE1)) {
 | |
|                 if (/\s*authUser.*$user/) {
 | |
|                     $found1 = 1;
 | |
|                     if (!/\s*authUser\s*.*execute.*$user/) {
 | |
|                         s/authUser\s*(.*)\s* $user/authUser $1,execute $user/; #modify it to have 'execute' if found
 | |
|                     }
 | |
|                 }
 | |
|                 if (!/\s*authUser\s*.*net.*$user/) {
 | |
|                     s/authUser\s*(.*)\s* $user/authUser $1,net $user/; #modify it to have 'net' if found
 | |
|                 }
 | |
| 
 | |
|                 if (/\s*createUser.*$mac.*$user.*$password/) {
 | |
|                     $found2 = 1;
 | |
|                 }
 | |
| 
 | |
|                 print FILE $_;
 | |
|             }
 | |
| 
 | |
|         }
 | |
| 
 | |
|         if (!$found1) {    #add new one if not found
 | |
|             print FILE "authUser log,execute,net $user\n";
 | |
|         }
 | |
| 
 | |
|         if (!$found2) {
 | |
|             print FILE "createUser -e 0x8000045001$mac $user SHA $password DES\n";
 | |
|         }
 | |
| 
 | |
|         close(FILE1);
 | |
|         close(FILE);
 | |
|         `mv -f $::snmpconfdir/snmptrapd.conf.tmp $::snmpconfdir/snmptrapd.conf`;
 | |
|     }
 | |
| 
 | |
|     #  }
 | |
| 
 | |
| 
 | |
|     # TODO: put the mib files to /usr/share/snmp/mibs
 | |
|     return (0, "");
 | |
| }
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3    configMail
 | |
|       This function adds a "alerts" mail aliase so that the mail notification
 | |
|       from the trap handler can be received. It the alerts already exists, this
 | |
|       function does nothing.
 | |
|       TODO: configure mail servers on MS to forward mails to MS
 | |
|     Arguments:
 | |
|       none
 | |
|     Returns:
 | |
|       (return code, message)
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub configMail {
 | |
| 
 | |
|     #check if "alerts" is in the /etc/aliases file
 | |
|     if (-f "/etc/aliases") {
 | |
| 
 | |
|         # if the file exists, check if alerts is in
 | |
|         `/bin/grep -e ^alerts /etc/aliases > /dev/null`;
 | |
|         if ($? == 0) { return (0, "") }
 | |
|     }
 | |
| 
 | |
|     #make a alerts aliase, forwarding the mail to the root of local host.
 | |
|     `echo "alerts:  root" >> /etc/aliases`;
 | |
| 
 | |
|     #make it effective
 | |
|     `newaliases`;
 | |
| 
 | |
|     return (0, "");
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3    processSettingChanges
 | |
|       This function gets called when the setting for this monitoring plugin
 | |
|       has been changed in the monsetting table.
 | |
|     Arguments:
 | |
|        none.
 | |
|     Returns:
 | |
|         0 for successful.
 | |
|         non-0 for not successful.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub processSettingChanges {
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3    getDiscription
 | |
|       This function returns the detailed description of the plugin inluding the
 | |
|      valid values for its settings in the monsetting tabel.
 | |
|      Arguments:
 | |
|         none
 | |
|     Returns:
 | |
|         The description.
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub getDescription {
 | |
|     return
 | |
|       "  Description:
 | |
|     snmpmon sets up the snmptrapd on the management server to receive SNMP
 | |
|     traps for different nodes. It also sets the trap destination for Blade
 | |
|     Center Management Module, RSA II, IPMIs that are managed by the xCAT cluster.
 | |
|     xCAT has categorized some events into different event priorities (critical,
 | |
|     warning and informational) based on the MIBs we know such as MM, RSA II and
 | |
|     IPMI. All the unknown events are categorized as 'warning'. By default,
 | |
|     the xCAT trap handler will log all events into the syslog and only
 | |
|     email the critical and the warning events to the mail alias called 'alerts'.
 | |
|     You can use the settings to override the default behavior.
 | |
|     Use command 'monstart snmpmon' to star monitoring and 'monstop snmpmon'
 | |
|     to stop it.
 | |
|   Settings:
 | |
|     ignore:  specifies the events that will be ignored. It's a comma separated
 | |
|         pairs of oid=value. For example,
 | |
|         spTrapAppType=4,spTrapMsgText=~power,spTrapMsgText=Hello there.
 | |
|     email:  specifies the events that will get email notification.
 | |
|     log:    specifies the events that will get logged.
 | |
|     runcmd#:specifies the events that will be passed to the user defined scripts.
 | |
|     cmds#:  specifies the command names that will be invoked for the events
 | |
|             specified in the runcmd# row. '#' is a number.
 | |
|     db:     specifies the events that will be logged into the eventlog table
 | |
|             in xCAT database.
 | |
| 
 | |
|     Special keywords for specifying events:
 | |
|       All -- all events.
 | |
|       None -- none of the events.
 | |
|       Critical -- all critical events.
 | |
|       Warning -- all warning events.
 | |
|       Informational -- all informational events.
 | |
| 
 | |
|     For example, you can have the following setting:
 | |
|       email  Critical,spTrapMsgText=~Test this,spTrapMsgText=Hello there
 | |
|       This means send email for all the critical events and events with spTrapMsgText
 | |
|       contains the phrase 'Test this' or equals 'Hello there'.\n"
 | |
| }
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| 
 | |
| =head3    getNodesMonServers
 | |
|       This function checks the given nodes, if they are bmc/ipmi nodes, the monserver pairs of
 | |
|      the nodes will be returned. If the nodes are managed by MM, the monserver pairs of their
 | |
|      mpa will be returned.
 | |
|      Arguments:
 | |
|        p_nodes -- a pointer to an arrays of nodes to be added for monitoring. none means all.
 | |
|        callback -- the callback pointer for error and status displaying. It can be null.
 | |
|    Returns:
 | |
|       A pointer to a hash table with monserver pairs as the key and an array
 | |
|                      pointer of nodes as the value.
 | |
|                      For example: { "sv1,ma1"=>[node1,node2], "sv2,ma2"=>node3...}
 | |
|          The pair is in the format of "monserver,monmaser". First one is the monitoring service
 | |
|       node ip/hostname that faces the mn and the second one is the monitoring service
 | |
|       node ip/hostname that faces the cn.
 | |
|       The value of the first one can be "noservicenode" meaning that there is no service node
 | |
|       for that node. In this case the second one is the site master.
 | |
|       It retuens a pointer to an array if there is an error. Format is [code, message].
 | |
| =cut
 | |
| 
 | |
| #--------------------------------------------------------------------------------
 | |
| sub getNodesMonServers
 | |
| {
 | |
|     print "snmpmon:getNodesMonServer called\n";
 | |
|     my $noderef = shift;
 | |
|     if ($noderef =~ /xCAT_monitoring::snmpmon/) {
 | |
|         $noderef = shift;
 | |
|     }
 | |
|     my $callback = shift;
 | |
| 
 | |
|     my $ret           = {};
 | |
|     my $localhostname = hostname();
 | |
|     my $pPairHash = xCAT_monitoring::monitorctrl->getNodeMonServerPair($noderef, 0);
 | |
| 
 | |
|     if (ref($pPairHash) eq 'ARRAY') {
 | |
|         return $pPairHash;
 | |
|     }
 | |
| 
 | |
| 
 | |
|     #check for blades, only returns the MPAs and their monservers
 | |
|     my %mpa_hash = ();
 | |
|     my $table    = xCAT::Table->new("mp");
 | |
|     if ($table) {
 | |
|         my @tmp1 = $table->getAllNodeAttribs([ 'node', 'mpa' ]);
 | |
|         if (@tmp1 > 0) {
 | |
|             foreach (@tmp1) {
 | |
|                 my $node = $_->{node};
 | |
|                 my $mpa  = $_->{mpa};
 | |
|                 if ((!exists($pPairHash->{$node})) && (!exists($pPairHash->{$mpa}))) { next; } #not in input
 | |
| 
 | |
|                 #if  (exists($pPairHash->{$node})) { delete($pPairHash->{$node}); }
 | |
|                 if ($mpa_hash{$mpa}) { next; }    #already handled
 | |
| 
 | |
|                 $mpa_hash{$mpa} = 1;
 | |
| 
 | |
|                 my $pairs;
 | |
|                 if (exists($pPairHash->{$mpa})) {
 | |
|                     $pairs = $pPairHash->{$mpa};
 | |
|                 } else {
 | |
|                     my $pHash = xCAT_monitoring::monitorctrl->getNodeMonServerPair([$mpa], 0);
 | |
|                     if (ref($pHash) eq 'ARRAY') {
 | |
|                         return $pHash;
 | |
|                     }
 | |
| 
 | |
|                     $pairs = $pHash->{$mpa};
 | |
|                 }
 | |
| 
 | |
|                 if (exists($ret->{$pairs})) {
 | |
|                     my $pa = $ret->{$pairs};
 | |
|                     push(@$pa, $mpa);
 | |
|                 }
 | |
|                 else {
 | |
|                     $ret->{$pairs} = [$mpa];
 | |
|                 }
 | |
| 
 | |
|                 #if (exists($pPairHash->{$mpa}))) { delete($pPairHash->{$mpa}); }
 | |
|             }    #foreach
 | |
|         }
 | |
|         $table->close();
 | |
|     }
 | |
| 
 | |
| 
 | |
|     #check BMC/IPMI nodes
 | |
|     $table = xCAT::Table->new("ipmi");
 | |
|     if ($table) {
 | |
|         my @tmp1 = $table->getAllNodeAttribs([ 'node', 'bmc' ]);
 | |
|         if (@tmp1 > 0) {
 | |
|             foreach (@tmp1) {
 | |
|                 my $node = $_->{node};
 | |
|                 my $bmc  = $_->{bmc};
 | |
|                 if (!exists($pPairHash->{$node})) { next; }
 | |
|                 my $pairs = $pPairHash->{$node};
 | |
| 
 | |
|                 if (exists($ret->{$pairs})) {
 | |
|                     my $pa = $ret->{$pairs};
 | |
|                     push(@$pa, $node);
 | |
|                 }
 | |
|                 else {
 | |
|                     $ret->{$pairs} = [$node];
 | |
|                 }
 | |
| 
 | |
|                 #delete($pPairHash->{$node});
 | |
|             }    #foreach
 | |
|         }
 | |
|         $table->close();
 | |
|     }
 | |
| 
 | |
|     #check swithes
 | |
|     my $table = xCAT::Table->new('switches', -create => 0);
 | |
|     if ($table) {
 | |
|         my @tmp1 = $table->getAllAttribs(('switch'));
 | |
|         if (scalar @tmp1 > 0) {
 | |
|             foreach (@tmp1) {
 | |
|                 my @switches_tmp = noderange($_->{switch});
 | |
|                 if (@switches_tmp == 0) { push @switches_tmp, $_->{switch}; }
 | |
|                 foreach my $node (@switches_tmp) {
 | |
|                     if (!exists($pPairHash->{$node})) { next; }
 | |
|                     my $pairs = $pPairHash->{$node};
 | |
| 
 | |
|                     if (exists($ret->{$pairs})) {
 | |
|                         my $pa = $ret->{$pairs};
 | |
|                         push(@$pa, $node);
 | |
|                     }
 | |
|                     else {
 | |
|                         $ret->{$pairs} = [$node];
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         $table->close();
 | |
|     }
 | |
| 
 | |
| 
 | |
|     return $ret;
 | |
| }
 |