diff --git a/xCAT-server/lib/xcat/plugins/switchdiscover.pm b/xCAT-server/lib/xcat/plugins/switchdiscover.pm index f9f571909..e789b577f 100644 --- a/xCAT-server/lib/xcat/plugins/switchdiscover.pm +++ b/xCAT-server/lib/xcat/plugins/switchdiscover.pm @@ -14,11 +14,13 @@ use xCAT::NodeRange; use xCAT::NetworkUtils; use xCAT::Utils; use xCAT::SvrUtils; +use xCAT::MacMap; use xCAT::Table; use XML::Simple; no strict; use Data::Dumper; use Socket; +use Expect; #global variables for this module my %globalopt; @@ -37,6 +39,7 @@ my %global_switch_type = ( cisco => "Cisco", BNT => "BNT", Blade => "BNT", + G8052 => "BNT", Mellanox => "Mellanox", mellanox => "Mellanox", MLNX => "Mellanox", @@ -153,7 +156,7 @@ sub parse_args { # Process command-line flags ############################################# if (!GetOptions( \%opt, - qw(h|help V|Verbose v|version x z w r n range=s s=s))) { + qw(h|help V|Verbose v|version x z w r n range=s s=s setup))) { return( usage() ); } @@ -261,6 +264,14 @@ sub parse_args { $globalopt{n} = 1; } + ######################################################### + # setup discover switch + ######################################################### + if ( exists( $opt{setup} )) { + $globalopt{setup} = 1; + } + + return; } @@ -460,6 +471,16 @@ sub process_request { xCATdB($result, \%request, $sub_req); } + if (exists($globalopt{setup})) { + #discovered switches need to write to xcatdb before we can set them up + # It will be removed once we found predefine switch. + if (!exists($globalopt{w})) { + xCATdB($result, \%request, $sub_req); + } + switchsetup($result, \%request, $sub_req); + } + + return; } @@ -1328,5 +1349,171 @@ sub format_xml { return ($xml); } +#-------------------------------------------------------------------------------- +=head3 switchsetup + find discovered switches with predefine switches + Arguments: + outhash: a hash containing the switches discovered + Returns: + result: +=cut +#-------------------------------------------------------------------------------- + +sub switchsetup { + my $outhash = shift; + my $request = shift; + my $sub_req = shift; + my $ret; + my @switchnode = (); + my $switchInfo; + my $output; + my $dshcmd; + + #print Dumper($outhash); + my $macmap = xCAT::MacMap->new(); + + ################################################# + # call find_mac to match pre-defined switch and + # discovery switch + ################################################## + + foreach my $mac ( keys %$outhash ) { + my $ip = $outhash->{$mac}->{ip}; + my $vendor = $outhash->{$mac}->{vendor}; + my $node = $macmap->find_mac($mac,0); + + # get predefine node ip address + $static_ip = xCAT::NetworkUtils->getipaddr($node); + + # issue makehosts so we can use xdsh + my $dswitch = get_hostname($outhash->{$mac}->{name}, $ip); + + + #add discovered switch to /etc/hosts + $output = xCAT::Utils->runxcmd({command => ["makehosts"], + node =>[$dswitch]}, $sub_req, 0, 1); + + #run xdsh command to set discover ip address to static ip address + #each switch type has different CLI for setup ip address + my $stype = get_switchtype($vendor); + + if (exists($globalopt{verbose})) { + send_msg($request, 0, "Found Discovery switch $dswitch, $ip, $mac with predefine switch $node, $static_ip $stype switch\n" ); + } + + if ( $stype =~ /BNT/ ) { + # BNT switches + #xdsh switch-192-168-5-152 --devicetype EthSwitch::BNT + # "enable;configure terminal;show interface ip;interface ip 1;ip address 192.168.5.22" + $dshcmd="enable;configure terminal;show interface ip;interface ip 1;ip address $static_ip"; + $output = xCAT::Utils->runxcmd({command => ["xdsh"], + node =>[$dswitch], + arg => ["--devicetype", "EthSwitch::BNT", "$dshcmd"] }, $sub_req, 0, 1); + #send_msg($request, 0, Dumper($output)); + + #set up hostname + $dshcmd="enable;configure terminal;hostname $node;write memory"; + $output = xCAT::Utils->runxcmd({command => ["xdsh"], + node =>[$node], + arg => ["--devicetype", "EthSwitch::BNT", "$dshcmd"] }, $sub_req, 0, 1); + } + elsif ( $stype =~ /Mellanox/ ) { + #set static ip address the mgmt0, we don't have EthSwitch yet, will use IBSwitch for now + #NOTE: this expect routine will timeout after set up address + + my $myexp = new Expect; + my $timeout = 10; + my $login_cmd = "ssh -ladmin $dswitch\r"; + my $first_prompt = "^.*>"; + my $config_prompt="^.*#"; + my $cfg_ip="mgmt0\r"; + my $cfg_ip="no interface mgmt0 dhcp\r"; + my $cfg_ip1="interface mgmt0 ip address $static_ip 255.255.0.0\r"; + + unless ($myexp->spawn($login_cmd)) + { + $myexp->soft_close(); + send_msg($request, 0, "Unable to run $login_cmd\n"); + next; + } + my @result = $myexp->expect( + $timeout, + [ + $first_prompt, + sub { + $myexp->clear_accum(); + $myexp->send("enable\r"); + $myexp->clear_accum(); + $myexp->send("configure terminal\r"); + $myexp->clear_accum(); + $myexp->exp_continue(); + } + ], + [ + "-re", $config_prompt, + sub { + $myexp->clear_accum(); + $myexp->send($cfg_ip); + $myexp->send($cfg_ip1); + $myexp->clear_accum(); + $myexp->send("configuration write\r"); + $myexp->send("exit\r"); + $myexp->send("exit\r"); + } + ], + ); + if (defined($result[1])) + { + my $errmsg = $result[1]; + $myexp->soft_close(); + send_msg($request,0,"Failed expect command $errmsg\n"); + } + + + $myexp->soft_close(); + + #set up hostname + $dshcmd="enable;configure terminal;hostname $node;configuration write"; + $output = xCAT::Utils->runxcmd({command => ["xdsh"], + node =>[$node], + arg => ["-l", "admin", "--devicetype", "IBSwitch::Mellanox", "$dshcmd"] }, $sub_req, 0, 1); + } + else { + send_msg($request, 0, "the switch type $stype is not support\n"); + } + + #after switch ip address is setup to static ip + #remove discover switch definition + if (exists($globalopt{verbose})) { + send_msg($request, 0, "remove discover switch $dswitch from xCAT"); + } + $output = xCAT::Utils->runxcmd({command => ["makehosts"], + node =>[$dswitch], + arg => ['-d'] }, $sub_req, 0, 1); + + my $ccmd = "rmdef $dswitch"; + $output = xCAT::Utils->runcmd($ccmd, 0); + #send_msg($request, 0, Dumper($output)); + + #add mac to predefine switch + if (exists($globalopt{verbose})) { + send_msg($request, 0, "Update Mac address for switch $node"); + } + + my $mactab = xCAT::Table->new('mac'); + my $upmac; + if ($mactab) { + $upmac->{$node}->{mac} = $mac; + $mactab->setNodesAttribs($upmac); + } + + } + + return; + + +} + + 1; diff --git a/xCAT-server/share/xcat/tools/configBNT b/xCAT-server/share/xcat/tools/configBNT new file mode 100755 index 000000000..80bd15bb8 --- /dev/null +++ b/xCAT-server/share/xcat/tools/configBNT @@ -0,0 +1,224 @@ +#!/usr/bin/env perl + +#--------------------------------------------------------- +# Configure Ethnet BNT switches +#--------------------------------------------------------- + +use strict; +use Getopt::Long; +use Expect; + +my $args = join ' ', @ARGV; +$::command = "$0 $args"; + +Getopt::Long::Configure("bundling"); +$Getopt::Long::ignorecase = 0; + + +#--------------------------------------------------------- +#Main + +# parse the options +if ( + !GetOptions( + 'h|help' => \$::HELP, + 'r|range=s' => \$::SWITCH, + 'p|port=s' => \$::PORT, + 'v|vlan=s' => \$::VLAN, + 'u|user=s' => \$::USER, + 'w|password=s' => \$::PASSWORD, + 'g|group=s' => \$::GROUP, + 'snmp' => \$::SNMP, + ) + ) +{ + &usage; + exit(1); +} + +# display the usage if -h or --help is specified +if ($::HELP) +{ + &usage; + exit(0); +} + +my $switch; +if ($::SWITCH) +{ + $switch = $::SWITCH; +} else { + &usage; + exit(1); +} + +my $cmd; + +#default root/password and protcol for BNT switch +my $cmd = `chdef $switch protocol=telnet username=root password=admin`; + +my $vlan; +my $port; +if ($::VLAN) +{ + if ($::PORT) { + $port = $::PORT; + } else { + print "Need port number to set up VLAN\n"; + &usage; + exit(1); + } + $vlan = $::VLAN; + print "Tagging VLAN=$vlan for $switch port $port\n"; + #create vlan + #tagged vlan + $cmd = `xdsh $switch --devicetype EthSwitch::BNT "enable;configure terminal;vlan $vlan;exit;interface port $port;switchport mode trunk;switchport trunk allowed vlan $vlan;write memory;exit;exit"`; +} + +#setup secure SNMP v3 +if ($::SNMP){ + my $mysw; + my $enable_cmd="enable\r"; + my $config_cmd="configure terminal\r"; + my $exit_cmd="exit\r"; + + my $pwd_prompt = "password: "; + my $sw_prompt = "$switch>"; + my $enable_prompt="$switch#"; + my $config_prompt="^.*\\\(config\\\)\#"; + + $mysw = new Expect; + my $timeout = 20; + my $login_cmd = "telnet $switch\r"; + my $passwd = "admin\r"; + my $snmp_user; + my $snmp_passwd; + my $snmp_group; + if ($::USER) { + $snmp_user = $::USER; + } else { + $snmp_user = "xcatadmin\r"; + } + if ($::PASSWORD) { + $snmp_passwd = $::PASSWORD; + } else { + # Need a special character + $snmp_passwd = "xcatadminpassw0rd\@snmp\r"; + } + if ($::GROUP) { + $snmp_group = $::GROUP; + } else { + $snmp_group = "xcatgroup\r"; + } + print "Setup SNMP server for user=$snmp_user, password=$snmp_passwd, group=$snmp_group\n"; + #create a SNMP user + my $cfg_user1="snmp-server user 5 name $snmp_user\r"; + my $cfg_user2="snmp-server user 5 authentication-protocol sha authentication-password\r"; + #create a SNMP group + my $cfg_group1="snmp-server group 5 group-name $snmp_group\r"; + my $cfg_group2="snmp-server group 5 user-name $snmp_user\r"; + my $cfg_group3="snmp-server group 5 security usm\r"; + #Add access permission + my $cfg_access1="snmp-server access 5 name $snmp_group\r"; + my $cfg_access2="snmp-server access 5 level authNoPriv\r"; + my $cfg_access3="snmp-server access 5 security usm\r"; + my $cfg_access4="snmp-server access 5 read-view iso\r"; + + $mysw->slave->stty(qw(sane -echo)); + + unless ($mysw->spawn($login_cmd)) + { + $mysw->soft_close(); + print "Unable to run $login_cmd\n"; + next; + } + my @result = $mysw->expect( + $timeout, + [ + $pwd_prompt, + sub { + $mysw->clear_accum(); + $mysw->send("$passwd\r"); + $mysw->clear_accum(); + $mysw->exp_continue(); + } + ], + [ + "-re", $sw_prompt, + sub { + #print "$switch: sending enable command: $enable_cmd\n"; + $mysw->clear_accum(); + $mysw->send($enable_cmd); + $mysw->exp_continue(); + } + ], + [ + "-re", $enable_prompt, + sub { + #print "$switch: sending config command: $config_cmd\n"; + $mysw->clear_accum(); + $mysw->send($config_cmd); + $mysw->exp_continue(); + } + ], + [ + "-re", $config_prompt, + sub { + $mysw->clear_accum(); + $mysw->send($cfg_user1); + $mysw->send($cfg_user2); + $mysw->send($passwd); + $mysw->send($snmp_passwd); + $mysw->send($snmp_passwd); + sleep 1; + $mysw->clear_accum(); + # create snmp group + $mysw->send($cfg_group1); + $mysw->send($cfg_group2); + $mysw->send($cfg_group3); + $mysw->clear_accum(); + $mysw->send($cfg_access1); + $mysw->send($cfg_access2); + $mysw->send($cfg_access3); + $mysw->send($cfg_access4); + $mysw->clear_accum(); + $mysw->send("write memory\r"); + $mysw->send($exit_cmd); + $mysw->send($exit_cmd); + } + ], + ); + ########################################## + # Expect error - report and quit + ########################################## + if (defined($result[1])) + { + my $errmsg = $result[1]; + $mysw->soft_close(); + print "Failed expect command $errmsg\n"; + exit(1); + } + $mysw->soft_close(); + + +} + +#--------------------------------------------------------- + +=head3 usage + + Displays message for -h option + +=cut + +#--------------------------------------------------------- +sub usage +{ + print "Usage: + configBNT [-?│-h│--help] + configBNT [--range switchnames] [-p|--port port] [-v|--vlan vlan] + configBNT [--range switchnames] [--snmp] [-u|--user snmp_user] [-w|--password snmp_password] [-g|--group snmp_group] + \n"; +} + + diff --git a/xCAT-server/share/xcat/tools/configMellanox b/xCAT-server/share/xcat/tools/configMellanox new file mode 100755 index 000000000..be79c17a4 --- /dev/null +++ b/xCAT-server/share/xcat/tools/configMellanox @@ -0,0 +1,115 @@ +#!/usr/bin/env perl + +#--------------------------------------------------------- +# Configure Ethnet Mellonax switches +#--------------------------------------------------------- + +use strict; +use Getopt::Long; +use Expect; + +my $args = join ' ', @ARGV; +$::command = "$0 $args"; + +Getopt::Long::Configure("bundling"); +$Getopt::Long::ignorecase = 0; + + +#--------------------------------------------------------- +#Main + +# parse the options +if ( + !GetOptions( + 'h|help' => \$::HELP, + 'r|range=s' => \$::SWITCH, + 'u|user=s' => \$::USER, + 'i|ip=s' => \$::IP, + ) + ) +{ + &usage; + exit(1); +} + +# display the usage if -h or --help is specified +if ($::HELP) +{ + &usage; + exit(0); +} + +my $switch; +if ($::SWITCH) +{ + $switch = $::SWITCH; +} else { + &usage; + exit(1); +} + +my $user; + +if ($::USER) +{ + $user = $::USER; +} else { + &usage; + exit(1); +} + +my $ip; +if ($::IP) +{ + $ip = $::IP; +} else { + &usage; + exit(1); +} + + +my $cmd; + +#default root/password and protcol for Mellonax switch +$cmd = `chtab switch=$switch switches.sshusername=$user`; +print $cmd; + +#call rspconfig command to setup switch +#enable ssh +$cmd=`rscpconfig $switch sshcfg=enable`; +print $cmd; + +#enable snmp function on the switch +$cmd=`rscpconfig $switch snmpcfg=enable`; +print $cmd; + +#enable the snmp trap +$cmd=`rscpconfig $switch alert=enable`; +print $cmd; + +#Logging destination: +$cmd=`rscpconfig $switch logdest=$ip`; +print $cmd; + +#config ntp +$cmd = `xdsh $switch -l $user --devicetype IBSwitch::Mellanox "enable;configure terminal;ntp enable;ntpdate $ip; ntp server $ip;configuration write;show ntp" `; +print $cmd; + +#--------------------------------------------------------- + +=head3 usage + + Displays message for -h option + +=cut + +#--------------------------------------------------------- +sub usage +{ + print "Usage: + configMellonax [-?│-h│--help] + configMellonax [--range switchnames] [-u|--user sshusername] [-i|--ip xcatMN_ip_address] + \n"; +} + +