diff --git a/xCAT-server/lib/xcat/plugins/switchdiscover.pm b/xCAT-server/lib/xcat/plugins/switchdiscover.pm index 5a84a7978..1b90ea155 100644 --- a/xCAT-server/lib/xcat/plugins/switchdiscover.pm +++ b/xCAT-server/lib/xcat/plugins/switchdiscover.pm @@ -326,7 +326,7 @@ sub process_request { my $req = shift; my $callback = shift; my $sub_req = shift; - + ########################################### # Build hash to pass around ########################################### @@ -472,20 +472,21 @@ sub process_request { my $msg = sprintf $format, $ip, $name, $vendor, $mac; send_msg(\%request, 0, $msg); } + send_msg(\%request, 0,"\n"); } + my ($discoverswitch, $predefineswitch) = matchPredefineSwitch($result, \%request, $sub_req); # writes the data into xCAT db if (exists($globalopt{w})) { send_msg(\%request, 0, "Writing the data into xCAT DB...."); - xCATdB($result, \%request, $sub_req); + xCATdB($discoverswitch, \%request, $sub_req); } if (exists($globalopt{setup})) { - switchsetup($result, \%request, $sub_req); + switchsetup($predefineswitch, \%request, $sub_req); } - return; } @@ -720,6 +721,7 @@ sub nmap_scan { my $mac; if (exists($host->{address})) { my $addr_ref = $host->{address}; + $found = 0; foreach my $addr ( @$addr_ref ) { my $type = $addr->{addrtype}; if ( $type ne "mac" ) { @@ -766,10 +768,10 @@ sub nmap_scan { } } - if (!$osguess_ips) { + if ($osguess_ips) { my $guess_switches = nmap_osguess($request, $osguess_ips); foreach my $guess_mac ( keys %$guess_switches ) { - $switches->{$guess_mac}->{ip} = $guess_switches->{$guess_mac}->{ip};; + $switches->{$guess_mac}->{ip} = $guess_switches->{$guess_mac}->{ip}; $switches->{$guess_mac}->{vendor} = $guess_switches->{$guess_mac}->{vendor}; } } @@ -1199,7 +1201,6 @@ sub xCATdB { $mac=" "; } - ################################################# # use lsdef command to check if this switch is # already in the switch table @@ -1369,13 +1370,9 @@ sub format_xml { } #-------------------------------------------------------------------------------- -=head3 switchsetup +=head3 matchPredefineSwitch find discovered switches with predefine switches for each discovered switches: - 1) matching mac to a predefined node - 2) if get predefined node, config the discovered switch, if failed, update - 'otherinterface' attribute of predefined node - 3) remove hosts record and node definition for the discovered switch Arguments: outhash: a hash containing the switches discovered Returns: @@ -1383,14 +1380,12 @@ sub format_xml { =cut #-------------------------------------------------------------------------------- -sub switchsetup { +sub matchPredefineSwitch { my $outhash = shift; my $request = shift; my $sub_req = shift; - my @switchnode = (); - my $static_ip; - my $discover_switch; - my $nodes_to_config; + my $discoverswitch; + my $configswitch; #print Dumper($outhash); my $macmap = xCAT::MacMap->new(); @@ -1409,22 +1404,38 @@ sub switchsetup { my $node = $macmap->find_mac($mac,0,1); if (!$node) { - send_msg($request, 0, "NO predefined switch matched this switch $dswitch with ip address $ip and mac address $mac"); + send_msg($request, 0, "Switch discovered: $dswitch "); + $discoverswitch->{$mac}->{ip} = $ip; + $discoverswitch->{$mac}->{vendor} = $vendor; + $discoverswitch->{$mac}->{name} = $dswitch; next; } - # get predefine node ip address - $static_ip = xCAT::NetworkUtils->getipaddr($node); 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" ); - } + send_msg($request, 0, "Switch discovered and matched: $dswitch to $node" ); + xCAT::Utils->runxcmd({ command => ['chdef'], arg => ['-t','node','-o',$node,"otherinterfaces=$ip",'status=Matched',"mac=$mac","switchtype=$stype","usercomment=$vendor"] }, $sub_req, 0, 1); - push (@{$nodes_to_config->{$stype}}, $node); + push (@{$configswitch->{$stype}}, $node); } + return ($discoverswitch, $configswitch); +} + +#-------------------------------------------------------------------------------- +=head3 switchsetup + configure the switch + Arguments: + outhash: a hash containing the switches need to configure + Returns: + result: +=cut +#-------------------------------------------------------------------------------- +sub switchsetup { + my $nodes_to_config = shift; + my $request = shift; + my $sub_req = shift; foreach my $mytype (keys %$nodes_to_config) { my $config_script = "$::XCATROOT/share/xcat/scripts/config".$mytype; if (-r -x $config_script) { diff --git a/xCAT-server/share/xcat/scripts/configBNT b/xCAT-server/share/xcat/scripts/configBNT index c2a3f4355..712dcd122 100755 --- a/xCAT-server/share/xcat/scripts/configBNT +++ b/xCAT-server/share/xcat/scripts/configBNT @@ -89,6 +89,10 @@ if ($::SWITCH) { exit(1); } +#get mac address for the switches +my $mactab = xCAT::Table->new("mac"); +my $machash = $mactab->getNodesAttribs(\@nodes,['mac']); + my $switches = join(",",@nodes); my $cmd; my $vlan; @@ -119,11 +123,24 @@ sub config_ip { my @discover_switches; my $nodetab = xCAT::Table->new('hosts'); my $nodehash = $nodetab->getNodesAttribs(\@nodes,['ip','otherinterfaces']); + # get netmask from network table + my $nettab = xCAT::Table->new("networks"); + my @nets; + if ($nettab) { + @nets = $nettab->getAllAttribs('net','mask'); + } + foreach my $switch (@nodes) { print "change $switch to static ip address\n"; + + #makesure host is in the /etc/hosts + $cmd = "makehosts $switch"; + $rc= xCAT::Utils->runcmd($cmd, 0); + my $dip= $nodehash->{$switch}->[0]->{otherinterfaces}; + my $mac= $machash->{$switch}->[0]->{mac}; if (!$dip) { - print "Add otherinterfaces attribute for discover ip: chdef $switch otherinterfaces=x.x.x.x\n"; + print "ERROR: Add otherinterfaces attribute for discover ip: chdef $switch otherinterfaces=x.x.x.x\n"; next; } @@ -139,6 +156,8 @@ sub config_ip { # don't need to set if ip addresses are same if ($dip eq $static_ip) { print "static ip $static_ip and discovery ip $dip is same, will not process command for $switch\n"; + $cmd = "chdef $csw otherinterfaces="; + $rc= xCAT::Utils->runcmd($cmd, 0); next; } @@ -147,7 +166,7 @@ sub config_ip { # if hostnames are same, created different one for discovery name if ($dswitch eq $switch) { - $dswitch=""; + $dswitch="$switch-discovery"; } #if not defined, need to create one for xdsh to use @@ -161,16 +180,46 @@ sub config_ip { $cmd = "makehosts $dswitch"; $rc= xCAT::Utils->runcmd($cmd, 0); - # verify if xdsh works - $cmd = "xdsh $dswitch --devicetype EthSwitch::BNT 'enable;configure terminal;exit' "; + #get netmask + my $mask; + foreach my $net (@nets) { + if (xCAT::NetworkUtils::isInSameSubnet( $net->{'net'}, $static_ip, $net->{'mask'}, 0)) { + $mask=$net->{'mask'}; + last; + } + } + + # For RackSwitch G8124 + if ($mac =~ /fc\:cf\:62/i) { + $cmd="xdsh $dswitch -t 10 --devicetype EthSwitch::BNT 'enable;configure terminal;show interface ip;interface ip-mgmt enable;interface ip-mgmt address $static_ip $mask;exit' "; + } elsif ($mac =~ /6c\:ae\:8b/i){ + print "this is BNT G8264-T switch\n"; + $cmd="xdsh $dswitch -t 10 --devicetype EthSwitch::BNT '/cfg/l3/if 128/maskplen $mask;/cfg/l3/if 128/addr $static_ip;apply' "; + } else { + $cmd="xdsh $dswitch -t 10 --devicetype EthSwitch::BNT 'enable;configure terminal;show interface ip;interface ip 1;ip address $static_ip;exit;exit' "; + } $rc= xCAT::Utils->runcmd($cmd, 0); - if ($::RUNCMD_RC != 0) { - xCAT::MsgUtils->message("E","Couldn't communicate with $dswitch, $dip"); + + # check if static ip address is reachable + my $retry = 0; + my $retry_failed = 1; + while ($retry < 3) { + if (!$p->ping($static_ip)) { + $retry = $retry + 1; + print "sleep 10\n"; + sleep 10; + } else { + $retry_failed = 0; + last; + } + } + print "retry $retry_failed\n"; + if ($retry_failed) { + print "Failed to set up static ip address: $static_ip for $switch\n"; + push (@discover_switches, $dswitch); next; } - $cmd="xdsh $dswitch -t 10 --devicetype EthSwitch::BNT 'enable;configure terminal;show interface ip;interface ip 1;ip address $static_ip;exit;exit' "; - $rc= xCAT::Utils->runcmd($cmd, 0); - print "finish setup static ip address for $switch\n"; + push (@discover_switches, $dswitch); push (@config_switches, $switch); } @@ -194,15 +243,21 @@ sub config_hostname { my @config_switches; my $switchtab = xCAT::Table->new('switches'); my $switchhash = $switchtab->getNodesAttribs(\@nodes,['sshusername','sshpassword']); + foreach my $switch (@nodes) { my $user= $switchhash->{$switch}->[0]->{sshusername}; my $pwd= $switchhash->{$switch}->[0]->{sshpassword}; + my $mac= $machash->{$switch}->[0]->{mac}; if ((!$user)||(!$pwd)) { print "switch ssh username or password is not define, add default one\n"; $cmd = "chdef $switch username=root password=admin"; $rc= xCAT::Utils->runcmd($cmd, 0); } - $cmd="xdsh $switch --devicetype EthSwitch::BNT 'enable;configure terminal;hostname $switch;write memory' "; + if ($mac =~ /6c\:ae\:8b/i){ + $cmd="xdsh $switch --devicetype EthSwitch::BNT '/cfg/sys/hprompt enable;/cfg/sys/ssnmp/name $switch;apply' "; + } else { + $cmd="xdsh $switch --devicetype EthSwitch::BNT 'enable;configure terminal;hostname $switch;write memory;exit' "; + } $rc= xCAT::Utils->runcmd($cmd, 0); if ($::RUNCMD_RC != 0) { xCAT::MsgUtils->message("E","Failed to setup hostname for $switch"); @@ -235,7 +290,7 @@ sub config_snmp { $snmp_passwd = $::PASSWORD; } else { # Need a special character - $snmp_passwd = "xcatadminpassw0rd\@snmp\r"; + $snmp_passwd = "xcatadminpassw1rd\@snmp\r"; } if ($::GROUP) { $snmp_group = $::GROUP; @@ -245,6 +300,16 @@ sub config_snmp { foreach my $switch (@nodes) { my $mysw; + + my $mac= $machash->{$switch}->[0]->{mac}; + if ($mac =~ /6c\:ae\:8b/i){ + my $rc = config_G8264($switch,$snmp_user,$snmp_passwd,$snmp_group); + if ($rc == 0){ + push (@config_switches, $switch); + } + next; + } + my $enable_cmd="enable\r"; my $config_cmd="configure terminal\r"; my $exit_cmd="exit\r"; @@ -351,11 +416,78 @@ sub config_snmp { if (@config_switches) { #update switch status my $csw = join(",",@config_switches); - $cmd = "chdef $csw status=switch_configed snmpversion=3 snmpauth=sha snmpusername=$snmp_user snmppassword=$snmp_passwd"; + $cmd = "chdef $csw status=switch_configed snmpversion=3 snmpauth=sha snmpprivacy=authNoPriv snmpusername=$snmp_user snmppassword=$snmp_passwd"; $rc= xCAT::Utils->runcmd($cmd, 0); } } +sub config_G8264 { + my $switch = shift; + my $snmp_user = shift; + my $snmp_passwd = shift; + my $snmp_group = shift; + my $cmd; + + $cmd="xdsh $switch --devicetype EthSwitch::BNT '/cfg/sys/ssnmp/snmpv3/usm 5/name $snmp_user;/cfg/sys/ssnmp/snmpv3/usm 5/auth sha;/cfg/sys/ssnmp/snmpv3/usm 5/priv none;/cfg/sys/ssnmp/snmpv3/group 5/model usm;/cfg/sys/ssnmp/snmpv3/group 5/uname $snmp_user;/cfg/sys/ssnmp/snmpv3/group 5/gname $snmp_group;/cfg/sys/ssnmp/snmpv3/access 5/name $snmp_group;/cfg/sys/ssnmp/snmpv3/access 5/model usm;/cfg/sys/ssnmp/snmpv3/access 5/level authNoPriv;apply' "; + + $rc= xCAT::Utils->runcmd($cmd, 0); + + #use expect to set password + my $mysw = new Expect; + my $timeout = 20; + my $login_cmd = "telnet $switch\r"; + my $passwd = "admin\r"; + my $pwd_prompt = "password: "; + my $main_prompt="Main#"; + my $authpw_cmd = "/cfg/sys/ssnmp/snmpv3/usm 5/authpw\r"; + + $mysw->slave->stty(qw(sane -echo)); + + unless ($mysw->spawn($login_cmd)) + { + $mysw->soft_close(); + print "Unable to run $login_cmd\n"; + return 1; + } + my @result = $mysw->expect( + $timeout, + [ + $pwd_prompt, + sub { + $mysw->clear_accum(); + $mysw->send("$passwd\r"); + $mysw->clear_accum(); + $mysw->exp_continue(); + } + ], + [ + "-re", $main_prompt, + sub { + $mysw->clear_accum(); + $mysw->send($authpw_cmd); + $mysw->send($passwd); + $mysw->send($snmp_passwd); + $mysw->send($snmp_passwd); + sleep 1; + $mysw->clear_accum(); + $mysw->send("apply\r"); + $mysw->send("save\r"); + $mysw->send("y\r"); + $mysw->send("exit\r"); + } + ], + ); + if (defined($result[1])) + { + my $errmsg = $result[1]; + $mysw->soft_close(); + print "Failed expect command $errmsg\n"; + return 1; + } + $mysw->soft_close(); + return 0; +} + sub config_vlan { if ($::PORT) { $port = $::PORT;