2012-11-29 21:42:30 +00:00
package xCAT::IMMUtils ;
use xCAT::SvrUtils qw/sendmsg/ ;
use xCAT::SSHInteract ;
2013-01-09 15:37:30 +00:00
use xCAT_plugin::bmcconfig ;
2012-11-29 21:42:30 +00:00
#For IMMs, there are a few contexts where setup is most sensibly done remotely via CLI automation, or must be done remotely.
#If slp driven discovery, this is the sensible path pretty much in all scenarios (rack and flex)
#for bmcsetup, it still makes sense for IBM Flex system servers where the server is forbidden from manipulation local authentication
#data
#setupIMM
#Arguments:
# first argument: the nodename to be managed (*NOT* the IMM, the node managed by the IMM)
# named arguments:
# nodedata - structure containing miscellaneous information about the target IMM. Currently, macaddress is the only member of interest
# skipbmcidcheck - if true will do the ssh in even if the bmcid indicates otherwis. remoteimmsetup context, for example, is better served with this strategy
# skipnetconfig - if true, will not issue ifconfig type commands. In remoteimmsetup, this is handled in the typical bmcsetup way
# callback - function to handle getting output back to client
# cliusername - username to use for ssh (might not match ipmi)
# clipassword - password for cli
# curraddr - current address (in case current address does not match intended address
# example invocation:
# xCAT::IMMUtils::setupIMM($node,nodedata=>$immdata,curraddr=>$addr,cliusername=>$user,clipassword=>$pass,callback=>$callback);
sub setupIMM {
my $ node = shift ;
my % args = @ _ ;
my $ nodedata = $ args { nodedata } ;
my $ callback = $ args { callback } ;
my $ ipmitab = xCAT::Table - > new ( 'ipmi' , - create = > 1 ) ;
2013-06-04 17:07:57 +00:00
# collect the bmc and bmcid attributes from the ipmi table for this bmc
2012-11-29 21:42:30 +00:00
my $ ient = $ ipmitab - > getNodeAttribs ( $ node , [ qw/bmc bmcid/ ] , prefetchcache = > 1 ) ;
2013-06-04 17:07:57 +00:00
# get the ipmi userid and password from the pmi, mp, or passwd table
2012-11-29 21:42:30 +00:00
my $ ipmiauthmap = xCAT::PasswordUtils:: getIPMIAuth ( noderange = > [ $ node ] ) ;
my $ newaddr ;
2013-06-04 17:07:57 +00:00
# if the bmc and bmcid were found
2012-11-29 21:42:30 +00:00
if ( $ ient ) {
my $ bmcid = $ ient - > { bmcid } ;
2013-06-04 17:07:57 +00:00
# if not skip and bmcid was found and its the same as the node's macaddress - then msg and skip
2012-11-29 21:42:30 +00:00
if ( not $ args { skipbmcidcheck } and $ bmcid and $ nodedata - > { macaddress } =~ /$bmcid/ ) {
sendmsg ( "The IMM has been configured (ipmi.bmcid). Skipped." , $ callback , $ node ) ;
return ;
} #skip configuration, we already know this one
2013-06-04 17:07:57 +00:00
# not skipping so save the bmc address from the ipmi table for later
2012-11-29 21:42:30 +00:00
$ newaddr = $ ient - > { bmc } ;
}
my @ ips = ( ) ;
my $ autolla = 0 ;
2013-06-04 17:07:57 +00:00
# if the bmc address was found in the ipmi table and its NOT an IPv6 IP
2012-11-29 21:42:30 +00:00
if ( $ newaddr and not $ newaddr =~ /^fe80:.*%.*/ ) {
2013-06-04 17:07:57 +00:00
# get the ip addresses associated with the bmc ip address in the ipmi table
2012-11-29 21:42:30 +00:00
@ ips = xCAT::NetworkUtils:: getipaddr ( $ newaddr , GetAllAddresses = > 1 ) ;
2013-06-04 17:07:57 +00:00
} else {
# otherwise check if the curraddr passed in is IPv6 LLA then use it
2012-11-29 21:42:30 +00:00
if ( $ args { curraddr } =~ /^fe80:.*%.*/ ) { #if SLP were able to glean an LLA out of this, let's just roll with that result
2013-06-04 17:07:57 +00:00
# set the node bmc attribute to the LLA found and passed in
2012-11-29 21:42:30 +00:00
$ ipmitab - > setNodeAttribs ( $ node , { bmc = > $ args { curraddr } } ) ;
$ autolla = 1 ;
}
}
2013-06-04 17:07:57 +00:00
# if there is not are not ip addresses resolved from the IP in the ipmi bmc ip or there is not a LLA then error and exit
2012-11-29 21:42:30 +00:00
if ( not scalar @ ips and not $ autolla ) {
sendmsg ( ":Cannot find the IP attribute for bmc" , $ callback , $ node ) ;
return ;
}
my $ targips ;
2012-11-29 21:55:41 +00:00
my $ sship = $ args { curraddr } ;
2013-06-04 17:07:57 +00:00
# if the ips resloved from the bmc ip in the ipmi table
2012-11-29 21:42:30 +00:00
if ( scalar ( @ ips ) ) {
$ targips = join ( ',' , @ ips ) ;
2012-11-29 21:55:41 +00:00
unless ( $ sship ) { $ sship = $ ips [ 0 ] ; }
2013-06-04 17:07:57 +00:00
# else if its the LLA ip address passed in
2012-11-29 21:42:30 +00:00
} elsif ( $ autolla ) {
$ targips = $ args { curraddr } ;
}
2013-06-04 17:07:57 +00:00
# Tell admin that configuration is about to begin
2012-11-29 21:42:30 +00:00
sendmsg ( ":Configuration of " . $ node . "[$targips] commencing, configuration may take a few minutes to take effect" , $ callback ) ;
my $ child = fork ( ) ;
if ( $ child ) { return ; }
unless ( defined $ child ) { die "error spawining process" }
#ok, with all ip addresses in hand, time to enable IPMI and set all the ip addresses (still static only, TODO: dhcp
2013-05-17 09:30:50 +00:00
my $ ssh ;
2013-06-04 17:07:57 +00:00
# setup ssh parameters and make initial ssh connection
2013-05-23 08:23:21 +00:00
eval { $ ssh = new xCAT:: SSHInteract ( - username = > $ args { cliusername } ,
- password = > $ args { clipassword } ,
- host = > $ sship ,
- nokeycheck = > 1 ,
- output_record_separator = > "\r" ,
Timeout = > 15 ,
Errmode = > 'return' ,
Prompt = > '/> $/' ) ; } ;
my $ errmsg = $@ ;
2013-06-04 17:07:57 +00:00
# error message and exit on any error on ssh connection
2013-05-23 08:23:21 +00:00
if ( $ errmsg ) {
if ( $ errmsg =~ /Login Failed/ ) {
$ errmsg = "Login failed" ;
} elsif ( $ errmsg =~ /Incorrect Password/ ) {
$ errmsg = "Incorrect Password" ;
} else {
$ errmsg = "Failed" ;
2013-05-17 09:30:50 +00:00
}
2013-05-23 08:23:21 +00:00
sendmsg ( ":$errmsg" , $ callback , $ node ) ;
exit ( 0 ) ;
}
2013-06-04 17:07:57 +00:00
# if ssh connection was good and we have a valid prompt
2012-11-29 21:42:30 +00:00
if ( $ ssh and $ ssh - > atprompt ) { #we are in and good to issue commands
2013-06-04 17:07:57 +00:00
# set access configiuration options to allow bmc to be managed by xcat
2012-11-29 21:42:30 +00:00
$ ssh - > cmd ( "accseccfg -pe 0 -rc 0 -ci 0 -lf 0 -lp 0" ) ; #disable the more insane password rules, this isn't by and large a human used interface
2013-06-04 17:07:57 +00:00
# enable ipmi
2012-11-29 21:42:30 +00:00
$ ssh - > cmd ( "users -1 -n " . $ ipmiauthmap - > { $ node } - > { username } . " -p " . $ ipmiauthmap - > { $ node } - > { password } . " -a super" ) ; #this gets ipmi going
2013-06-04 17:07:57 +00:00
# if we do not have to skip network configuration
2012-11-29 21:42:30 +00:00
unless ( $ args { skipnetconfig } ) {
2013-06-04 17:07:57 +00:00
# process all the IP addresses
2012-11-29 21:42:30 +00:00
foreach my $ ip ( @ ips ) {
2013-06-04 17:07:57 +00:00
# if address is IPv6
2012-11-29 21:42:30 +00:00
if ( $ ip =~ /:/ ) {
$ ssh - > cmd ( "ifconfig eth0 -ipv6static enable -i6 $ip" ) ;
} else {
2013-06-04 17:07:57 +00:00
# resolve the IP network parms
2012-11-29 21:42:30 +00:00
( my $ sip , my $ mask , my $ gw ) = xCAT_plugin::bmcconfig:: net_parms ( $ ip ) ;
my $ cmd = "ifconfig eth0 -c static -i $ip -s $mask" ;
if ( $ gw ) { $ cmd . = " -g $gw" ; }
$ ssh - > cmd ( $ cmd ) ;
}
}
}
2013-06-04 17:07:57 +00:00
# close the ssh session
2012-11-29 21:42:30 +00:00
$ ssh - > close ( ) ;
2013-06-04 17:07:57 +00:00
# update the ipmi table bmc attribute for this node
2012-11-29 21:42:30 +00:00
$ ipmitab - > setNodeAttribs ( $ node , { bmcid = > $ nodedata - > { macaddress } } ) ;
}
2013-05-23 08:23:21 +00:00
sendmsg ( ":Succeeded" , $ callback , $ node ) ;
2012-11-29 21:42:30 +00:00
exit ( 0 ) ;
}
1 ;