2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-05-29 09:13:08 +00:00

Switch-based switch discovery for BNT and Mellanox

This commit is contained in:
Casandra Qiu 2016-07-11 17:03:00 -04:00
parent 72571f4444
commit 91d803ec38
3 changed files with 527 additions and 1 deletions

View File

@ -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;

View File

@ -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";
}

View File

@ -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";
}