2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-05-23 20:22:05 +00:00
2016-08-09 16:54:08 -04:00

372 lines
11 KiB
Perl
Executable File

#!/usr/bin/env perl
#---------------------------------------------------------
# Configure Ethnet BNT switches
#---------------------------------------------------------
BEGIN
{
$::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
$::XCATDIR = $ENV{'XCATDIR'} ? $ENV{'XCATDIR'} : '/etc/xcat';
}
use lib "$::XCATROOT/lib/perl";
use strict;
use Socket;
use Getopt::Long;
use Expect;
use xCAT::Usage;
use xCAT::NodeRange;
use xCAT::NetworkUtils;
use xCAT::Utils;
use xCAT::Table;
use xCAT::MsgUtils;
Getopt::Long::Configure("bundling");
$Getopt::Long::ignorecase = 0;
#global variables
my @nodes;
my @filternodes;
#---------------------------------------------------------
#Main
# parse the options
if (
!GetOptions(
'h|help' => \$::HELP,
'switches=s' => \$::SWITCH,
'port=s' => \$::PORT,
'vlan=s' => \$::VLAN,
'user=s' => \$::USER,
'password=s' => \$::PASSWORD,
'group=s' => \$::GROUP,
'snmp' => \$::SNMP,
'ip' => \$::IP,
'name' => \$::NAME,
'all' => \$::ALL,
)
)
{
&usage;
exit(1);
}
# display the usage if -h or --help is specified
if ($::HELP)
{
&usage;
exit(0);
}
if ($::SWITCH) {
my @filternodes = xCAT::NodeRange::noderange( $::SWITCH );
if (nodesmissed) {
my $nodenotdefined = join(',', nodesmissed);
xCAT::MsgUtils->message("I","The following nodes are not defined in xCAT DB: $nodenotdefined");
}
# check switch type
my $switchestab = xCAT::Table->new('switches');
my $switches_hash = $switchestab->getNodesAttribs(\@filternodes,['switchtype']);
foreach my $fsw (@filternodes) {
if (($switches_hash->{$fsw}->[0]->{switchtype}) =~ /BNT/) {
push @nodes, $fsw;
} else {
xCAT::MsgUtils->message("E","The $fsw is not BNT switch, will not config");
}
}
unless (@nodes) {
xCAT::MsgUtils->message("E","No Valid Switch to process");
exit(1);
}
} else {
xCAT::MsgUtils->message("E","Invalid flag, please provide switches with --switches");
&usage;
exit(1);
}
my $switches = join(",",@nodes);
my $cmd;
my $vlan;
my $port;
my $sub_req;
my $rc;
if (($::IP) || ($::ALL))
{
config_ip();
}
if (($::NAME) || ($::ALL))
{
config_hostname();
}
if (($::SNMP) || ($::ALL))
{
config_snmp();
}
if ($::VLAN)
{
config_vlan();
}
sub config_ip {
my @config_switches;
my @discover_switches;
my $nodetab = xCAT::Table->new('hosts');
my $nodehash = $nodetab->getNodesAttribs(\@nodes,['ip','otherinterfaces']);
foreach my $switch (@nodes) {
print "change $switch to static ip address\n";
my $dip= $nodehash->{$switch}->[0]->{otherinterfaces};
my $static_ip= $nodehash->{$switch}->[0]->{ip};
#get hostname
my $dswitch = xCAT::NetworkUtils->gethostname($dip);
#if not defined, need to create one for xdsh to use
if (!$dswitch) {
my $ip_str = $dip;
$ip_str =~ s/\./\-/g;
$dswitch = "switch-$ip_str";
}
$cmd = "chdef -t node -o $dswitch groups=switch ip=$dip switchtype=BNT username=root password=admin protocol=telnet nodetype=switch";
$rc= xCAT::Utils->runcmd($cmd, 0);
$cmd = "makehosts $dswitch";
$rc= xCAT::Utils->runcmd($cmd, 0);
# verify if xdsh works
$cmd = "xdsh $dswitch --devicetype EthSwitch::BNT 'enable;configure terminal;exit' ";
$rc= xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0) {
xCAT::MsgUtils->message("E","Couldn't communicate with $dswitch, $dip");
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);
}
if (@config_switches) {
#update switch status
my $csw = join(",",@config_switches);
$cmd = "chdef $csw status=ip_configed otherinterfaces=";
$rc= xCAT::Utils->runcmd($cmd, 0);
}
if (@discover_switches) {
my $dsw = join(",",@discover_switches);
#remove discover switch from xCATdb and /etc/hosts
$cmd = "makehosts -d $dsw";
$rc= xCAT::Utils->runcmd($cmd, 0);
$cmd = "rmdef $dsw";
$rc= xCAT::Utils->runcmd($cmd, 0);
}
}
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};
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' ";
$rc= xCAT::Utils->runcmd($cmd, 0);
if ($::RUNCMD_RC != 0) {
xCAT::MsgUtils->message("E","Failed to setup hostname for $switch");
next;
}
push (@config_switches, $switch);
}
if (@config_switches) {
#update switch status
my $csw = join(",",@config_switches);
$cmd = "chdef $csw status=hostname_configed" ;
$rc= xCAT::Utils->runcmd($cmd, 0);
}
}
#setup secure SNMP v3
sub config_snmp {
my $snmp_user;
my $snmp_passwd;
my $snmp_group;
my @config_switches;
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";
}
foreach my $switch (@nodes) {
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";
print "Setup SNMP server for $switch\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 {
$mysw->clear_accum();
$mysw->send($enable_cmd);
$mysw->exp_continue();
}
],
[
"-re", $enable_prompt,
sub {
$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();
push (@config_switches, $switch);
}
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";
$rc= xCAT::Utils->runcmd($cmd, 0);
}
}
sub config_vlan {
if ($::PORT) {
$port = $::PORT;
} else {
&usage;
exit(1);
}
$vlan = $::VLAN;
print "Tagging VLAN=$vlan for $switches port $port\n";
#create vlan, tagged vlan
$cmd = `xdsh $switches --devicetype EthSwitch::BNT "enable;configure terminal;vlan $vlan;exit;interface port $port;switchport mode trunk;switchport trunk allowed vlan $vlan;write memory;exit;exit"`;
}
#---------------------------------------------------------
=head3 usage
Displays message for -h option
=cut
#---------------------------------------------------------
sub usage
{
print "Usage:
configBNT [-?│-h│--help]
configBNT [--switches switchnames] [--all]
configBNT [--switches switchnames] [--ip]
configBNT [--switches switchnames] [--name ]
configBNT [--switches switchnames] [--snmp] [--user snmp_user] [--password snmp_password] [--group snmp_group]
configBNT [--switches switchnames] [--port port] [--vlan vlan]
\n";
}