#!/usr/bin/perl

print "\n\t\t\tBroning for \"Brocade Zoning\"\n
\t\tWrite by Sylvain GARGASSON
\t\tMail: syl21@syl21.org\n
\tVersion BETA \"Don\'t use in production environement\"

\tAlways read, understand and validate the output before apply it !!!
\tI can\'t be responsable of what you do with this script !!!
\tThis script is under GPL CopyLeft\n
\t\tWARNING:
\t\tYou can\'t have two server with the same name
\t\tYou can\'t have a server with 2HBA on the same Fabric\n";

use strict;
use warnings;

######################################### Set date #####################################################
my $date;
(my $sec,my $min,my $hour,my $mday,my $mon,my $year,my $wday,my $yday,my $isdst) = localtime(time);
$year += 1900;
$mon++;
if ($mon =~ m/../) {
$date=$year."_".$mon."_".$mday;
} else {
$date=$year."_0".$mon."_".$mday;
}
##################################### Variable #################################################
my @alphabet = ('A'..'Z');
my @fabric_letter;
my @fabric_wwn;
my @fabric_type;
my @fabric_name;
my @telnet_output;
my @name;
my @zone;
my $number_of_fabric;
my $number_of_clariion;
my $IPadress;
my $user;
my $password;
my $telnet;
my $file;
my $line;
my $i;
my $j;
my $k;
my $name;
my $SPletter;
my $SPnumber;
my $wwn;
my $match;
my $host_unknow=1;
my $clariion_unknow=1;
my $target=0;
################################## Input Selector ######################################################
print "\nAre you on the customer network : (y/n)";
my $customer_network = <stdin>;
chomp $customer_network;
if ( "$customer_network" =~ m/^y/i ) {
################################## Brocade Telnet ######################################################
	print "\nHow many fabric have you : ";
	$number_of_fabric = <stdin>;
	chomp $number_of_fabric;
	for  ($i=0;$i<$number_of_fabric;$i++) {
		print "\nIP adress of a switch on your fabric $alphabet[$i] : ";
		$IPadress = <stdin>;
		chomp $IPadress;
		print "\nSwitch user : ";
		$user = <stdin>;
		chomp $user;
		print "\nSwitch password : ";
		$password = <stdin>;
		chomp $password;
		use Net::Telnet ();
		$telnet = new Net::Telnet (Timeout => 5, Prompt => '/[\$%#>] $/');
		$telnet->open($IPadress);
		$telnet->login($user, $password);
		$telnet->break;
		@telnet_output = $telnet->cmd("nsshow");
		for $j ( 0 .. $#telnet_output ) {
				if ("$telnet_output[$j]" =~ m/;([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2});[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2};/i) {
				push ( @fabric_wwn, $1);
				push ( @fabric_letter, $alphabet[$i]);
				}
			}
		@telnet_output = $telnet->cmd("nscamshow");
		for $j ( 0 .. $#telnet_output ) {
				if ("$telnet_output[$j]" =~ m/;([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2});[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2};/i) {
				push ( @fabric_wwn, $1);
				push ( @fabric_letter, $alphabet[$i]);
				}
			}
		$telnet->close;
	}
#################################### Clariion NaviCli ##############################################
	print "Be sure that you have NaviCLI on your path, if not, install it and login in windows again\n";
	print "\nHow many clariion have you : ";
	$number_of_clariion = <stdin>;
	chomp $number_of_clariion;
	for  ($i=1;$i<=$number_of_clariion;$i++) {
		print "\nIP adress of a SP on your clariion $i : ";
		$IPadress = <stdin>;
		chomp $IPadress;
		open(CMD, "navicli -h $IPadress arrayname|") or die "Can't start navicli: $!";
		while ( $line = <CMD>){
			if ("$line" =~ m/Array Name:(.*)/) {
				$name = $1;
				$name =~ s/-/_/g;
				$name =~ s/\W//g;
				$name =~ tr/[a-z]/[A-Z]/;
			}
		}
		close CMD;
		open(CMD, "navicli -h $IPadress port -list -sp|") or die "Can't start navicli: $!";
		while ( $line = <CMD>){
			if ("$line" =~ m/SP Name:(.*)/) {
				$SPletter = $1;
				$SPletter =~ s/-/_/g;
				$SPletter =~ s/\W//g;
				$SPletter =~ tr/[a-z]/[A-Z]/;
			}
			if ("$line" =~ m/SP Port ID:[^0-9]*([0-9]*)/i) {
				$SPnumber = $1;
			}
			if ("$line" =~ m/SP UID:\s*[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2})/i) {
				$wwn=$1;
				for $j ( 0 .. $#fabric_letter ) {
					if (defined($fabric_name[$j])) {next;}
					if ( $fabric_wwn[$j] =~ m/$wwn/i ) {
						$fabric_type[$j]="T";
						$fabric_name[$j]=$name."_".$SPletter."".$SPnumber;
						last;
					}
				}
			}
		}
		close CMD;
		open(CMD, "navicli -h $IPadress port -list -hba|") or die "Can't start navicli: $!";
		$match=0;
		while ( $line = <CMD>){
			if ( $match == 0 ) {
				if ("$line" =~ m/HBA UID:\s*[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2})/i) {
					$wwn=$1;
					$match=1;
				}
			} else {
				$line =~ m/Server Name:(.*)/;
				@name=split /\./,$1;
				$name[0] =~ s/-/_/g;
				$name[0] =~ s/\W//g;
				$name[0] =~ tr/[a-z]/[A-Z]/;
				for $j ( 0 .. $#fabric_letter ) {
					if (defined($fabric_name[$j])) {next;}
					if ( $fabric_wwn[$j] =~ m/$wwn/i ) {
						$fabric_type[$j]="I";
						$fabric_name[$j]=$name[0];
						last;
					}
				}
			$match=0;
			}
		}
		close CMD;
	}
} else {
##################################### Brocade LOG ###################################################
	print "\n\tConnect on a switch of your fabric and
\tlog the output of these commands to a file :\n
\t\tnscamshow and nsshow\n
\tmake it for each fabric in a different file\n";
	print "\nHow many fabric have you : ";
	$number_of_fabric = <stdin>;
	chomp $number_of_fabric;
	for  ($i=0;$i<$number_of_fabric;$i++) {
		print "\nFile for the fabric $alphabet[$i] : ";
		my $file = <stdin>;
		chomp $file;
		open FILE,"< $file" or die "$!";
		while ( $line = <FILE>){
			if ("$line" =~ m/;([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2});[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2};/i) {
					push ( @fabric_wwn, $1);
					push ( @fabric_letter, $alphabet[$i]);
			}
		}
		close FILE;
	}
##################################### Clariion LOG ####################################################
	print "\nUsing navicli, for the first clariion replace A.B.C.D by IP adress:\n
\"C:\\Program Files\\EMC\\Navisphere CLI\\NaviCLI\" -h A.B.C.D arrayname > clarA.txt
\"C:\\Program Files\\EMC\\Navisphere CLI\\NaviCLI\" -h A.B.C.D port -list -sp >> clarA.txt
\"C:\\Program Files\\EMC\\Navisphere CLI\\NaviCLI\" -h A.B.C.D port -list -hba > hba.txt
\nAfter for each over Clariion \"change the clariion filename (clarX.txt) and A.B.C.D by the IP adress\"
and add the last commande to the same file like this folowing :\n
\"C:\\Program Files\\EMC\\Navisphere CLI\\NaviCLI\" -h A.B.C.D arrayname > clarB.txt
\"C:\\Program Files\\EMC\\Navisphere CLI\\NaviCLI\" -h A.B.C.D port -list -sp >> clarB.txt
\"C:\\Program Files\\EMC\\Navisphere CLI\\NaviCLI\" -h A.B.C.D port -list -hba >> hba.txt\n";
	print "\nHow many clariion have you : ";
	$number_of_clariion = <stdin>;
	chomp $number_of_clariion;
	for  ($i=1;$i<=$number_of_clariion;$i++) {
		print "\nFile for the clariion $i : ";
		$file = <stdin>;
		chomp $file;
		open FILE,"< $file" or die "$!";
		$name="clariion_unknow";
		while ( $line = <FILE>){
			if ("$line" =~ m/Array Name:(.*)/) {
				$name = $1;
				$name =~ s/-/_/g;
				$name =~ s/\W//g;
				$name =~ tr/[a-z]/[A-Z]/;
			}
		}
		seek (FILE,0,0);
		while ( $line = <FILE>){
			if ("$line" =~ m/SP Name:(.*)/) {
				$SPletter = $1;
				$SPletter =~ s/-/_/g;
				$SPletter =~ s/\W//g;
				$SPletter =~ tr/[a-z]/[A-Z]/;
			}
			if ("$line" =~ m/SP Port ID:[^0-9]*([0-9]*)/i) {
				$SPnumber = $1;
			}
			if ("$line" =~ m/SP UID:\s*[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2})/i) {
				$wwn=$1;
				for $j ( 0 .. $#fabric_letter ) {
					if (defined($fabric_name[$j])) {next;}
					if ( $fabric_wwn[$j] =~ m/$wwn/i ) {
						$fabric_type[$j]="T";
						$fabric_name[$j]=$name."_".$SPletter."".$SPnumber;
						last;
					}
				}
			}
		}
	close FILE;
	}
	print "\nFile for HBA : ";
	$file = <stdin>;
	chomp $file;
	open FILE,"< $file" or die "$!";
	$match=0;
	while ( $line = <FILE>){
	if ( $match == 0 ) {
		if ("$line" =~ m/HBA UID:\s*[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2})/i) {
			$wwn=$1;
			$match=1;
		}
	} else {
		$line =~ m/Server Name:(.*)/;
		@name=split /\./,$1;
		$name[0] =~ s/-/_/g;
		$name[0] =~ s/\W//g;
		$name[0] =~ tr/[a-z]/[A-Z]/;
		for $i ( 0 .. $#fabric_letter ) {
				if ( $fabric_wwn[$i] =~ m/$wwn/i ) {
					if (defined($fabric_name[$i])) {next;}
					$fabric_type[$i]="I";
					$fabric_name[$i]=$name[0];
					last;
				}
			}
		$match=0;
		}
	}
	close FILE;
}
########################################## UNKNOW WWN ##################################################
for $i ( 0 .. $#fabric_letter ) {
	if (defined($fabric_name[$i])) {
		if ("$fabric_name[$i]" =~ m/[0-9a-f]{16}/i) {
			$fabric_type[$i]="I";
			$fabric_name[$i]="UNKNOW_Host_$host_unknow";
			print "\nWARNING: $host_unknow server(s) is bad register on clariion\n";
			$host_unknow++;
		}
		next;
	} else {
		if ("$fabric_wwn[$i]" =~ m/^50:/i) {
			$fabric_type[$i]="T";
			$fabric_name[$i]="UNKNOW_Clariion_$clariion_unknow";
			print "\nWARNING: $clariion_unknow SP Port is not found, are you sure of the clariion number?\n";
			$clariion_unknow++;
		} else {
			$fabric_type[$i]="I";
			$fabric_name[$i]="UNKNOW_Host_$host_unknow";
			print "\n WARNING: $host_unknow server(s) is not register on clariion\n";
			$host_unknow++;
		}
	}
}
########################################## OUTPUT TEST #################################################
for $i ( 0 .. $#fabric_letter ) {print "$fabric_letter[$i] $fabric_wwn[$i] $fabric_type[$i] $fabric_name[$i]\n";}
########################################## Fabric create ###############################################
for  ($i=0;$i<$number_of_fabric;$i++) {
	open RESULT,"> result_Fab$alphabet[$i].txt" or die "$!";
########################################## PRE output ##################################################
	print RESULT "cfgclear\n";
########################################## Alicreate ###################################################
	for $j ( 0 .. $#fabric_wwn ) {
		if ( $fabric_letter[$j] =~ m/$alphabet[$i]/i ) {
			print RESULT "alicreate \"A_$fabric_name[$j]\", \"$fabric_wwn[$j]\"\n";
		}
	}
########################################## Zonecreate ##################################################
	for $j ( 0 .. $#fabric_wwn ) {
		if ( $fabric_letter[$j] =~ m/$alphabet[$i]/i && $fabric_type[$j] =~ m/T/i) {
			for $k ( 0 .. $#fabric_wwn ) {
				if ( $fabric_letter[$k] =~ m/$alphabet[$i]/i && $fabric_type[$k] =~ m/I/i) {
					print RESULT "zonecreate \"Z_$fabric_name[$k]_$fabric_name[$j]\", \"A_$fabric_name[$k]; A_$fabric_name[$j]\"\n";
					push ( @zone, "Z_$fabric_name[$k]_$fabric_name[$j]");
				}
			}			
		}
	}
########################################## Cfgcreate ####################################################
	print RESULT "cfgcreate \"C_Fab".$alphabet[$i]."_".$date."\", \"";
	for $j ( 0 .. $#zone ) {
		if ( $j == $#zone ) {
			print RESULT "$zone[$j]\"\n";
		} else {
			print RESULT "$zone[$j]; ";
		}
	}
	$#zone = -1;
########################################## POST output #################################################
print RESULT "cfgenable \"C_Fab".$alphabet[$i]."_".$date."\"";
close RESULT;
}
print "\n\t\tFINISH\n";
exit;