Professional Documents
Culture Documents
#################################################
# itverf.pl uses SYMCLI XML output to query Symmetrix information to validate st
orage builds at Navitaire
#
# Author: Nikhil Dhingra
#
# Version control:
v 1.0
#
################################################################################
#################################################
use XML::Simple;
use Data::Dumper;
use Getopt::Long qw(:config no_auto_abbrev);
#use strict;
##### Global Variables ##########
my $CACHE_DIRECTORY = "C:\\Scripts\\SYMM_QUERY\\CACHE\\";
my $RM_CACHE_DIRECTORY = "C:\\Scripts\\RM_QUERY\\CACHE\\";
my @DG_INSTANCES = ("hounslow_list_dg.xml", "sydney_list_dg.xml", "MSP_list_dg.x
ml");
my
my
my
my
my
my
my
@offset_mv=();
@serials = ();
@dgname = ();
@offset_snp;
@offset_nbu;
@offset_sg;
$offset_multi=0;
# Force autoflush
$| = 1;
if ($#ARGV<0){
&usage();
}
else
{
my $dash=0;
# everything will begin with a - (e.g. symmquery -l), he
nce this checks to see if there is a '-' in the command line
for(my $i=0;$i<=$#ARGV;$i++)
{
if($ARGV[$i]=~"-")
{
$dash=1;
}
}
if($dash eq 0)
{
usage();
}
}
################################################################################
# get command line options by using GetOptions sub
#
################################################################################
GetOptions("m|multi" => \$offset_multi,
"snp=s{1,}" => \@offset_snp,
"mv=s{1}" => \@offset_mv,
%hash_view;
@view_name;
@storage_group_name;
@port_group_name;
@init_group_name;
$error_log;
$step_count = 1;
e'}}->{'init_grpname'}},$masking_view_array[$i]->{'View_Info'}->{'init_grpname'}
);
$masking_view_array[$i]->{'View_Info'}->{'Device'} = [ $masking_view
_array[$i]->{'View_Info'}->{'Device'} ] if ref($masking_view_array[$i]->{'View_I
nfo'}->{'Device'}) ne 'ARRAY';
my @sg_info = @{$masking_view_array[$i]->{'View_Info'}->{'Device'}};
for(my $j=0;$j<=$#sg_info;$j++)
{
push(@sg_devices,$sg_info[$j]->{'dev_name'});
}
}
}
## get rid of duplicate entries
my @out=keys %{{ map{$_=>1}@sg_devices}}; # Perform PFM
@sg_devices = sort @out;
my $main_view;
if(%hash_view){
print "...FOUND\n\n";
}
else{
print "\n\n##### ERROR could not find masking view $mv#####\n\n";
return;
}
#### DO STORAGE GROUP CHECKS ###############################################
########
foreach my $key (%hash_view)
{
if(uc($key) =~ "MV")
{
$main_view = $key;
printf("\n%-20s%-20s\n","",$key);
printf("%-20s%-5s%-20s\n","","->",$hash_view{$key}->{'stor_grpname'}
);
printf("%-20s%-5s%-20s\n","","->",$hash_view{$key}->{'port_grpname'}
);
my @temp = @{$hash_view{$key}->{'init_grpname'}};
printf("%-20s%-5s%-20s\n","","->",$temp[0]);
for(my $i=1;$i<=$#temp;$i++)
{
printf("%-25s%-5s%-20s\n","","->",$temp[$i]);
}
for(my $i=0;$i<=$#temp;$i++)
{
if($temp[$i] =~ "IGC" || $key =~ "iMV"){}
else{
$temp[$i] =~ s/\*//g;
#chop($temp[$i]);
my $return_value = find_gk_mv($serial,${temp[$i]},$step_
count);
if($return_value)
{
$step_count = $return_value;
}
}
}
print "\nSTEP $step_count: Checking devices in: $hash_view{$key}->{
'stor_grpname'} against SG devices entered";
$step_count++;
my $output = compare_arrays(\@offset_sg,\@sg_devices,$offset_multi);
if($output)
{
print "\n\n#### ERROR, DISCREPANCY FOUND: $output #####\n\n";
$error_log = $error_log."\n\nERROR, DISCREPANCY FOUND WHEN COMPA
RING DEVICES $hash_view{$key}->{'stor_grpname'} agaisnt SG devices entered: $out
put #####\n\n";
}
else{
print "...SUCCESS DEVICES MATCH\n\n";
}
}
}
if(!@offset_nbu)
{
if($error_log)
{
print "\n\nxxxxxxxx IT VALIDATION ABORTED: THE FOLLOWING ERRORS
WERE FOUND xxxxxxxxxxxxxxxxxxxx\n\n";
print $error_log;
return;
}
else{
print "\n\n******** IT VALIDATION COMPLETE SUCCESSFULLY ********
**\n\n";
return;
}
}
#### DO NBU MASKING VIEW AND STORAGE GROUP CHECKS ##########################
#############################
my $nbu_view = $mv;
$nbu_view =~ s/iMVC/MV/g;
$nbu_view =~ s/MVC/MV/g;
$nbu_view =~ s/iMV/MV/g;
$nbu_view = $nbu_view."_NBU";
print "\nSTEP $step_count: Looking for NBU view: $nbu_view";
$step_count++;
my $found_nbu = 0;
for(my $i=0;$i<=$#masking_view_array;$i++)
{
if(uc($masking_view_array[$i]->{'View_Info'}->{'view_name'}) eq uc($nbu_
view))
{
$found_nbu=1;
}
}
if(!$found_nbu)
{
print "...NOT FOUND\n";
$nbu_view =~ s/_ODS//g;
$nbu_view =~ s/_OLTP//g;
print "\nSTEP $step_count:
Looking for NBU view: $nbu_view";
$step_count++;
for(my $i=0;$i<=$#masking_view_array;$i++)
{
if(uc($masking_view_array[$i]->{'View_Info'}->{'view_name'}) eq uc($
nbu_view))
{
$found_nbu=1;
}
}
}
if(!$found_nbu)
{
print "\n##### ERROR could not find masking view $nbu_view #####\n";
$error_log = $error_log."\nERROR: could not find masking view $nbu_view\
n";
}
else{
for(my $i=0;$i<=$#masking_view_array;$i++)
{
if(uc($masking_view_array[$i]->{'View_Info'}->{'view_name'}) eq uc($
nbu_view))
{
print "...FOUND\n\n";
$hash_view{$masking_view_array[$i]->{'View_Info'}->{'view_name'}
}->{'stor_grpname'} = $masking_view_array[$i]->{'View_Info'}->{'stor_grpname'};
$hash_view{$masking_view_array[$i]->{'View_Info'}->{'view_name'}
}->{'port_grpname'} = $masking_view_array[$i]->{'View_Info'}->{'port_grpname'};
$hash_view{$masking_view_array[$i]->{'View_Info'}->{'view_name'}
}->{'init_grpname'} = $masking_view_array[$i]->{'View_Info'}->{'init_grpname'};
printf("%-20s%-20s\n","",$nbu_view);
printf("%-20s%-5s%-20s\n","","->",$masking_view_array[$i]->{'Vie
w_Info'}->{'stor_grpname'});
printf("%-20s%-5s%-20s\n","","->",$masking_view_array[$i]->{'Vie
w_Info'}->{'port_grpname'});
printf("%-20s%-5s%-20s\n","","->",$masking_view_array[$i]->{'Vie
w_Info'}->{'init_grpname'});
print "\nSTEP $step_count: Checking devices in: $masking_vi
ew_array[$i]->{'View_Info'}->{'stor_grpname'} against NBU devices entered";
$step_count++;
$masking_view_array[$i]->{'View_Info'}->{'Device'} = [ $mask
ing_view_array[$i]->{'View_Info'}->{'Device'} ] if ref($masking_view_array[$i]->
{'View_Info'}->{'Device'}) ne 'ARRAY';
my @sg_info = @{$masking_view_array[$i]->{'View_Info'}->{'De
vice'}};
my @nbu_devices;
for(my $j=0;$j<=$#sg_info;$j++)
{
push(@nbu_devices,$sg_info[$j]->{'dev_name'});
}
#print @nbu_devices;
my $output = compare_arrays(\@offset_nbu,\@nbu_devices,$offs
et_multi);
if($output)
{
}
else{
print "...SUCCESS DEVICES MATCH\n";
}
}
}
#### DO DEVICE GROUP CHECKS ################################################
#######
if(@device_group)
{
my @vdev;
for(my $i=0;$i<=$#device_group;$i++)
{
print "\nSTEP $step_count: Looking for Device group: $device_group[
$i]";
$step_count++;
my $temp = symm_dg_search($device_group[$i]);
if(!$temp)
{
print "\n####### ERROR: Device Group: $device_group[$i] not foun
d #########\n";
$error_log = $error_log."\n\nERROR: Device Group: $device_group[
$i] not found #########\n"
}
#print Dumper(@{$temp});
@vdev = (@vdev,@{$temp});
}
@vdev = sort @vdev;
print "\n\nSTEP $step_count: Comparing devices in @device_group with SNP
& NBU devices entered";
$step_count++;
my @snp_nbu_input = (@offset_snp, @offset_nbu);
@snp_nbu_input = sort @snp_nbu_input;
my $array_diff = compare_arrays(\@snp_nbu_input,\@vdev,$offset_multi);
if($array_diff)
{
print "\n\n#### ERROR, DISCREPANCY FOUND: $array_diff ########\n
\n";
$error_log = $error_log."\n\nERROR, DISCREPANCY FOUND BETWEEN @d
evice_group AND SNP & NBU DEVICES ENTERED: $array_diff ########\n\n";
}
else{
print "...SUCCESS DEVICES MATCH\n";
}
#### DO REPLICATION MANAGER CHECKS #####################################
##################
my $rm_error=0;
for(my $i=0;$i<=$#device_group;$i++)
{
#my @temp = split('_',$device_group[$i]);
#my $rm_sp_name = "SP_".$temp[1];
my $rm_sp_name = $device_group[$i];
$rm_sp_name =~ s/DGC_/SP_/g;
$rm_sp_name =~ s/DG_/SP_/g;
my $rm_sp_nbu_name = $rm_sp_name."_nbu";
print "STEP $step_count: Looking for RM storage pools: $rm_sp_name "
;
$step_count++;
my @rm_vdev = @{search_rm_info($rm_sp_name)};
if(!@rm_vdev)
{
print "\n##### ERROR: RM storage pool $rm_sp_name not found ####
##\n";
$error_log = $error_log."\nERROR: RM storage pool $rm_sp_name no
t found\n";
$rm_error++;
}
print "\n\nSTEP $step_count: Looking for RM storage pools: $rm_sp_nb
u_name ";
$step_count++;
my @rm_vdev_nbu = @{search_rm_info($rm_sp_nbu_name)};
if(!@rm_vdev_nbu)
{
print "\n##### ERROR: RM storage pool $rm_sp_nbu_name not found
######\n";
$error_log = $error_log."\nERROR: RM storage pool $rm_sp_nbu_nam
e not found\n";
$rm_error++;
}
#print @rm_vdev;
if($rm_error)
{
next;
}
print "\n\nSTEP $step_count: Comparing devices in RM SP POOL: $rm_sp
_name & $rm_sp_nbu_name with devices in $device_group[$i]";
$step_count++;
my @rm_pools = (@rm_vdev, @rm_vdev_nbu);
@rm_pools = sort @rm_pools;
my $array_diff = compare_arrays(\@snp_nbu_input,\@rm_pools,0);
if($array_diff)
{
print "\n\n#### ERROR, DISCREPANCY FOUND: $array_diff ########\n
\n";
$error_log = $error_log."\n\nERROR, DISCREPANCY FOUND BETWEEN RM
storage pool: $rm_sp_name & $rm_sp_nbu_name AND $device_group[$i]: $array_diff
\n\n";
}
else
{
print "...SUCCESS DEVICES MATCH\n";
}
}
}
if($error_log)
{
print "\n\nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxx\n";
print "xxxxxxxx IT VALIDATION ABORTED: THE FOLLOWING ERRORS WERE FOUND x
xxxxxxxxxxxxxxxxxxx\n";
print "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxx\n\n";
print $error_log;
}
else{
print "\n\n******** IT VALIDATION COMPLETED SUCCESSFULLY **********\n\n"
;
}
}
################################################################################
# Sub search_sg_info looks at the SG groups to
################################################################################
sub search_sg_info{
my $serial = shift;
my $snp_name = shift;
my $data_list_sg = get_xml($serial,"_list_sg.xml");
my @devices;
#print Dumper($data_list_sg);
$data_list_sg->{'SG'} = [ $data_list_sg->{'SG'} ] if ref($data_list_sg->
{'SG'}) ne 'ARRAY';
my @data_sg = @{$data_list_sg->{'SG'}};
for(my $i=0;$i<=$#data_sg;$i++)
{
if($data_sg[$i]->{'SG_Info'}->{'name'} eq $snp_name)
{
print "...FOUND\n";
$data_sg[$i]->{'DEVS_List'}->{'Device'} = [ $data_sg[$i]
->{'DEVS_List'}->{'Device'} ] if ref($data_sg[$i]->{'DEVS_List'}->{'Device'}) ne
'ARRAY';
@devices = @{$data_sg[$i]->{'DEVS_List'}->{'Device'}};
my @snp_devices;
for(my $j=0;$j<=$#devices;$j++)
{
push(@snp_devices,$devices[$j]->{'dev_name'});
}
#print @snp_devices;
return @snp_devices;
}
}
return;
}
################################################################################
# looks at RM_SP_CONFIG.xml and searchs for the given storage pool
################################################################################
sub search_rm_info{
my $rm_sp_name = shift;
my $data = get_xml($RM_CACHE_DIRECTORY,"RM_SP_CONFIG.xml");
#print Dumper($data);
foreach my $dc (%{$data})
{
foreach my $sp (%{$data->{$dc}})
{
if(uc($sp) eq uc($rm_sp_name))
{
print "...FOUND\n";
$data->{$dc}->{$sp}->{'vdev'} =~ s/,//g;
$data->{$dc}->{$sp}->{'vdev'} =~ s/\s//g;
my @output = split('[0-9][0-9]_V',$data->{$dc}->
{$sp}->{'vdev'});
shift @output;
@output = sort @output;
#print @output;
return \@output;
}
}
}
return 0;
}
################################################################################
# Compares two arrays
################################################################################
sub compare_arrays{
my $snp_nbu_input_ref = shift;
my $vdev_ref = shift;
my $offset_multi = shift;
my @snp_nbu_input = @{$snp_nbu_input_ref};
my @vdev = @{$vdev_ref};
for(my $i=0;$i<=$#snp_nbu_input;$i++)
{
for(my $j=0;$j<=$#vdev;$j++)
{
if(uc($snp_nbu_input[$i]) eq uc($vdev[$j]))
{
delete $snp_nbu_input[$i];
delete $vdev[$j];
last;
}
}
}
if(@snp_nbu_input || @vdev){
@snp_nbu_input = sort @snp_nbu_input;
@vdev = sort @vdev;
my $snp_nbu = join(",",@snp_nbu_input);
my $vdev_rem = join(",",@vdev);
$snp_nbu =~ s/^,+//; #remove leading spaces
$snp_nbu =~ s/,+$//; #remove trailing spaces
$vdev_rem =~ s/^,+//; #remove leading spaces
$vdev_rem =~ s/,+$//; #remove trailing spaces
if($offset_multi)
{
#print "MULTI FOUNDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD\n";
return $snp_nbu;
}
else{
return " (1) ".$vdev_rem."(2) ".$snp_nbu;
}
}
else{
return;
}
}
################################################################################
# Opens XML file and converts it to perl XML using XMLin
################################################################################
sub get_xml{
my $serial = shift;
my $output = shift;
my $filename;
if($serial eq $RM_CACHE_DIRECTORY)
{
$filename = $serial.$output;
}
else{
$filename = $CACHE_DIRECTORY.$serial.$output;
}
open(FILE, $filename) || die "\nCould not open file: $filename...abortin
g\n";
my @config = <FILE>;
my $temp = join("",@config);
my $data = XMLin($temp);
return ($data);
}
################################################################################
# Searches for a DG in the list_dg.xml file and returns the info
################################################################################
sub symm_dg_search{
my $dg = shift;
my @vdev;
my @tgt;
my @std;
my $count;
@DG_INSTANCES = ("hounslow_list_dg.xml", "sydney_list_dg.xml", "MSP_list
_dg.xml");
for(my $i=0;$i<=$#DG_INSTANCES;$i++)
{
my $filename = $CACHE_DIRECTORY.$DG_INSTANCES[$i];
open(FILE, $filename) || die "\nCould not open file: $filename..
.aborting\n";
my @config = <FILE>;
my $temp = join("",@config);
my $data = XMLin($temp);
#print Dumper($data);
my @dg_list = @{$data->{'DG'}};
for(my $j=0;$j<=$#dg_list;$j++)
{
if($dg_list[$j]->{'DG_Info'}->{'name'} eq $dg){
#print "$dg_list[$j]->{'DG_Info'}->{'name'} \($d
g_list[$j]->{'DG_Info'}->{'symid'}\)\n";
print "...FOUND";
if($dg_list[$j]->{'VDEV_List'})
{
$dg_list[$j]->{'VDEV_List'}->{'Device'}
= [$dg_list[$j]->{'VDEV_List'}->{'Device'}] if ref($dg_list[$j]->{'VDEV_List'}->
{'Device'}) ne 'ARRAY';
my @device = @{$dg_list[$j]->{'VDEV_List
'}->{'Device'}};
for(my $h=0;$h<=$#device;$h++)
{
push(@vdev,$device[$h]->{'dev_na
me'});
}
}
if($dg_list[$j]->{'TGT_List'})
{
$dg_list[$j]->{'TGT_List'}->{'Device'} =
[$dg_list[$j]->{'TGT_List'}->{'Device'}] if ref($dg_list[$j]->{'TGT_List'}->{'D
evice'}) ne 'ARRAY';
my @device = @{$dg_list[$j]->{'TGT_List'
}->{'Device'}};
for(my $h=0;$h<=$#device;$h++)
{
push(@tgt,$device[$h]->{'dev_nam
e'});
}
}
if($dg_list[$j]->{'STD_List'})
{
$dg_list[$j]->{'STD_List'}->{'Device'} =
[$dg_list[$j]->{'STD_List'}->{'Device'}] if ref($dg_list[$j]->{'STD_List'}->{'D
evice'}) ne 'ARRAY';
my @device = @{$dg_list[$j]->{'STD_List'
}->{'Device'}};
for(my $h=0;$h<=$#device;$h++)
{
push(@std,$device[$h]->{'dev_nam
e'});
}
}
#printf("\n%-10s%-10s%-10s%-10s\n\n","","STD \($
dg_list[$j]->{'DG_Info'}->{'std_devs'}\)","TGT \($dg_list[$j]->{'DG_Info'}->{'tg
t_devs'}\)","VDEV \($dg_list[$j]->{'DG_Info'}->{'vdevs'}\)");
if($#vdev > $#tgt && $#vdev > $#std)
{
$count = $#vdev;
}
elsif($#tgt > $#vdev && $#tgt > $#std)
{
$count = $#tgt;
}
elsif($#std > $#tgt && $#std > $#vdev)
{
$count = $#std;
}
return \@vdev;
}
}
}
return 0;
}