#!/usr/bin/perl use Net::Telnet; # # sw-alicheck # This script produces a report of the switchshow and alishow output # from a list of brocade switches. The value of the script is that # it merges the alishow and switchshow output. This makes it easier # to spot WWNs that are connected to the switch without having aliases # and spot aliases that are no longer connected to the switch. Those # instances could either be the result of obsolete alias entries, or # failed connections to the switches. # # NOTE: YOU MUST EDIT THIS SCRIPT TO INCLUDE YOUR OWN USER ID, # PASSWORD, AND SWITCH LIST. # # History: # V1.0 Fall 2010 Andy Welter. Initial version. # V1.1 Dec 2010 Andy Welter. Add comments, filter out unlicensed ports. # V1.2 Jan 2011 Andy Welter. Add support for NPIV connections # V1.3 Jan 2011 Andy Welter. Add support for cascaded switches. # # # to send commands use # $telnet->print('somecommand'); # $output=$telnet->waitfor('/\$ /'); # or # $output=$telnet->cmd ('somecommand'); # use Getopt::Std; if ( getopts ('s:u:p:c:h:i') == 0) { print "$usage\n"; exit 1; }; sub sort_by_value { local(*x) = @_; sub _by_value { $x{$a} cmp $x{$b}; } sort _by_value keys %x; } # # read the aliases from the switch and store them in a hash. sub aliget { # # some of the cfg, zone, and alias data is spread out across multiple lines. # we want each zone or alias to be on the same line. # # The last line is going to be a command prompt. # the $lastline logic is what keeps us from printing that. # my ($host,@output)=@_; $name=""; %alilist=(); foreach $_ (@output) { chomp; # get rid of leading white space s/^\s+//g; # stop processing alias $name if we see a item if (m/zone:|cfg:|configuration:/) { $name=""; } elsif ( m/alias:/) { # we have a new alias name, process it ($type,$name,$wwids)=split /\s+/; # look for wwids foreach $wwid (split /\s+/,$wwids) { if ($wwid=~m/..:..:..:..:..:..:..:../) { $alilist{$wwid}=$name; }; }; } elsif (m/..:..:..:..:..:..:..:../) { # found a wwid. Add it to the alias list if we are working on a $name $wwid=$_; if ($name ne "" ) { $alilist{$wwid}=$name; }; }; }; }; # # get list of WWIDs on an NPIV device sub npivget { # # This assumes that the telnet connection is still active. ($port)=@_; my $line; my $wwidlist=(); my (@output) = $telnet->cmd ("portshow $port"); foreach $line (@output) { if ($line=~m/^portWwn of device/) { # start scanning for WWNs $startscan=1; } else { if ( $startscan == 1) { # process WWNs until we run out of them if ($line=~m/..:..:..:..:..:..:..:../) { $line=~s/\s+//g; push @wwidlist, ($line); } else { $startscan=0; }; }; }; }; return @wwidlist; }; # # Display the switch status and determine which WWIDs are logged into each port. sub swget { # # for each port with a connected WWID, record the port number, and print # the alias for that WWID. Print a warning if no alias is found for the WWID. my ($host,@output)=@_; $name=""; foreach $_ (@output) { chomp; # ignore switch ports with no module. if ( ! m/No POD Lic/ ) { @wwidlist=(); print "$_"; @line=split /\s+/; if ( m/NPIV/ ) { # an NPIV device is on this port. get the list of WWIDs @wwidlist=npivget($line[1]); } else { # regular device with one WWID if ($line[$#line]=~m/..:..:..:..:..:..:..:../ && $line[0] ne "switchWwn:") { @wwidlist=($line[$#line]); }; }; foreach $wwid (@wwidlist) { $portlist{$wwid}=$host . "-" . $line[1]; if ( $alilist{$wwid} eq "" ) { print "NO-ALIAS "; } else { print "$alilist{$wwid} "; }; }; print "\n"; }; }; }; $user=$opt_u; $passwd=$opt_p; $cmd=$opt_c; if ( $opt_h eq "" ) { $opt_h=24; }; # # EDIT SWITCH LIST HERE if ( $opt_s eq "" ) { @fablist=("fab-a-sw1,fab-a-sw2,fab-a-sw3", "fab-b-sw1,fab-b-sw2,fab-b-sw3"); } else { @fablist=split /\s+/,$opt_s; }; # # EDIT USER ID HERE if ( $user eq "" ) { $user="admin"; }; # # EDIT PASSWORD HERE if ( $passwd eq "" ) { $passwd="myVerySecurePassword"; }; if ( $cmd eq "" ) { $cmd="zoneshow"; }; @ltime=localtime (time()); $date=sprintf ("%d/%02d/%02d-%02d:%02d:%02d", $ltime[5]+1900,$ltime[4]+1,$ltime[3],$ltime[2],$ltime[1],$ltime[0]); foreach $fabric (@fablist) { %portlist=(); @hostlist=split /,/,$fabric; foreach $host (@hostlist) { $telnet = new Net::Telnet (Timeout=>20, Prompt=>'/\> /', Errmode=>'return'); print "\n\n###\n### $host\n###\n"; if ($telnet->open ($host)) { if ($telnet->login ($user,$passwd)) { @output= $telnet->cmd ("alishow"); # # analyze the alias info aliget ($host,@output); @output= $telnet->cmd ("switchshow"); # # parse and print the switchshow output swget ($host,@output); $telnet->print ('exit'); } else { print "login failed for $host\n"; }; } else { print "open failed for $host\n"; }; $telnet->close(); }; # # print the alias list print "\n"; foreach $wwid (sort_by_value(*alilist)) { printf ("%-24s %s",$alilist{$wwid}, $wwid); if ($portlist{$wwid} eq "") { print "\tNOT-LOGGED-IN"; } else { print "\t$portlist{$wwid}" }; print "\n"; }; }; exit ($rc);