﻿#!/usr/bin/perl

print "\n\t\t\tBroning for \"Brocade Zoning\"\n
\t\tWrite by Sylvain GARGASSON
\t\tMail: syl21\@syl21.org\n
\t!!! Version BETA 3 \"Don\'t use in production environement\" !!!\n
\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
\t\tYou can\'t have Tape Drive on your SAN\n\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 $scope; my $user; my $password; my $telnet; 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;
################################## 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 "\n\tSwitch user : ";
	$user = <stdin>;
	chomp $user;
	print "\n\tSwitch 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 "\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;
	print "\nUser Scope for your clariion $i (0 - global; 1 - local; 2 - LDAP) : ";
	$scope = <stdin>;
	chomp $scope;
	print "\nUser of your clariion $i : ";
	$user = <stdin>;
	chomp $user;
	print "\nPassword your clariion $i : ";
	$password = <stdin>;
	chomp $password;
	open(CMD, "naviseccli -User $user -Password $password -Scope $scope -Address $IPadress userarrayname|") or die "Can't found NaviSecCli , install it and login in windows again: $!";
	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;
}
########################################## 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 #################################################
#open RESULT,"> discovery.txt" or die "$!";
#for $i ( 0 .. $#fabric_letter ) {print RESULT "$fabric_letter[$i] $fabric_wwn[$i] $fabric_type[$i] $fabric_name[$i]\n";}
#close RESULT;
########################################## File create ###############################################
for  ($i=0;$i<$number_of_fabric;$i++) {
	open RESULT,"> result_Fab$alphabet[$i].txt" or die "$!";
########################################## PRE output ##################################################
	print RESULT "cfgclear\n";
	print RESULT "setdefaultnoaccess #revoir commande\n\n\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."\"\n";
close RESULT;
}
print "\n\t\tFINISH\n";
exit;