mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 11:22:27 +00:00 
			
		
		
		
	Merge pull request #4391 from cxhong/pdurelay
Relay action and snmp configuration support for Coral PDU
This commit is contained in:
		| @@ -694,17 +694,25 @@ passed as argument rather than by table value', | ||||
|         }, | ||||
|     }, | ||||
|     pdu => { | ||||
|         cols => [qw(node nodetype outlet machinetype modelnum serialnum comments disable)], | ||||
|         cols => [qw(node nodetype pdutype outlet username password snmpversion community snmpuser authtype authkey privtype privkey seclevel comments disable)], | ||||
|         keys         => [qw(node)], | ||||
|         nodecol      => "node", | ||||
|         table_desc   => 'Parameters to use when interrogating pdus', | ||||
|         descriptions => { | ||||
|             node => 'The hostname/address of the pdu to which the settings apply', | ||||
|             nodetype => 'The node type should be pdu ', | ||||
|             pdutype => 'The type of pdu ', | ||||
|             outlet => 'The pdu outlet count', | ||||
|             machinetype => 'The pdu machine type', | ||||
|             modelnum    => 'The pdu model number', | ||||
|             serialnum   => 'The pdu serial number', | ||||
|             username => 'The remote login user name', | ||||
|             password => 'The remote login password', | ||||
|             snmpversion => 'The version to use to communicate with switch.  SNMPv1 is assumed by default.', | ||||
|             community => 'The community string to use for SNMPv1/v2', | ||||
|             snmpuser => 'The username to use for SNMPv3 communication, ignored for SNMPv1', | ||||
|             authtype => 'The authentication protocol(MD5|SHA) to use for SNMPv3.', | ||||
|             authkey => 'The authentication passphrase for SNMPv3 ', | ||||
|             privtype => 'The privacy protocol(AES|DES) to use for SNMPv3.', | ||||
|             privkey => 'The privacy passphrase to use for SNMPv3.', | ||||
|             seclevel => 'The Security Level(noAuthNoPriv|authNoPriv|authPriv) to use for SNMPv3.', | ||||
|             comments => 'Any user-written notes.', | ||||
|             disable  => "Set to 'yes' or '1' to comment out this row.", | ||||
|         }, | ||||
| @@ -2950,24 +2958,64 @@ my @nodeattrs = ( | ||||
|         tabentry        => 'pdu.nodetype', | ||||
|         access_tabentry => 'pdu.node=attr:node', | ||||
|     }, | ||||
|     {   attr_name => 'pdutype', | ||||
|         only_if         => 'nodetype=pdu', | ||||
|         tabentry        => 'pdu.pdutype', | ||||
|         access_tabentry => 'pdu.node=attr:node', | ||||
|     }, | ||||
|     { attr_name => 'outlet', | ||||
|         only_if         => 'nodetype=pdu', | ||||
|         tabentry        => 'pdu.outlet', | ||||
|         access_tabentry => 'pdu.node=attr:node', | ||||
|     }, | ||||
|     {   attr_name => 'machinetype', | ||||
|     {   attr_name => 'username', | ||||
|         only_if         => 'nodetype=pdu', | ||||
|         tabentry        => 'pdu.machinetype', | ||||
|         tabentry        => 'pdu.username', | ||||
|         access_tabentry => 'pdu.node=attr:node', | ||||
|     }, | ||||
|     { attr_name => 'modelnum', | ||||
|     { attr_name => 'password', | ||||
|         only_if         => 'nodetype=pdu', | ||||
|         tabentry        => 'pdu.modelnum', | ||||
|         tabentry        => 'pdu.password', | ||||
|         access_tabentry => 'pdu.node=attr:node', | ||||
|     }, | ||||
|     { attr_name => 'serialnum', | ||||
|     { attr_name => 'snmpversion', | ||||
|         only_if         => 'nodetype=pdu', | ||||
|         tabentry        => 'pdu.serialnum', | ||||
|         tabentry        => 'pdu.snmpversion', | ||||
|         access_tabentry => 'pdu.node=attr:node', | ||||
|     }, | ||||
|     { attr_name => 'community', | ||||
|         only_if         => 'nodetype=pdu', | ||||
|         tabentry        => 'pdu.community', | ||||
|         access_tabentry => 'pdu.node=attr:node', | ||||
|     }, | ||||
|     { attr_name => 'snmpuser', | ||||
|         only_if         => 'nodetype=pdu', | ||||
|         tabentry        => 'pdu.snmpuser', | ||||
|         access_tabentry => 'pdu.node=attr:node', | ||||
|     }, | ||||
|     { attr_name => 'authtype', | ||||
|         only_if         => 'nodetype=pdu', | ||||
|         tabentry        => 'pdu.authtype', | ||||
|         access_tabentry => 'pdu.node=attr:node', | ||||
|     }, | ||||
|     { attr_name => 'authkey', | ||||
|         only_if         => 'nodetype=pdu', | ||||
|         tabentry        => 'pdu.authkey', | ||||
|         access_tabentry => 'pdu.node=attr:node', | ||||
|     }, | ||||
|     { attr_name => 'privtype', | ||||
|         only_if         => 'nodetype=pdu', | ||||
|         tabentry        => 'pdu.privtype', | ||||
|         access_tabentry => 'pdu.node=attr:node', | ||||
|     }, | ||||
|     { attr_name => 'privkey', | ||||
|         only_if         => 'nodetype=pdu', | ||||
|         tabentry        => 'pdu.privkey', | ||||
|         access_tabentry => 'pdu.node=attr:node', | ||||
|     }, | ||||
|     { attr_name => 'seclevel', | ||||
|         only_if         => 'nodetype=pdu', | ||||
|         tabentry        => 'pdu.seclevel', | ||||
|         access_tabentry => 'pdu.node=attr:node', | ||||
|     }, | ||||
|  | ||||
|   | ||||
| @@ -41,7 +41,8 @@ our %global_switch_type = ( | ||||
|     MELLAN => "Mellanox", | ||||
|     Cumulus => "onie", | ||||
|     cumulus => "onie", | ||||
|     Edgecore => "onie" | ||||
|     Edgecore => "onie", | ||||
|     coral => "crpdu" | ||||
| ); | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -71,6 +71,41 @@ sub handled_commands | ||||
|     }; | ||||
| } | ||||
|  | ||||
| sub pdu_usage | ||||
| { | ||||
|     my ($callback, $command) = @_; | ||||
|     my $usagemsg =  | ||||
|     "Usage:  | ||||
|         pdudiscover [<noderange>|--range ipranges] [-r|-x|-z] [-w] [-V|--verbose] [--setup] | ||||
|         rpower pdunodes [off|on|stat|reset] | ||||
|  | ||||
|      The following command supports IR PDU with pdutype=irpdu : | ||||
|         rpower CN [pduoff|pduon|pdustat|pdustatus|pdureset]  | ||||
|  | ||||
|      The following commands support CR PDU with pdutype=crpdu : | ||||
|         rpower    pdunodes relay=[1|2|3] [on|off] | ||||
|         rinv      pdunodes | ||||
|         rvitals   pdunodes | ||||
|         rspconfig pdunodes sshcfg | ||||
|         rspconfig pdunodes snmpcfg | ||||
|         rspconfig pdunode [hostname=<NAME>|ip=<IP>|mask=<MASK>] | ||||
|           | ||||
|         \n"; | ||||
|                      | ||||
|     if ($callback) | ||||
|     { | ||||
|         my $rsp = {}; | ||||
|         $rsp->{data}->[0] = $usagemsg; | ||||
|         xCAT::MsgUtils->message("I", $rsp, $callback); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         xCAT::MsgUtils->message("I", $usagemsg); | ||||
|     } | ||||
|     return; | ||||
|  | ||||
| } | ||||
|  | ||||
| #-------------------------------------------------------------------------------- | ||||
| =head3   preprocess_request | ||||
|  | ||||
| @@ -94,15 +129,12 @@ sub preprocess_request { | ||||
|  | ||||
|     my $usage_string=xCAT::Usage->parseCommand($command, @exargs); | ||||
|     if ($usage_string) { | ||||
|         $callback->({data=>[$usage_string]}); | ||||
|         $req = {}; | ||||
|         return; | ||||
|          &pdu_usage($callback, $command); | ||||
|          return 1; | ||||
|     } | ||||
|  | ||||
|     if ((!$noderange) && ($command ne "pdudiscover") ){ | ||||
|         $usage_string = xCAT::Usage->getUsage($command); | ||||
|         $callback->({ data => $usage_string }); | ||||
|         $req = {}; | ||||
|         &pdu_usage($callback, $command); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
| @@ -137,11 +169,6 @@ sub process_request | ||||
|         @exargs = @$extrargs; | ||||
|     } | ||||
|  | ||||
|     #fill in the total outlet count for each pdu | ||||
|     $pdutab = xCAT::Table->new('pdu'); | ||||
|     @pduents = $pdutab->getAllNodeAttribs(['node', 'outlet']); | ||||
|     #fill_outletCount(\@pduents, $callback); | ||||
|  | ||||
|     if( $command eq "rinv") { | ||||
|         #for higher performance, handle node in batch | ||||
|         return showMFR($noderange, $callback); | ||||
| @@ -149,6 +176,7 @@ sub process_request | ||||
|         return showMonitorData($noderange, $callback); | ||||
|     }elsif ($command eq "rpower") { | ||||
|         my $subcmd = $exargs[0]; | ||||
|         my $subcmd2 = $exargs[1]; | ||||
|         if (($subcmd eq 'pduoff') || ($subcmd eq 'pduon') || ($subcmd eq 'pdustat')|| ($subcmd eq 'pdureset') ){ | ||||
|             #if one day, pdu node have pdu attribute, handle in this section too | ||||
|             return powerpduoutlet($noderange, $subcmd, $callback); | ||||
| @@ -169,11 +197,14 @@ sub process_request | ||||
|                 } | ||||
|             } | ||||
|             if(@allpdunodes) { | ||||
|                 if(($subcmd eq 'on') || ($subcmd eq 'off') || ($subcmd eq 'stat') || ($subcmd eq 'state') || ($subcmd eq 'reset') ){ | ||||
|                 if ( ($subcmd =~ /relay/) || ($subcmd2 =~ /relay/) ) { | ||||
|                     process_powerrelay($request,$subreq,\@allpdunodes,$callback); | ||||
|                 } elsif(($subcmd eq 'on') || ($subcmd eq 'off') || ($subcmd eq 'stat') || ($subcmd eq 'state') || ($subcmd eq 'reset') ){ | ||||
|                     return powerpdu(\@allpdunodes, $subcmd, $callback); | ||||
|                 } else { | ||||
|                     my $pdunode = join (",", @allpdunodes); | ||||
|                     $callback->({ errorcode => [1],error => "The option $subcmd is not support for pdu node(s) $pdunode."}); | ||||
|                     &pdu_usage($callback, $command); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @@ -181,15 +212,19 @@ sub process_request | ||||
|         my $subcmd = $exargs[0]; | ||||
|         if ($subcmd eq 'sshcfg') { | ||||
|             process_sshcfg($noderange, $subcmd, $callback); | ||||
|         }elsif ($subcmd eq 'snmpcfg') { | ||||
|             process_snmpcfg($noderange, $subcmd, $callback); | ||||
|         }elsif ($subcmd =~ /ip|netmask|hostname/) { | ||||
|             process_netcfg($request, $subreq, $subcmd, $callback); | ||||
|         } else { | ||||
|             $callback->({ errorcode => [1],error => "The input $command $subcmd is not support for pdu"}); | ||||
|             &pdu_usage($callback, $command); | ||||
|         } | ||||
|     }elsif($command eq "pdudiscover") { | ||||
|         process_pdudiscover($request, $subreq, $callback); | ||||
|     }elsif($command eq "nodeset") { | ||||
|         $callback->({ errorcode => [1],error => "The input $command is not support for pdu"}); | ||||
|         &pdu_usage($callback, $command); | ||||
|     }else{ | ||||
|         #reserve for other new command in future | ||||
|     } | ||||
| @@ -197,29 +232,30 @@ sub process_request | ||||
|     return; | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------- | ||||
|  | ||||
| =head3  fill_outletcount  | ||||
|  | ||||
|   Get outlet count for IR PDU. | ||||
|  | ||||
| =cut | ||||
|  | ||||
| #------------------------------------------------------- | ||||
| sub fill_outletCount { | ||||
|     my $pduentries = shift; | ||||
|     my $session = shift; | ||||
|     my $pdu = shift; | ||||
|     my $callback = shift; | ||||
|     my $outletoid = ".1.3.6.1.4.1.2.6.223.8.2.1.0"; | ||||
|     my $pdutab = xCAT::Table->new('pdu'); | ||||
|  | ||||
|     foreach my $pdu (@$pduentries) { | ||||
|         my $cur_pdu = $pdu->{node}; | ||||
|         my $count = $pdu->{outlet}; | ||||
|         #get total outlet number for the pdu | ||||
|         if (!$count) { | ||||
|             my $session = connectTopdu($cur_pdu,$callback); | ||||
|             #will not log this error to output | ||||
|             if (!$session) { | ||||
|                 next; | ||||
|             } | ||||
|             $count = $session->get("$outletoid"); | ||||
|             if ($count) { | ||||
|                 $pdutab->setNodeAttribs($cur_pdu, {outlet => $count}); | ||||
|             } | ||||
|         } | ||||
|         $pdunodes->{$cur_pdu}->{outlet}=$count; | ||||
|     my $count = $session->get("$outletoid"); | ||||
|     if ($count) { | ||||
|         $pdutab->setNodeAttribs($pdu, {outlet => $count}); | ||||
|     } | ||||
|  | ||||
|     return $count; | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------- | ||||
| @@ -240,13 +276,25 @@ sub powerpdu { | ||||
|         return powerstat($noderange, $callback); | ||||
|     } | ||||
|  | ||||
|     my $pdutab = xCAT::Table->new('pdu'); | ||||
|     my $pduhash = $pdutab->getNodesAttribs($noderange, ['pdutype','outlet']); | ||||
|  | ||||
|     foreach my $node (@$noderange) { | ||||
|         if ($pduhash->{$node}->[0]->{pdutype} eq 'crpdu') { | ||||
|             process_relay($node,$subcmd,$callback,1,3); | ||||
|             next; | ||||
|         } | ||||
|  | ||||
|         my $session = connectTopdu($node,$callback); | ||||
|         if (!$session) { | ||||
|             $callback->({ errorcode => [1],error => "Couldn't connect to $node"}); | ||||
|             next; | ||||
|         } | ||||
|         my $count = $pdunodes->{$node}->{outlet}; | ||||
|         my $count = $pduhash->{$node}->[0]->{outlet}; | ||||
|         unless ($count) { | ||||
|             $count = fill_outletCount($session, $node, $callback); | ||||
|         } | ||||
|  | ||||
|         my $value; | ||||
|         my $statstr; | ||||
|         if ($subcmd eq "off") { | ||||
| @@ -295,6 +343,9 @@ sub powerpduoutlet { | ||||
|  | ||||
|     my $nodetab = xCAT::Table->new('pduoutlet'); | ||||
|     my $nodepdu = $nodetab->getNodesAttribs($noderange,['pdu']); | ||||
|     my $pdutab = xCAT::Table->new('pdu'); | ||||
|     my $pduhash = $pdutab->getNodesAttribs($noderange, ['pdutype','outlet']); | ||||
|  | ||||
|     foreach my $node (@$noderange) { | ||||
|         # the pdu attribute needs to be set | ||||
|         if(! $nodepdu->{$node}->[0]->{pdu}){ | ||||
| @@ -305,12 +356,20 @@ sub powerpduoutlet { | ||||
|         my @pdus = split /,/, $nodepdu->{$node}->[0]->{pdu}; | ||||
|         foreach my $pdu_outlet (@pdus) { | ||||
|             my ($pdu, $outlet) = split /:/, $pdu_outlet; | ||||
|             if ($pduhash->{$pdu}->[0]->{pdutype} eq 'crpdu') { | ||||
|                 $callback->({ error => "$node: This command doesn't supports CONSTELLATION PDU with pdutype=crpdu for $pdu"}); | ||||
|                 next; | ||||
|             } | ||||
|             my $session = connectTopdu($pdu,$callback); | ||||
|             if (!$session) { | ||||
|                 $callback->({ errorcode => [1],error => "$node: Couldn't connect to $pdu"}); | ||||
|                 next; | ||||
|             } | ||||
|             if ($outlet > $pdunodes->{$pdu}->{outlet} ) { | ||||
|             my $count = $pduhash->{$pdu}->[0]->{outlet}; | ||||
|             unless ($count) { | ||||
|                 $count = fill_outletCount($session, $pdu, $callback); | ||||
|             } | ||||
|             if ($outlet > $count ) { | ||||
|                 $callback->({ error => "$node: $pdu outlet number $outlet is invalid"}); | ||||
|                 next; | ||||
|             } | ||||
| @@ -382,13 +441,60 @@ sub powerstat { | ||||
|     my $callback = shift; | ||||
|     my $output; | ||||
|  | ||||
|     my $pdutab = xCAT::Table->new('pdu'); | ||||
|     my $pduhash = $pdutab->getNodesAttribs($noderange, ['pdutype','outlet','snmpversion','snmpuser','authtype','authkey','privtype','privkey','seclevel']); | ||||
|  | ||||
|     foreach my $pdu (@$noderange) { | ||||
|         if ($pduhash->{$pdu}->[0]->{pdutype} eq 'crpdu') { | ||||
|             my $snmpversion = $pduhash->{$pdu}->[0]->{snmpversion}; | ||||
|             if ($snmpversion =~ /3/) { | ||||
|                 my $snmpuser = $pduhash->{$pdu}->[0]->{snmpuser}; | ||||
|                 my $seclevel = $pduhash->{$pdu}->[0]->{seclevel}; | ||||
|                 if ((defined $snmpuser) && (defined $seclevel)) { | ||||
|                     my $authtype = $pduhash->{$pdu}->[0]->{authtype}; | ||||
|                     if (!defined $authtype) { | ||||
|                         $authtype="MD5"; | ||||
|                     } | ||||
|                     my $authkey = $pduhash->{$pdu}->[0]->{authkey}; | ||||
|                     my $privtype = $pduhash->{$pdu}->[0]->{privtype}; | ||||
|                     if (!defined $privtype) { | ||||
|                         $privtype="DES"; | ||||
|                     } | ||||
|                     my $privkey = $pduhash->{$pdu}->[0]->{privkey}; | ||||
|                     if (!defined $privkey) { | ||||
|                         if (defined $authkey) { | ||||
|                             $privkey=$authkey; | ||||
|                         } | ||||
|                     } | ||||
|                     my $snmpcmd; | ||||
|                     if ($seclevel eq "authNoPriv") { | ||||
|                         $snmpcmd = "snmpwalk -v3 -u $snmpuser -a $authtype -A $authkey -l $seclevel";  | ||||
|                     } elsif ($seclevel eq "authPriv") { | ||||
|                         $snmpcmd = "snmpwalk -v3 -u $snmpuser -a $authtype -A $authkey -l $seclevel -x $privtype -X $privkey";  | ||||
|                     } else {   #default to notAuthNoPriv | ||||
|                         $snmpcmd = "snmpwalk -v3 -u $snmpuser -l $seclevel";  | ||||
|                     } | ||||
|  | ||||
|                     for (my $relay = 1; $relay <= 3; $relay++) { | ||||
|                         relaystat($pdu, $relay, $snmpcmd, $callback); | ||||
|                     } | ||||
|                     next; | ||||
|                 } | ||||
|            }  | ||||
|             xCAT::SvrUtils::sendmsg("please config snmpv3 to be able to query pdu relay status", $callback,$pdu); | ||||
|             xCAT::SvrUtils::sendmsg("    use chdef command to add pdu snmpv3 attributes to pdu table", $callback); | ||||
|             xCAT::SvrUtils::sendmsg("    then run 'rspconfig $pdu snmpcfg' command ", $callback); | ||||
|             next; | ||||
|         } | ||||
|         my $session = connectTopdu($pdu,$callback); | ||||
|         if (!$session) { | ||||
|             $callback->({ errorcode => [1],error => "Couldn't connect to $pdu"}); | ||||
|             next; | ||||
|         } | ||||
|         my $count = $pdunodes->{$pdu}->{outlet}; | ||||
|         my $count = $pduhash->{$pdu}->[0]->{outlet}; | ||||
|         unless ($count) { | ||||
|             $count = fill_outletCount($session, $pdu, $callback); | ||||
|         } | ||||
|         for (my $outlet =1; $outlet <= $count; $outlet++) | ||||
|         { | ||||
|             my $statstr = outletstat($session, $outlet); | ||||
| @@ -518,6 +624,13 @@ sub process_netcfg { | ||||
|     my $pdu = @$nodes[0]; | ||||
|     my $rsp = {}; | ||||
|  | ||||
|     my $pdutab = xCAT::Table->new('pdu'); | ||||
|     my $pduhash = $pdutab->getNodesAttribs($nodes, ['pdutype']); | ||||
|     unless ($pduhash->{$pdu}->[0]->{pdutype} eq "crpdu") { | ||||
|         xCAT::SvrUtils::sendmsg("This command only supports CONSTELLATION PDU with pdutype=crpdu", $callback,$pdu); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     my $nodetab = xCAT::Table->new('hosts'); | ||||
|     my $nodehash = $nodetab->getNodesAttribs($nodes,['ip','otherinterfaces']); | ||||
|  | ||||
| @@ -526,7 +639,7 @@ sub process_netcfg { | ||||
|     my $discover_ip = $nodehash->{$pdu}->[0]->{otherinterfaces}; | ||||
|     ($exp, $errstr) = session_connect($static_ip, $discover_ip); | ||||
|     if (defined $errstr) { | ||||
|         xCAT::SvrUtils::sendmsg("Failed to connect", $callback); | ||||
|         xCAT::SvrUtils::sendmsg("Failed to connect", $callback,$pdu); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
| @@ -603,8 +716,16 @@ sub process_sshcfg { | ||||
|  | ||||
|     my $nodetab = xCAT::Table->new('hosts'); | ||||
|     my $nodehash = $nodetab->getNodesAttribs($noderange,['ip','otherinterfaces']); | ||||
|      | ||||
|  | ||||
|     my $pdutab = xCAT::Table->new('pdu'); | ||||
|     my $pduhash = $pdutab->getNodesAttribs($noderange, ['pdutype']); | ||||
|  | ||||
|     foreach my $pdu (@$noderange) { | ||||
|         unless ($pduhash->{$pdu}->[0]->{pdutype} eq "crpdu") { | ||||
|             xCAT::SvrUtils::sendmsg("This command only supports CONSTELLATION PDU with pdutype=crpdu", $callback,$pdu); | ||||
|             next; | ||||
|         } | ||||
|  | ||||
|         my $msg = " process_sshcfg"; | ||||
|         xCAT::SvrUtils::sendmsg($msg, $callback, $pdu, %allerrornodes); | ||||
|  | ||||
| @@ -635,6 +756,15 @@ sub process_sshcfg { | ||||
|     return; | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------- | ||||
|  | ||||
| =head3  session_connect  | ||||
|  | ||||
|   open a expect session and connect to CR PDU. | ||||
|  | ||||
| =cut | ||||
|  | ||||
| #------------------------------------------------------- | ||||
| sub session_connect { | ||||
|     my $static_ip   = shift; | ||||
|     my $discover_ip   = shift; | ||||
| @@ -682,7 +812,15 @@ sub session_connect { | ||||
|      return ($ssh); | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------- | ||||
|  | ||||
| =head3  session_exec  | ||||
|  | ||||
|   execute command to CR PDU. | ||||
|  | ||||
| =cut | ||||
|  | ||||
| #------------------------------------------------------- | ||||
| sub session_exec { | ||||
|      my $exp = shift; | ||||
|      my $cmd = shift; | ||||
| @@ -765,11 +903,20 @@ sub process_pdudiscover { | ||||
| sub showMFR { | ||||
|     my $noderange = shift; | ||||
|     my $callback = shift; | ||||
|     my $output; | ||||
|  | ||||
|     my $nodetab = xCAT::Table->new('hosts'); | ||||
|     my $nodehash = $nodetab->getNodesAttribs($noderange,['ip','otherinterfaces']); | ||||
|  | ||||
|     my $pdutab = xCAT::Table->new('pdu'); | ||||
|     my $pduhash = $pdutab->getNodesAttribs($noderange, ['pdutype']); | ||||
|  | ||||
|     foreach my $pdu (@$noderange) { | ||||
|         unless ($pduhash->{$pdu}->[0]->{pdutype} eq "crpdu") { | ||||
|             xCAT::SvrUtils::sendmsg("This command only supports CONSTELLATION PDU with pdutype=crpdu", $callback,$pdu); | ||||
|             next; | ||||
|         } | ||||
|  | ||||
|         # connect to PDU | ||||
|         my $static_ip = $nodehash->{$pdu}->[0]->{ip}; | ||||
|         my $discover_ip = $nodehash->{$pdu}->[0]->{otherinterfaces}; | ||||
| @@ -814,11 +961,20 @@ sub showMFR { | ||||
| sub showMonitorData { | ||||
|     my $noderange = shift; | ||||
|     my $callback = shift; | ||||
|     my $output; | ||||
|  | ||||
|     my $nodetab = xCAT::Table->new('hosts'); | ||||
|     my $nodehash = $nodetab->getNodesAttribs($noderange,['ip','otherinterfaces']); | ||||
|  | ||||
|     my $pdutab = xCAT::Table->new('pdu'); | ||||
|     my $pduhash = $pdutab->getNodesAttribs($noderange, ['pdutype']); | ||||
|  | ||||
|     foreach my $pdu (@$noderange) { | ||||
|         unless ($pduhash->{$pdu}->[0]->{pdutype} eq "crpdu") { | ||||
|             xCAT::SvrUtils::sendmsg("This command only supports CONSTELLATION PDU with pdutype=crpdu", $callback,$pdu); | ||||
|             next; | ||||
|         } | ||||
|  | ||||
|         # connect to PDU | ||||
|         my $static_ip = $nodehash->{$pdu}->[0]->{ip}; | ||||
|         my $discover_ip = $nodehash->{$pdu}->[0]->{otherinterfaces}; | ||||
| @@ -844,5 +1000,264 @@ sub showMonitorData { | ||||
|     } | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------- | ||||
|  | ||||
| =head3  relaystat  | ||||
|  | ||||
|   process individual relay stat for CR PDU. | ||||
|   The OID for 3 relay: | ||||
| 	1.3.6.1.4.1.2.6.262.15.2.13 | ||||
| 	1.3.6.1.4.1.2.6.262.15.2.14 | ||||
| 	1.3.6.1.4.1.2.6.262.15.2.15 | ||||
|  | ||||
| =cut | ||||
|  | ||||
| #------------------------------------------------------- | ||||
| sub relaystat { | ||||
|     my $pdu = shift; | ||||
|     my $relay = shift; | ||||
|     my $snmpcmd = shift; | ||||
|     my $callback = shift; | ||||
|  | ||||
|     my $relayoid = $relay + 12; | ||||
|  | ||||
|     #default pdu snmpv3, won't show up for snmpv1  | ||||
|     my $cmd = "$snmpcmd $pdu 1.3.6.1.4.1.2.6.262.15.2.$relayoid"; | ||||
|          | ||||
|     my $result = xCAT::Utils->runcmd($cmd, 0); | ||||
|     my ($msg,$stat) = split /: /, $result; | ||||
|     if ($stat eq "1" ) { | ||||
|         xCAT::SvrUtils::sendmsg(" relay $relay is on", $callback, $pdu, %allerrornodes); | ||||
|     } elsif ( $stat eq "0" ) { | ||||
|         xCAT::SvrUtils::sendmsg(" relay $relay is off", $callback, $pdu, %allerrornodes); | ||||
|     } else { | ||||
|         xCAT::SvrUtils::sendmsg(" relay $relay is unknown", $callback, $pdu, %allerrornodes); | ||||
|     } | ||||
|  | ||||
|     return; | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------- | ||||
|  | ||||
| =head3  process_powerrelay  | ||||
|  | ||||
|   process relay action for CR PDU. | ||||
|  | ||||
| =cut | ||||
|  | ||||
| #------------------------------------------------------- | ||||
| sub process_powerrelay { | ||||
|     my $request = shift; | ||||
|     my $subreq    = shift; | ||||
|     my $subcmd    = shift; | ||||
|     my $callback = shift; | ||||
|  | ||||
|     my $relay; | ||||
|     my $action; | ||||
|  | ||||
|     my $extrargs  = $request->{arg}; | ||||
|     my @exargs    = ($request->{arg}); | ||||
|     if (ref($extrargs)) { | ||||
|         @exargs = @$extrargs; | ||||
|     } | ||||
|  | ||||
|     my $nodes = $request->{node}; | ||||
|  | ||||
|     foreach my $cmd (@exargs) { | ||||
|         if ($cmd =~ /=/ ) { | ||||
|             my ($key, $value) = split(/=/, $cmd); | ||||
|             $relay = $value; | ||||
|         } else { | ||||
|             $action = $cmd; | ||||
|         } | ||||
|     } | ||||
|     if ( (defined $relay) && (defined $action) ) { | ||||
|         my $relay_count = 1; | ||||
|         foreach my $pdu (@$nodes) { | ||||
|             process_relay($pdu, $action, $callback, $relay, $relay_count); | ||||
|         } | ||||
|     } else { | ||||
|         xCAT::SvrUtils::sendmsg(" This command is not support, please define relay number and action", $callback); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------- | ||||
|  | ||||
| =head3  process_relay  | ||||
|  | ||||
|   process relay action for CR PDU. | ||||
|  | ||||
| =cut | ||||
|  | ||||
| #------------------------------------------------------- | ||||
| sub process_relay { | ||||
|     my $pdu = shift; | ||||
|     my $subcmd = shift; | ||||
|     my $callback = shift; | ||||
|     my $relay_num = shift; | ||||
|     my $relay_count = shift; | ||||
|  | ||||
|     if ( !defined $relay_count ) { | ||||
|         $relay_num = 1; | ||||
|         $relay_count = 3; | ||||
|     } | ||||
|  | ||||
|     my $nodetab = xCAT::Table->new('hosts'); | ||||
|     my $nodehash = $nodetab->getNodeAttribs($pdu,['ip','otherinterfaces']); | ||||
|  | ||||
|     # connect to PDU | ||||
|     my $static_ip = $nodehash->{$pdu}->[0]->{ip}; | ||||
|     my $discover_ip = $nodehash->{$pdu}->[0]->{otherinterfaces}; | ||||
|     my ($session, $errstr) = session_connect($static_ip, $discover_ip); | ||||
|  | ||||
|     my $ret; | ||||
|     my $err; | ||||
|     my $statestr; | ||||
|      | ||||
|  | ||||
|     for (my $i = 0; $i < $relay_count; $i++) { | ||||
|         my $relay = $relay_num; | ||||
|         xCAT::SvrUtils::sendmsg(" power $subcmd for relay $relay_num", $callback,$pdu); | ||||
|         if ($subcmd eq "off") { | ||||
|             relay_action($session, $pdu, $relay, "OFF", $callback); | ||||
|         } elsif ( $subcmd eq "on") { | ||||
|             relay_action($session, $pdu, $relay, "ON", $callback); | ||||
|         } elsif ( $subcmd eq "reset") { | ||||
|             relay_action($session, $pdu, $relay, "OFF", $callback); | ||||
|             relay_action($session, $pdu, $relay, "ON", $callback); | ||||
|         } else { | ||||
|             xCAT::SvrUtils::sendmsg(" subcmd $subcmd is not support", $callback,$pdu); | ||||
|         } | ||||
|         $relay_num++; | ||||
|     } | ||||
|     $session->hard_close(); | ||||
|  | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------- | ||||
|  | ||||
| =head3  realy_action  | ||||
|  | ||||
|   process individual relay action for CR PDU. | ||||
|  | ||||
| =cut | ||||
|  | ||||
| #------------------------------------------------------- | ||||
| sub relay_action { | ||||
|     my $session = shift; | ||||
|     my $pdu = shift; | ||||
|     my $relay = shift; | ||||
|     my $action = shift; | ||||
|     my $callback = shift; | ||||
|  | ||||
|     my ($ret, $err) = session_exec($session, "/dev/shm/bin/PduManager -r $relay -v $action"); | ||||
|     if (defined $err) { | ||||
|         xCAT::SvrUtils::sendmsg("Failed to process relay action: $err", $callback); | ||||
|     } | ||||
|     if (defined $ret) { | ||||
|         xCAT::SvrUtils::sendmsg("$ret", $callback,$pdu); | ||||
|     } | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------- | ||||
|  | ||||
| =head3  process_snmpcfg  | ||||
|  | ||||
|   config snmp and snmpv3 for CR PDU. | ||||
|  | ||||
| =cut | ||||
|  | ||||
| #------------------------------------------------------- | ||||
| sub process_snmpcfg { | ||||
|     my $noderange = shift; | ||||
|     my $subcmd = shift; | ||||
|     my $callback = shift; | ||||
|     my $snmp_conf="/etc/snmp/snmpd.conf"; | ||||
|     my $xCATSettingsSTART="xCAT settings START"; | ||||
|     my $xCATSettingsEND="xCAT settings END"; | ||||
|     my $xCATSettingsInfo="Entries between the START and END lines will be replaced each time by xCAT command"; | ||||
|  | ||||
|  | ||||
|     my $nodetab = xCAT::Table->new('hosts'); | ||||
|     my $nodehash = $nodetab->getNodesAttribs($noderange,['ip','otherinterfaces']); | ||||
|  | ||||
|     my $pdutab = xCAT::Table->new('pdu'); | ||||
|     my $pduhash = $pdutab->getNodesAttribs($noderange, ['pdutype','community','snmpversion','snmpuser','authtype','authkey','privtype','privkey','seclevel']); | ||||
|  | ||||
|     foreach my $pdu (@$noderange) { | ||||
|         unless ($pduhash->{$pdu}->[0]->{pdutype} eq "crpdu") { | ||||
|             xCAT::SvrUtils::sendmsg("This command only supports CONSTELLATION PDU with pdutype=crpdu", $callback,$pdu); | ||||
|             next; | ||||
|         } | ||||
|  | ||||
|         my $community = $pduhash->{$pdu}->[0]->{community}; | ||||
|         my $snmpversion = $pduhash->{$pdu}->[0]->{snmpversion}; | ||||
|         my $snmpuser = $pduhash->{$pdu}->[0]->{snmpuser}; | ||||
|         my $authtype = $pduhash->{$pdu}->[0]->{authtype}; | ||||
|         if (!defined $authtype) { | ||||
|             $authtype="MD5"; | ||||
|         } | ||||
|         my $authkey = $pduhash->{$pdu}->[0]->{authkey}; | ||||
|         my $privtype = $pduhash->{$pdu}->[0]->{privtype}; | ||||
|         if (!defined $privtype) { | ||||
|             $privtype="DES"; | ||||
|         } | ||||
|         my $privkey = $pduhash->{$pdu}->[0]->{privkey}; | ||||
|         if (!defined $privkey) { | ||||
|             if (defined $authkey) { | ||||
|                 $privkey=$authkey; | ||||
|             } | ||||
|         } | ||||
|         my $seclevel = $pduhash->{$pdu}->[0]->{seclevel}; | ||||
|  | ||||
|         # connect to PDU | ||||
|         my $static_ip = $nodehash->{$pdu}->[0]->{ip}; | ||||
|         my $discover_ip = $nodehash->{$pdu}->[0]->{otherinterfaces}; | ||||
|         my ($exp, $errstr) = session_connect($static_ip, $discover_ip); | ||||
|  | ||||
|         my $ret; | ||||
|         my $err; | ||||
|  | ||||
|         ($ret, $err) = session_exec($exp, "sed -i '/$xCATSettingsSTART/,/$xCATSettingsEND/ d' $snmp_conf"); | ||||
|         ($ret, $err) = session_exec($exp, "echo '# $xCATSettingsSTART' >> $snmp_conf"); | ||||
|         ($ret, $err) = session_exec($exp, "echo '# $xCATSettingsInfo' >> $snmp_conf"); | ||||
|         if (defined $community) { | ||||
|             ($ret, $err) = session_exec($exp, "echo 'com2sec readwrite  default        $community' >> $snmp_conf"); | ||||
|         } | ||||
|         #set snmpv3 configuration | ||||
|         if ($snmpversion =~ /3/) { | ||||
|             if ((defined $snmpuser) && (defined $seclevel)) { | ||||
|                 my $msg1; | ||||
|                 if ($seclevel eq "authNoPriv") { | ||||
|                     $msg1 = "createUser $snmpuser $authtype $authkey"; | ||||
|                 } elsif ($seclevel eq "authPriv") { | ||||
|                     $msg1 = "createUser $snmpuser $authtype $authkey $privtype $privkey"; | ||||
|                 } else {   #default to notAuthNoPriv | ||||
|                     $msg1 = "createUser $snmpuser"; | ||||
|                 } | ||||
|                 my $msg2 = "rwuser $snmpuser $seclevel .1.3.6.1.4.1.2.6.262"; | ||||
|                 ($ret, $err) = session_exec($exp, "sed -i '/\"$snmpuser\"/ d' /var/lib/net-snmp/snmpd.conf"); | ||||
|                 ($ret, $err) = session_exec($exp, "echo $msg1 >> $snmp_conf"); | ||||
|                 ($ret, $err) = session_exec($exp, "echo $msg2 >> $snmp_conf"); | ||||
|             } else { | ||||
|                 xCAT::SvrUtils::sendmsg("Need to define user name and security level for snmpv3 configuration", $callback); | ||||
|             } | ||||
|         } | ||||
|         ($ret, $err) = session_exec($exp, "echo '# $xCATSettingsEND' >> $snmp_conf"); | ||||
|  | ||||
|         #need to restart snmpd after config file changes | ||||
|         ($ret, $err) = session_exec($exp, "ps | grep snmpd | grep -v grep | awk '{ print $1}' | xargs kill -9"); | ||||
|         ($ret, $err) = session_exec($exp, "/usr/sbin/snmpd -Lsd -Lf /dev/null -p /var/run/snmpd"); | ||||
|         if (defined $err) { | ||||
|             xCAT::SvrUtils::sendmsg("Failed to configure snmp : $err", $callback); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         $exp->hard_close(); | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| 1; | ||||
|   | ||||
| @@ -1150,6 +1150,9 @@ sub get_switchtype { | ||||
|         $key = $1; | ||||
|         return $xCAT::data::switchinfo::global_switch_type{$key}; | ||||
|     } else { | ||||
|         if (exists($globalopt{pdu})) { | ||||
|             return "irpdu"; | ||||
|         } | ||||
|         return $key; | ||||
|     } | ||||
| } | ||||
| @@ -1190,7 +1193,7 @@ sub xCATdB { | ||||
|         # it's attribute  | ||||
|         ################################################## | ||||
|         if (exists($globalopt{pdu})) { | ||||
|             $ret = xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$host,"groups=$device","ip=$ip","mac=$mac","nodetype=$device","mgt=$device","usercomment=$vendor"] }, $sub_req, 0, 1); | ||||
|             $ret = xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$host,"groups=$device","ip=$ip","mac=$mac","nodetype=$device","mgt=$device","usercomment=$vendor","pdutype=$stype"] }, $sub_req, 0, 1); | ||||
|         } else { | ||||
|             $ret = xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$host,"groups=$device","ip=$ip","mac=$mac","nodetype=$device","mgt=$device","usercomment=$vendor","switchtype=$stype"] }, $sub_req, 0, 1); | ||||
|         } | ||||
| @@ -1286,6 +1289,8 @@ sub format_stanza { | ||||
|         $result .= "\tnodetype=$device\n"; | ||||
|         if (!exists($globalopt{pdu})) { | ||||
|             $result .= "\tswitchtype=$stype\n"; | ||||
|         } else { | ||||
|             $result .= "\tpdutype=$stype\n"; | ||||
|         } | ||||
|     } | ||||
|     return ($result);  | ||||
| @@ -1328,6 +1333,8 @@ sub format_xml { | ||||
|         $result .= "nodetype=$device\n"; | ||||
|         if (!exists($globalopt{pdu})) { | ||||
|             $result .= "switchtype=$stype\n"; | ||||
|         } else { | ||||
|             $result .= "\tpdutype=$stype\n"; | ||||
|         } | ||||
|  | ||||
|         my $href = { | ||||
| @@ -1399,7 +1406,7 @@ sub matchPredefineSwitch { | ||||
|         # only write to xcatdb if -w or --setup option specified | ||||
|         if ( (exists($globalopt{w})) || (exists($globalopt{setup})) ) { | ||||
|             if (exists($globalopt{pdu})) { | ||||
|                 xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$node,"otherinterfaces=$ip",'status=Matched',"mac=$mac","usercomment=$vendor"] }, $sub_req, 0, 1); | ||||
|                 xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$node,"otherinterfaces=$ip",'status=Matched',"mac=$mac","usercomment=$vendor","pdutype=$stype"] }, $sub_req, 0, 1); | ||||
|             } else { | ||||
|                 xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$node,"otherinterfaces=$ip",'status=Matched',"mac=$mac","switchtype=$stype","usercomment=$vendor"] }, $sub_req, 0, 1); | ||||
|             } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user